1

我目前正在尝试将一些代码上传到 LPC810,它是一个 Cortex-M0+ 微控制器。我有一个我正在尝试使用的简单程序,它只是让 LED 闪烁。

typedef unsigned int volatile * vp;

int main()
{
    *(vp) 0x4000C1C0 = 0xFFFFFFBFUL;
    *(vp) 0xA0002000 |= 1 << 2;
    for(;;) {
        *(vp) 0xA0002300 |= 1 << 2;
        volatile long wait = 240000;
        while (wait > 0) --wait;
    }
    return 0;
}

编辑:这个文件叫做main.c.

我没有编写此代码,但我知道它有效。问题是当我把它编译成一个二进制文件上传时,它原来是 75 kiB 的数量级!这对我的微控制器来说太大了。

在elf文件上运行后size,似乎有一堆额外的函数和数据被链接进来。我正在使用newlib。

下面是我的 Makefile。我确信这可能与我的编译/链接标志有关,但我一直无法弄清楚。

PROGRAM=hello
ARCH=arm-none-eabi

CC=$(ARCH)-gcc
CXX=$(ARCH)-g++
OBJCOPY=$(ARCH)-objcopy
OBJDUMP=$(ARCH)-objdump
NM=$(ARCH)-nm
SIZE=$(ARCH)-size

FLAGS=-pedantic-errors -Wall -Wextra -Werror -Wfatal-errors -O3 \
    -fdiagnostics-color -mcpu=cortex-m0plus -mthumb
CFLAGS=-std=c11 $(FLAGS)
CXXFLAGS=-std=c++14 $(FLAGS)
LDFLAGS=

OBJECTS=./obj/main.o

all: ./$(PROGRAM).hex

run: ./$(PROGRAM).hex
    sudo lpc21isp -wipe -verify -bin ./$(PROGRAM).hex /dev/ttyUSB0 115200 12000
    make clean

./$(PROGRAM).hex: ./$(PROGRAM).elf
    $(OBJCOPY) ./$(PROGRAM).elf -O binary ./$(PROGRAM).hex
    $(OBJDUMP) -D $< > $(PROGRAM).disasm
    $(NM) -n $(PROGRAM).elf > $(PROGRAM).sym
    $(SIZE) $(PROGRAM).elf

./$(PROGRAM).elf: $(OBJECTS)
    $(CC) $(FLAGS) $(LDFLAGS) $^ -o $@

./obj/%.o: ./src/%.s
    $(CC) $(FLAGS) -c $^ -o $@

./obj/%.o: ./src/%.c
    $(CC) $(CFLAGS) -c $^ -o $@

./obj/%.o: ./src/%.cpp
    $(CXX) $(CXXFLAGS) -c $^ -o $@

clean:
    rm $(OBJECTS) ./$(PROGRAM)*

我正在生成一个带有十六进制扩展名的二进制文件,对于任何混淆非常抱歉。

关于如何解决这个问题的任何想法?谢谢你的帮助!

4

2 回答 2

1

我想建议与链接器选项链接--gc-sections。这应该剥离所有未使用的库内容。

因此,添加-Wl,--gc-sections到您的 LDFLAGS。

但是我很确定你的编译器的输出没有你想象的那么大。我假设您的二进制文件包含很多零。实际上,我假设您的有效负载少于 265 字节,其余为零。这是因为您的输出链接到地址零。使用 .检查您的 ELF 文件arm-none-eabi -e hello.elf。(您的应用程序代码在部分中.text

要解决这个问题,我很确定您必须了解链接器脚本的工作原理。为此,请查看手册“The GNU linker”。

于 2015-05-08T14:52:35.007 回答
0

使用 -Os 而不是 -O3 优化二进制空间,使用 -s 去除符号,并摆脱您正在链接的 stdc++ 库 (std=c++14),这甚至不是 C++ 程序!

于 2015-04-24T18:00:28.583 回答