因为在标准C语音中是不能获取SP指针的。因而,如果想通过C代码来获取入栈的寄存器值,需要配合一小段汇编代码来获取当前的SP值,然后再把这个SP值以参数形式传送给C代码,最后以指针的形式把栈中的各寄存器值输出,同时也可以输出一些想要的各种状态寄存器值。如下:
Keil环境汇编封皮:
1 HardFault_Handler 2 PROC 3 EXPORT HardFault_Handler [WEAK] 4 IMPORT hard_fault_handler_c 5 TST LR, #4 6 ITE EQ 7 MRSEQ R0, MSP 8 MRSNE R0, PSP 9 B hard_fault_handler_c 10 ENDP
C服务程序,输入为SP的值:
1 void hard_fault_handler_c( unsigned int *reg ) 2 { 3 unsigned int stacked_r0; 4 unsigned int stacked_r1; 5 unsigned int stacked_r2; 6 unsigned int stacked_r3; 7 unsigned int stacked_r12; 8 unsigned int stacked_lr; 9 unsigned int stacked_pc; 10 unsigned int stacked_psr; 11 12 stacked_r0 = (unsigned int)reg[0]; 13 stacked_r1 = (unsigned int)reg[1]; 14 stacked_r2 = (unsigned int)reg[2]; 15 stacked_r3 = (unsigned int)reg[3]; 16 17 stacked_r12 = (unsigned int)reg[4]; 18 stacked_lr = (unsigned int)reg[5]; 19 stacked_pc = (unsigned int)reg[6]; 20 stacked_psr = (unsigned int)reg[7]; 21 22 while( 1 ) 23 { 24 printf("--> %s ", __FUNCTION__); 25 //printf("EXC_RETURN: %08X ", r1); 26 printf("R0: %08X ", stacked_r0); 27 printf("R1: %08X ", stacked_r1); 28 printf("R2: %08X ", stacked_r2); 29 printf("R3: %08X ", stacked_r3); 30 printf("R12: %08X ", stacked_r12); 31 printf("LR: %08X ", stacked_lr); 32 printf("PC: %08X ", stacked_pc); 33 printf("PSR: %08X ", stacked_psr); 34 35 // 系统handler控制及状态寄存器 36 printf("SHCSR: %08X ", (*(volatile unsigned int *)(0xE000ED24))); 37 //printf("MFSR: %02X ", (*(volatile unsigned char *)(0xE000ED28))); 38 //printf("BFSR: %02X ", (*(volatile unsigned char *)(0xE000ED29))); 39 //printf("UFSR: %04X ", (*(volatile unsigned short *)(0xE000ED2A))); 40 // 存储器管理fault、总线fault、用法fault状态寄存器 41 printf("CFSR: %08X ", (*(volatile unsigned int *)(0xE000ED28))); 42 // 硬fault状态寄存器 43 printf("HFSR: %08X ", (*(volatile unsigned int *)(0xE000ED2C))); 44 // 调试fault状态寄存器 45 printf("DFSR: %08X ", (*(volatile unsigned int *)(0xE000ED30))); 46 47 // 存储器管理fault地址寄存器 48 printf("MMAR: %08X ", (*(volatile unsigned int *)(0xE000ED34))); 49 // 总线fault地址寄存器 50 printf("BFAR: %08X ", (*(volatile unsigned int *)(0xE000ED38))); 51 // 辅助fault地址寄存器 52 printf("AFAR: %08X ", (*(volatile unsigned int *)(0xE000ED3C))); 53 } 54 55 return ; 56 }
参考摘录:
《ARM Cortex-M3权威指南.pdf》