开发环境
硬件平台:正点原子F407开发板
软件版本:rtt 4.1.0
IDE:keil
demo:使用rtt固件包里的stm32f407-atk-explorer分支配合CmBacktrace里rtt平台的example
初始移植
一开始按照demo里给的方式,先初始化Cmbacktrace,然后注册异常钩子函数,在钩子函数里执行cm_backtrace_fault函数,然后在另外一个线程里执行除零操作。当程序运行起来,串口就会打印如下信息。
msh />thread pri status sp stack size max used left tick error
sys_moni 30 running 0x00000048 0x00000800 04% 0x00000005 000
tshell 20 suspend 0x00000094 0x00001000 03% 0x00000009 000
tcp_clie 5 suspend 0x00000160 0x00000800 17% 0x00000000 000
phy 30 suspend 0x00000094 0x00000400 14% 0x00000002 000
tcpip 10 suspend 0x000000c8 0x00000400 20% 0x00000014 000
etx 12 suspend 0x00000098 0x00000400 14% 0x00000010 000
erx 12 suspend 0x00000098 0x00000400 14% 0x00000010 000
sys work 23 suspend 0x00000060 0x00000800 04% 0x0000000a 000
tidle0 31 ready 0x00000054 0x00000400 09% 0x0000000a 000
main 10 suspend 0x0000009c 0x00000800 33% 0x00000007 000
Firmware name: CmBacktrace, hardware version: V1.0.0, software version: V0.1.0
Fault on thread sys_moni
Error: Thread stack(20000d00) was overflow
===== Thread stack information =====
Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
Dump call stack has an error
从这段信息看,并不能找到异常发生时栈的使用情况。找了一圈没找到原因。
再次移植
于是又把cmbacktrace的demo移植到裸机和ucosii平台都调通了。这时我就想了下这几个demo的区别,发现调通的这两个平台是用的cmb_fault.s里的的Hard_Fault函数,这个函数如下:
HardFault_Handler PROC
MOV r0, lr ; get lr
MOV r1, sp ; get stack pointer (current is MSP)
BL cm_backtrace_fault
于是我把rtt里的Hard_Fault注释掉,也使用cmb_fault.s里的这个Hard_Fault,并注释掉异常钩子函数,程序居然可以正常打印栈里面的信息了。至此算是成功把cmbacktrace成功移植到rtt平台了。
疑问
为什么使用cmbacktrace里的rtt平台的demo没跑通?demo里在异常钩子函数里执行cm_backtrace_fault为什么这么写没看明白,还请大佬们帮忙解释下。
static rt_err_t exception_hook(void *context) {
extern long list_thread(void);
uint8_t _continue = 1;
rt_enter_critical();
#ifdef RT_USING_FINSH
list_thread();
#endif
cm_backtrace_fault(* ((uint32_t *)(cmb_get_sp() + sizeof(uint32_t) * 8)), cmb_get_sp() + sizeof(uint32_t) * 9);
while (_continue == 1);
return RT_EOK;
}
原作者:wcyingdream