本帖最后由 aozima 于 2012-12-2 22:07 编辑
项目中加了一些代码,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:\n");
- 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("\n");
- }
- static void bus_fault_track(void)
- {
- rt_kprintf("bus fault:\n");
- 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\n", SCB_BFAR);
- }
- else
- {
- rt_kprintf("\n");
- }
- }
- static void mem_manage_fault_track(void)
- {
- rt_kprintf("mem manage fault:\n");
- 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\n", SCB_MMAR);
- }
- else
- {
- rt_kprintf("\n");
- }
- }
- 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\n");
- }
- 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\n");
- }
- }
- /**
- * fault exception handling
- */
- void rt_hw_hard_fault_exception(struct stack_context* contex)
- {
- rt_kprintf("psr: 0x%08x\n", contex->psr);
- rt_kprintf(" pc: 0x%08x\n", contex->pc);
- rt_kprintf(" lr: 0x%08x\n", contex->lr);
- rt_kprintf("r12: 0x%08x\n", contex->r12);
- rt_kprintf("r03: 0x%08x\n", contex->r3);
- rt_kprintf("r02: 0x%08x\n", contex->r2);
- rt_kprintf("r01: 0x%08x\n", contex->r1);
- rt_kprintf("r00: 0x%08x\n", contex->r0);
- hard_fault_track();
- rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
- #ifdef RT_USING_FINSH
- list_thread();
- #endif
- while (1);
- }
再写了两个测试代码,以手动触发fault。- #include <finsh.h>
- static void div0_test(void)
- {
- int x,y,z;
- x = 10;
- y = 0;
- z = x / y;
- rt_kprintf("z:%d\n", z);
- }
- FINSH_FUNCTION_EXPORT(div0_test, div0_test)
- static void unalign_test(void)
- {
- int * p;
- p = (int *)0x00;
- rt_kprintf("00:0x%08X\n", *p);
- p = (int *)0x04;
- rt_kprintf("04:0x%08X\n", *p);
- p = (int *)0x03;
- rt_kprintf("03:0x%08X\n", *p);
- }
- FINSH_FUNCTION_EXPORT(unalign_test, unalign_test)
测试时可以使用finsh强大的功能来配置CPU的状态:
1. 访问末授权区域- finsh>>int * p //声明一个指针变量
- 0, 0x00000000
- finsh>>p = 0xDFFFFFF0 // 指向片上外设区结束处,一般不可能用完,所以此处一般不可访问。
- -536870928, 0xdffffff0
- finsh>>*p // 读取指针处数据
- psr: 0x01000000
- pc: 0x00000e3e
- lr: 0x0000451d
- r12: 0x00000000
- r03: 0x00000000
- r02: 0x1fff0180
- r01: 0x1fff0814
- r00: 0xdffffff0
- bus fault:
- SCB_CFSR_BFSR:0x82 PRECISERR SCB->BFAR:DFFFFFF0
- hard fault on thread: tshell
- thread pri status sp stack size max used left tick error
- -------- ---- ------- ---------- ---------- ---------- ---------- ---
- tidle 0x1f ready 0x00000040 0x00000100 0x00000060 0x00000015 000
- tshell 0x14 ready 0x00000088 0x00000400 0x00000218 0x00000009 000
2. 非对齐访问测试- finsh>>int * p //声明一个指针变量
- 0, 0x00000000
- finsh>>p = 0xE000ED14 // 指向SCB->CCR
- -536810220, 0xe000ed14
- finsh>>*p = 0x00000208 // 打开非对齐异常
- 520, 0x00000208
- finsh>>unalign_test() // 非对齐访问测试
- psr: 0x21000000
- pc: 0x00000430
- lr: 0x00003cbd
- r12: 0x0000006e
- r03: 0x00000002
- r02: 0x00000004
- r01: 0x1fff1b6a
- r00: 0x1fff1a2c
- usage fault:
- SCB_CFSR_UFSR:0x100 UNALIGNED
- hard fault on thread: tshell
- thread pri status sp stack size max used left tick error
- -------- ---- ------- ---------- ---------- ---------- ---------- ---
- tidle 0x1f ready 0x00000058 0x00000100 0x00000060 0x00000001 000
- tshell 0x14 ready 0x00000088 0x00000400 0x00000218 0x00000008 000
3. 除零异常测试- finsh>>int * p //声明一个指针变量
- 0, 0x00000000
- finsh>>p = 0xE000ED14 // 指向SCB->CCR
- -536810220, 0xe000ed14
- finsh>>*p = 0x00000210 // 打开除零异常
- 528, 0x00000210
- finsh>>div0_test() // 除零异常测试
- psr: 0x41000000
- pc: 0x00001efe
- lr: 0x0000096d
- r12: 0x00000000
- r03: 0x1fff012c
- r02: 0x1fff0917
- r01: 0x00001ef9
- r00: 0x00000000
- usage fault:
- SCB_CFSR_UFSR:0x200 DIVBYZERO
- hard fault on thread: tshell
- thread pri status sp stack size max used left tick error
- -------- ---- ------- ---------- ---------- ---------- ---------- ---
- tidle 0x1f ready 0x00000040 0x00000100 0x00000060 0x0000000b 000
- tshell 0x14 ready 0x00000088 0x00000400 0x00000218 0x00000009 000
|