Problem:
与静态库链接时生成的固件映像与与直接从静态库中提取的对象链接时生成的固件映像不同。
两个固件映像都没有错误地链接并成功加载到微控制器上。
后一个二进制文件(与对象链接)按预期成功执行,而前一个二进制文件(链接到静态库)则不然。
编译期间唯一的警告是unused-but-set-variable
在制造商提供的 HAL 中,由于各种宏定义,这些对于编译实现来说并不是必需的;和unused-parameter
在各种弱函数中,也在制造商提供的 HAL 中。
描述:
我正在为 STM32F407 开发嵌入式应用程序。到目前为止,我一直在使用一个代码库,包括微处理器的 HAL 和设置代码、特定外设的驱动程序以及利用前两者的应用程序。
由于我希望使用相同的驱动程序和 HAL 开发多个应用程序(两者都已完成并经过测试,因此不会经常更改),因此我希望将 HAL 和驱动程序编译和分发为静态库,然后可以将其链接到应用程序源。
问题在于,当链接应用程序和静态库时,固件映像无法在微处理器上正确执行。当链接应用程序和直接从静态库提取的目标文件时,固件映像将按预期执行。
具体来说:
使用以下方式与静态库链接时创建的二进制文件不起作用:
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(APPOBJECTS) Library/libtest.a
使用以下方式与从静态库中提取的对象链接时创建的二进制文件有效:
@cd Library && $(AR) x libtest.a && cd ..
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(APPOBJECTS) Library/*.o
在这两种情况下:
CFLAGS = $(INCLUDES) $(DEFS) -ggdb3 -O0 -std=c99 -Wall -specs=nano.specs -nodefaultlibs
CFLAGS+= -fdata-sections -ffunction-sections -mcpu=cortex-m4 -march=armv7e-m -mthumb
CFLAGS+= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -MP -MF [email protected] /cdn-cgi/l/email-protection
LDFLAGS = -T$(LDSCRIPT) -Wl,-static -Wl,-Map=$(@:.elf=.map),--cref -Wl,--gc-sections
我比较了输出-Wl,--print-gc-sections
以及app.map
文件,但是两个版本之间有足够的不同,没有任何一件事会被认为是错误的。我也尝试过没有-Wl,--gc-sections
,无济于事。
的输出arm-none-eabi-size
两个固件映像是:
text data bss dec hex filename
43464 76 8568 52108 cb8c workingapp.elf
text data bss dec hex filename
17716 44 8568 26328 66d8 brokenapp.elf
在不使用编译器的情况下进行编译时,可以看到类似的大小差异-Wl,--gc-sections
Using arm-none-eabi-gdb
为了调试微控制器的执行,当WWDG中断发生时,有故障的固件映像进入无限循环。该中断在固件中未启用,因此中断处理程序默认为Default_Handler
(无限循环)。运行工作固件映像时不会发生此中断。
正如已接受的答案中所述,发生的 WWDG 中断实际上是一个转移注意力的事件
--Mike