本帖最后由 keer_zu 于 2022-1-26 11:22 编辑
(转自 aozima)rt-thread问答。
ARM cortex-M上面的fault想必大家都不陌生,我相信还没有谁从来没有出现过fault。
但出现fault后如何排查,相信很多人都是一筹莫展。 在我的项目中加了一些代码,Fault 后可以打印出更多的信息。 - #define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
- #define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
- #define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
- #define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
- #define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
- #define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
- #define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
- static void usage_fault_track(void)
- {
- rt_kprintf("usage fault:
- ");
- rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
- if(SCB_CFSR_UFSR & (1<<0))
- {
- /* [0]:UNDEFINSTR */
- rt_kprintf("UNDEFINSTR ");
- }
- if(SCB_CFSR_UFSR & (1<<1))
- {
- /* [1]:INVSTATE */
- rt_kprintf("INVSTATE ");
- }
- if(SCB_CFSR_UFSR & (1<<2))
- {
- /* [2]:INVPC */
- rt_kprintf("INVPC ");
- }
- if(SCB_CFSR_UFSR & (1<<3))
- {
- /* [3]:NOCP */
- rt_kprintf("NOCP ");
- }
- if(SCB_CFSR_UFSR & (1<<8))
- {
- /* [8]:UNALIGNED */
- rt_kprintf("UNALIGNED ");
- }
- if(SCB_CFSR_UFSR & (1<<9))
- {
- /* [9]:DIVBYZERO */
- rt_kprintf("DIVBYZERO ");
- }
- rt_kprintf("
- ");
- }
- static void bus_fault_track(void)
- {
- rt_kprintf("bus fault:
- ");
- rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
- if(SCB_CFSR_BFSR & (1<<0))
- {
- /* [0]:IBUSERR */
- rt_kprintf("IBUSERR ");
- }
- if(SCB_CFSR_BFSR & (1<<1))
- {
- /* [1]:PRECISERR */
- rt_kprintf("PRECISERR ");
- }
- if(SCB_CFSR_BFSR & (1<<2))
- {
- /* [2]:IMPRECISERR */
- rt_kprintf("IMPRECISERR ");
- }
- if(SCB_CFSR_BFSR & (1<<3))
- {
- /* [3]:UNSTKERR */
- rt_kprintf("UNSTKERR ");
- }
- if(SCB_CFSR_BFSR & (1<<4))
- {
- /* [4]:STKERR */
- rt_kprintf("STKERR ");
- }
- if(SCB_CFSR_BFSR & (1<<7))
- {
- rt_kprintf("SCB->BFAR:%08X
- ", SCB_BFAR);
- }
- else
- {
- rt_kprintf("
- ");
- }
- }
- static void mem_manage_fault_track(void)
- {
- rt_kprintf("mem manage fault:
- ");
- rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
- if(SCB_CFSR_MFSR & (1<<0))
- {
- /* [0]:IACCVIOL */
- rt_kprintf("IACCVIOL ");
- }
- if(SCB_CFSR_MFSR & (1<<1))
- {
- /* [1]:DACCVIOL */
- rt_kprintf("DACCVIOL ");
- }
- if(SCB_CFSR_MFSR & (1<<3))
- {
- /* [3]:MUNSTKERR */
- rt_kprintf("MUNSTKERR ");
- }
- if(SCB_CFSR_MFSR & (1<<4))
- {
- /* [4]:MSTKERR */
- rt_kprintf("MSTKERR ");
- }
- if(SCB_CFSR_MFSR & (1<<7))
- {
- /* [7]:MMARVALID */
- rt_kprintf("SCB->MMAR:%08X
- ", SCB_MMAR);
- }
- else
- {
- rt_kprintf("
- ");
- }
- }
- static void hard_fault_track(void)
- {
- if(SCB_HFSR & (1UL<<1))
- {
- /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */
- rt_kprintf("failed vector fetch
- ");
- }
- if(SCB_HFSR & (1UL<<30))
- {
- /* [30]:FORCED, Indicates hard fault is taken because of bus fault,
- memory management fault, or usage fault. */
- if(SCB_CFSR_BFSR)
- {
- bus_fault_track();
- }
- if(SCB_CFSR_MFSR)
- {
- mem_manage_fault_track();
- }
- if(SCB_CFSR_UFSR)
- {
- usage_fault_track();
- }
- }
- if(SCB_HFSR & (1UL<<31))
- {
- /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */
- rt_kprintf("debug event
- ");
- }
- }
- /**
- * fault exception handling
- */
- void rt_hw_hard_fault_exception(struct stack_context* contex)
- {
- rt_kprintf("psr: 0x%08x
- ", contex->psr);
- rt_kprintf(" pc: 0x%08x
- ", contex->pc);
- rt_kprintf(" lr: 0x%08x
- ", contex->lr);
- rt_kprintf("r12: 0x%08x
- ", contex->r12);
- rt_kprintf("r03: 0x%08x
- ", contex->r3);
- rt_kprintf("r02: 0x%08x
- ", contex->r2);
- rt_kprintf("r01: 0x%08x
- ", contex->r1);
- rt_kprintf("r00: 0x%08x
- ", contex->r0);
- hard_fault_track();
- rt_kprintf("hard fault on thread: %s
- ", rt_current_thread->name);
- #ifdef RT_USING_FINSH
- list_thread();
- #endif
- while (1);
- }
|