简介
- arm none eabi gcc版本10.3-2021.10 20210824
- 设备:北欧nRF52840/nRF52832/nRF52833
- 受影响的库:Nordic NRF5 SDK 17.1.0-自定义构建系统(CMake(
我为Nordic NRF5 SDK编写了CMake构建系统(本机仅支持makefile(。构建系统有一个可执行文件(应用程序(和多个底层静态库。依赖关系如下:
application
...
- NordicAl (abstraction layer)
- nrf5_sdk
...
//root/CMakeLists.txt
add_executable(application)
...
add_subdirectory(lib/NordicAl)
...
target_link_libraries(application PRIVATE
nordic_al
...)
....
//root/lib/NordicAl/CMakeLists.txt
add_library(nordic_al)
...
add_subdirectory(lib/nrf5_sdk)
target_link_libraries(nordic_al PRIVATE
nrf5_sdk
...)
...
//root/lib/NordicAl/lib/nrf5_sdk/CMakeLists.txt
add_library(nrf5_sdk)
...
target_sources(nrf5_sdk PRIVATE
...
${NRF5_SDK_ROOT}/modules/nrfx/mdk/gcc_startup_${PLATFORM_MCU_FAMILY}.S
${NRF5_SDK_ROOT}/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c
)
问题
我在NordicnRF5SDK之上创建了一个自定义的C硬故障处理程序。它与以前的生成系统(makefile生成系统(配合使用。必须注意的是,以前的构建系统不会像新的CMake系统那样创建静态库。它只是无条件地将一切联系在一起。
在完美的世界中,SDK的用户(即i(应该定义一个回调(HardFault_c_handler(,在发生硬故障时,它将由中断向量调用。
在nRF5 SDK库中,启动文件(modules/nrfx/mdk/gcc_startup_nrf52840.S(包含在目标nRF5_SDK(静态库(中。此问题的相关代码:
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler
.long NMI_Handler
.long HardFault_Handler
...
.weak HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
b .
.size HardFault_Handler, . - HardFault_Handler
此外,在c文件中有一个HardFault_Handler
的强定义,应该优先于这个弱定义。文件(components/librarys/hardfault/nrf52/handler/hardfault_handler_gcc.c(包含:
extern void HardFault_c_handler(uint32_t *);
void HardFault_Handler(void) __attribute__(( naked ));
void HardFault_Handler(void)
{
__ASM volatile(
...
" .ltorg n"
: : "X"(HardFault_c_handler)
);
}
在发生硬故障的情况下,MCU应该调用c文件中的代码,但它没有。
我的问题是为什么?如何使它更喜欢强大的功能?我现在的想法,尽管我不确定。因为这个回调,即HardFault_Handler
,在主应用程序中没有被引用(或者在到达启动文件之前(,链接器不需要解析它。只有当它在启动文件中看到这个符号时,它才会查找它,并且因为这是一个静态库,它只查找第一次出现的符号。
我尝试过的东西
- 删除静态库,这修复了问题
- 将
HardFault_Handler
的弱定义分离成单独的汇编文件,这使得链接器将函数从第一个出现的文件链接起来,使用-Wl,-trace-symbol=HardFault_Handler
我看到链接器只查找第一个出现而不停止(弱和强无关( - 将c文件放在源中的启动文件之前,不会更改结果
编辑
我的链接器标志:
-mcpu=cortex-m4
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
-mthumb
-mabi=aapcs
-ffreestanding
-fno-common
-finline-small-functions
-findirect-inlining
-fstack-protector-strong
-ffunction-sections
-fdata-sections
-Wl,--gc-sections
--specs=nano.specs
我发现,当我使用CMake时,我可以使用add_library()
函数提供OBJECT
关键字。在这种情况下,关键字按预期工作。请注意,链接到另一个对象库的对象库无法正常工作。底层对象库也必须包含在最顶层(非对象库(的目标中。