|
最近看好几个人做Bootloader被HardFault折磨的不行,我潜水太久太无聊出来冒个泡。
原文地址: Developing a Generic Hard Fault handler for ARM Cortex-M3/Cortex-M4
我看大家进到HardFault_Handler基本都是靠看LR 寄存器进行猜测,有人做了个很好用的HardFault_Handler处理代码,可以直接把错误类型和寄存器内容通过SWO打印出来。
由于ARM在中断的时候会把主要的CPU寄存器自动入栈,所以用这个代码显示出来的结果更精确,尤其是PC跑到0xffffff00左右的情况。
先上个例子,我把PC直接加了0x01000000:
我自从用了以后根本停不下来,直接加到所有工程模板里面了,从Cortex M3 到M7都能用,M0没设备没试过。
不废话了上代码:
- /* Private typedef -----------------------------------------------------------*/
- enum { r0, r1, r2, r3, r12, lr, pc, psr};
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- void Hard_Fault_Handler(uint32_t stack[]);
- /* Private functions ---------------------------------------------------------*/
- static void printErrorMsg(const char * errMsg)
- {
- while(*errMsg != '\0'){
- ITM_SendChar(*errMsg);
- ++errMsg;
- }
- }
- static void printUsageErrorMsg(uint32_t CFSRValue)
- {
- printErrorMsg("Usage fault: \n");
- CFSRValue >>= 16; // right shift to lsb
- if((CFSRValue & (1<<9)) != 0) {
- printErrorMsg("Divide by zero\n");
- }
- if((CFSRValue & (1<<8)) != 0) {
- printErrorMsg("Unaligned access\n");
- }
- }
- static void printBusFaultErrorMsg(uint32_t CFSRValue)
- {
- printErrorMsg("Bus fault: \n");
- CFSRValue = ((CFSRValue & 0x0000FF00) >> 8); // mask and right shift to lsb
- }
- static void printMemoryManagementErrorMsg(uint32_t CFSRValue)
- {
- printErrorMsg("Memory Management fault: \n");
- CFSRValue &= 0x000000FF; // mask just mem faults
- }
- static void stackDump(uint32_t stack[])
- {
- static char msg[80];
- sprintf(msg, "R0 = 0x%08x\n", stack[r0]); printErrorMsg(msg);
- sprintf(msg, "R1 = 0x%08x\n", stack[r1]); printErrorMsg(msg);
- sprintf(msg, "R2 = 0x%08x\n", stack[r2]); printErrorMsg(msg);
- sprintf(msg, "R3 = 0x%08x\n", stack[r3]); printErrorMsg(msg);
- sprintf(msg, "R12 = 0x%08x\n", stack[r12]); printErrorMsg(msg);
- sprintf(msg, "LR = 0x%08x\n", stack[lr]); printErrorMsg(msg);
- sprintf(msg, "PC = 0x%08x\n", stack[pc]); printErrorMsg(msg);
- sprintf(msg, "PSR = 0x%08x\n", stack[psr]); printErrorMsg(msg);
- }
- void Hard_Fault_Handler(uint32_t stack[])
- {
- static char msg[80];
- //if((CoreDebug->DHCSR & 0x01) != 0) {
- printErrorMsg("\nIn Hard Fault Handler\n");
- sprintf(msg, "SCB->HFSR = 0x%08x\n", SCB->HFSR);
- printErrorMsg(msg);
- if ((SCB->HFSR & (1 << 30)) != 0) {
- printErrorMsg("Forced Hard Fault\n");
- sprintf(msg, "SCB->CFSR = 0x%08x\n", SCB->CFSR );
- printErrorMsg(msg);
- if((SCB->CFSR & 0xFFFF0000) != 0) {
- printUsageErrorMsg(SCB->CFSR);
- }
- if((SCB->CFSR & 0xFF00) != 0) {
- printBusFaultErrorMsg(SCB->CFSR);
- }
- if((SCB->CFSR & 0xFF) != 0) {
- printMemoryManagementErrorMsg(SCB->CFSR);
- }
- }
- stackDump(stack);
- __ASM volatile("BKPT #01");
- //}
- while(1);
- }
- /******************************************************************************/
- /* Cortex-M7 Processor Exceptions Handlers */
- /******************************************************************************/
- /**
- * @brief This function handles NMI exception.
- * @param None
- * @retval None
- */
- void NMI_Handler(void)
- {
- }
- /**
- * @brief This function handles Hard Fault exception.
- * @param None
- * @retval None
- */
- void HardFault_Handler(void)
- {
- __asm("TST lr, #4");
- __asm("ITE EQ \n"
- "MRSEQ r0, MSP \n"
- "MRSNE r0, PSP");
- __asm("B Hard_Fault_Handler");
- }
复制代码
最后上几个自己的USB Bootloader的照片
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|