问题描述
我这边真的很奇怪。我正在为运行 Nucleus RTOS 的 Cortex-M4f 编写固件。对于我的应用程序,我有一些预构建的静态库(例如 libexternal.a),它们需要应用程序必须提供的全局结构(在静态库中声明为 extern)。
在我的应用程序代码中,我可以很好地访问结构体,但是在静态库的代码中,我总是得到一个 HardFault 中断。
通过调试,我发现处理器试图访问错误地址上的结构。下面是一些示例伪代码:
appconfig.c
struct AppConfiguration g_appconfig = {
/* initialize everything statically */
};
main.c
include <staticlib.h>
void main(){
g_appconfig.somemember = 1 /* this works */
staticlib_lib_init();
}
下面的所有内容都是静态库的一部分,并在编译应用程序之前预先构建。
appconfig.h
struct AppConfiguration{
uint32_t somemember;
};
staticlib.h
#include "appconfig.h"
extern struct AppConfiguration g_appconfig;
void static_lib_init();
staticlib.c
#include "staticlib.h"
void static_lib_init(){
g_appconfig.somemember = 1 /* causes a HardFault */
}
静态库是用标志编译的:
-ffunction-sections
-fdata-sections
-fno-builtin-memcpy
-DARM_MATH_CM4=1
-mthumb
-mcpu=cortex-m4
-mfloat-abi=soft
-fPIC
-Wno-unused-but-set-variable
和带有标志的应用程序:
-ffunction-sections
-fdata-sections
-fno-builtin-memcpy
-mthumb
-mcpu=cortex-m4
-g
-mfloat-abi=soft
通过调试,我发现静态库试图在错误的内存地址访问 g_appconfig。例如
g_appconfig 从地址 0x2000061c 开始,static_lib_init() 尝试在地址 0xff7f4342 访问它。我的 SRAM 是 320k 大,从 0x2000000 开始,我的 ROM 是 2MB 大,从 0x8000000 开始。所以在 0xff 处访问内存是没有意义的......(可能是一些硬件寄存器或其他任何东西)。
static_lib_init() 的反汇编如下所示:
00000000 <static_lib_init>:
0: b5f0 push {r4,r5,r6,r7,lr}
2: b08f sub sp,#60 ; 0x3c
4: af06 add r7,sp,#24
6: 6178 str r0,[r7,#20]
8: 6139 str r1,#16]
a: 60fa str r2,#12]
c: 60bb str r3,#8]
e: 4cf9 ldr r4,[pc,#996] ; (3f4 <static_lib_init+0x3f4>)
10: 447c add r4,pc
12: 4bf9 ldr r3,#996] ; (3f8 <static_lib_init+0x3f8>)
14: 58e3 ldr r3,[r4,r3]
16: 461a mov r2,r3
18: 2301 movs r3,#1
1a: f8c2 30d0 str.w r3,[r2,#208] ; 0xd0
r2
应该包含 g_appconfig
的起始地址(#208 是我想在现实世界代码中访问的元素的偏移量),但调试时包含 0xff7f4342。
知道这是怎么发生的吗?链接器不应该在链接时替换生成的静态库中 g_appconfig 的地址吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)