介绍
- 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
)
问题
我在 Nordic nRF5 SDK 之上创建了一个自定义 C 硬故障处理程序。它适用于以前的构建系统(makefile 构建系统)。必须注意的是,以前的构建系统不会创建静态库,新的 CMake 系统也是如此。它只是无条件地链接一切。
在理想情况下,SDK 的用户(即我)应该定义一个回调(HardFault_c_handler),它会在硬故障的情况下被中断向量调用。
在 nRF5 SDK 库中,目标 nrf5_sdk(静态库)中包含一个启动文件(modules/nrfx/mdk/gcc_startup_nrf52840.S)。此问题的相关代码:
__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
HardFault_Handler
此外,在 ac 文件中有一个强定义,应该优先于这个弱定义。文件(components/libraries/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