单片机调试技巧--栈回溯

在启动文件中修改

cpp 复制代码
					
    IMPORT rt_hw_hard_fault_exception
    EXPORT HardFault_Handler
HardFault_Handler    PROC

    ; get current context
    TST     lr, #0x04               ; if(!EXC_RETURN[2])
    ITE     EQ
    MRSEQ   r0, msp                 ; [2]=0 ==> Z=1, get fault context from handler.
    MRSNE   r0, psp                 ; [2]=1 ==> Z=0, get fault context from thread.

    STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
    STMFD   r0!, {lr}               ; push exec_return register

    TST     lr, #0x04               ; if(!EXC_RETURN[2])
    ITE     EQ
    MSREQ   msp, r0                 ; [2]=0 ==> Z=1, update stack pointer to MSP.
    MSRNE   psp, r0                 ; [2]=1 ==> Z=0, update stack pointer to PSP.

    PUSH    {lr}
    BL      rt_hw_hard_fault_exception
    POP     {lr}

    ORR     lr, lr, #0x04
    BX      lr
    ENDP
	

调用的硬件中断函数

cpp 复制代码
#define rt_uint32_t unsigned int
struct exception_info
{
    rt_uint32_t exc_return;
    rt_uint32_t r4;
    rt_uint32_t r5;
    rt_uint32_t r6;
    rt_uint32_t r7;
    rt_uint32_t r8;
    rt_uint32_t r9;
    rt_uint32_t r10;
    rt_uint32_t r11;
    rt_uint32_t r0;
    rt_uint32_t r1;
    rt_uint32_t r2;
    rt_uint32_t r3;
    rt_uint32_t r12;
    rt_uint32_t lr;
    rt_uint32_t pc;
    rt_uint32_t psr;
};


/*
 * fault exception handler
 */
void rt_hw_hard_fault_exception(struct exception_info * exception_info)
{
	unsigned int *app_sp;

	int i;
	app_sp = (unsigned int *)(exception_info + 1);  /* context + 16*4 */
	
    printf("psr: 0x%08x\r\n", exception_info->psr);
    printf("r00: 0x%08x\r\n", exception_info->r0);
    printf("r01: 0x%08x\r\n", exception_info->r1);
    printf("r02: 0x%08x\r\n", exception_info->r2);
    printf("r03: 0x%08x\r\n", exception_info->r3);
    printf("r04: 0x%08x\r\n", exception_info->r4);
    printf("r05: 0x%08x\r\n", exception_info->r5);
    printf("r06: 0x%08x\r\n", exception_info->r6);
    printf("r07: 0x%08x\r\n", exception_info->r7);
    printf("r08: 0x%08x\r\n", exception_info->r8);
    printf("r09: 0x%08x\r\n", exception_info->r9);
    printf("r10: 0x%08x\r\n", exception_info->r10);
    printf("r11: 0x%08x\r\n", exception_info->r11);
    printf("r12: 0x%08x\r\n", exception_info->r12);
    printf(" lr: 0x%08x\r\n", exception_info->lr);
    printf(" pc: 0x%08x\r\n", exception_info->pc);



	printf("stacks: \r\n");
	i = 0;
	for (i = 0; i < 1024; )
	{
		printf("%08x ", *app_sp);
		app_sp++;
		i++;
		if (i % 16 == 0)
			printf("\r\n");
			
	}
	printf("\r\n");

    while (1);
}
cpp 复制代码
fromelf  --text  -a -c  --output=xxx.dis  Objects\xxx.axf
相关推荐
养生技术人12 分钟前
Oracle OCP认证考试题目详解082系列第45题
运维·数据库·sql·oracle·开闭原则·ocp
奥尔特星云大使40 分钟前
mysql主从配置(保姆级)
数据库·mysql·主从复制
BD_Marathon1 小时前
【MySQL】SQL的分类
数据库·sql·mysql
BD_Marathon2 小时前
【MySQL】函数
android·数据库·mysql
田甲3 小时前
【STM32】墨水屏驱动开发
stm32·单片机·墨水屏
她说..4 小时前
Redis项目应用总结(苍穹外卖/黑马头条/乐尚代驾)
java·数据库·redis·缓存·消息队列·redisson·geo
蒋士峰DBA修行之路4 小时前
实验二十 GaussDB逻辑备份恢复实验
数据库·gaussdb
gsfl4 小时前
Redis 常见面试题
数据库·redis·缓存
点灯小铭5 小时前
基于51单片机手机无线蓝牙APP控制风扇调速设计
单片机·mongodb·智能手机·毕业设计·51单片机·课程设计