

在移植 cmbacktrace 时出现 _sstack、estack、stext、etext 等符号未定义的错误,是因为这些符号需要在链接脚本中明确声明。以下是完整的解决步骤:
_sstack / __StackLimit: 栈起始地址 (低地址)estack / __initial_sp: 栈结束地址 (高地址,栈指针初始位置)stext / __text_start__: 代码段起始地址etext / __text_end__: 代码段结束地址在Keil项目中找到后缀为 .sct 的链接脚本(如 project_name.sct),修改内容如下:
; 定义RAM区域(用于栈)
RAM 0x20000000 0x10000 { ; 起始地址 + 长度(根据实际芯片修改)
.ANY (+RW +ZI)
.ANY (STACK) ; 栈空间分配
}
; 定义ROM区域(用于代码)
ROM 0x08000000 0x80000 { ; 起始地址 + 长度(根据实际芯片修改)
*.o (RESET, +First) ; 中断向量表
.ANY (+RO) ; 代码和常量
}
; 导出符号到C代码
__initial_sp = ORIGIN(RAM) + LENGTH(RAM); ; estack
__StackLimit = ORIGIN(RAM); ; _sstack
__text_start__ = ORIGIN(ROM); ; stext
__text_end__ = ORIGIN(ROM) + LENGTH(ROM); ; etext
EXPORT __initial_sp [weak]
EXPORT __StackLimit [weak]
EXPORT __text_start__ [weak]
EXPORT __text_end__ [weak]
注:
ORIGIN()和LENGTH()是内置函数,分别表示内存区域的起始地址和长度。
EXPORT [weak]允许符号被覆盖(增强兼容性)。
cmb_cfg.h 中配置参数修改 cmbacktrace 的配置文件 cmb_cfg.h,使用链接脚本导出的符号:
// cmb_cfg.h
extern unsigned int __StackLimit; // 栈起始地址
extern unsigned int __initial_sp; // 栈结束地址
extern unsigned int __text_start__; // 代码段起始
extern unsigned int __text_end__; // 代码段结束
#define CMB_CSTACK_BLOCK_START ((uint32_t)&__StackLimit)
#define CMB_CSTACK_BLOCK_END ((uint32_t)&__initial_sp)
#define CMB_CODE_START ((uint32_t)&__text_start__)
#define CMB_CODE_END ((uint32_t)&__text_end__)确保启动文件(如 startup_stm32fxxx.s)未覆盖链接脚本中的符号。通常情况下,启动文件会引用链接脚本定义的 __initial_sp。
清理并重新编译整个项目,确保链接器正确使用了新定义的符号。
仍提示符号未定义:
Project -> Options for Target -> Linker -> Scatter File栈/代码地址不匹配:
printf("Stack: 0x%08X - 0x%08Xn", &__StackLimit, &__initial_sp);
printf("Code: 0x%08X - 0x%08Xn", &__text_start__, &__text_end__);调整内存区域大小:
LENGTH() 的值(如 0x20000 替换为实际容量)。; STM32F103C8T6 的示例配置
ROM 0x08000000 0x20000 { ; 128K ROM
*.o (RESET, +First)
.ANY (+RO)
}
RAM 0x20000000 0x5000 { ; 20K RAM
.ANY (+RW +ZI)
.ANY (STACK)
}
__initial_sp = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = ORIGIN(RAM);
__text_start__ = ORIGIN(ROM);
__text_end__ = ORIGIN(ROM) + LENGTH(ROM);
EXPORT __initial_sp [weak]
EXPORT __StackLimit [weak]
EXPORT __text_start__ [weak]
EXPORT __text_end__ [weak]通过以上步骤,cmbacktrace 所需的符号将正确定义,移植即可成功完成。
举报
更多回帖