|
本帖最后由 hugeice 于 2012-8-11 17:59 编辑
单片机为LM3S9B92,一个以太网程序运行半小时后会出现usage fault或者bus fault,从异常时的现场来看估计是堆栈被破坏!(栈中的PC为0x20002dff,即下面反汇编的红色代码处)
为了进一步查找原因,配置了MPU对内存进行分类保护,堆栈大小4K,并且在堆栈下方预留的4K的空间,设置为不可读写,用来作为守卫区。具体MPU配置和链接脚本如下:- /* Init MPU */
- /* ROM: RX */
- MPURegionSet(0, 0x20000000,
- MPU_RGN_SIZE_32K |
- MPU_RGN_PERM_EXEC |
- MPU_RGN_PERM_PRV_RO_USR_NO |
- MPU_RGN_ENABLE);
- /* SRAM: RW */
- MPURegionSet(1, 0x20008000,
- MPU_RGN_SIZE_32K |
- MPU_RGN_PERM_NOEXEC |
- MPU_RGN_PERM_PRV_RW_USR_NO |
- MPU_RGN_ENABLE);
- MPURegionSet(2, 0x20010000,
- MPU_RGN_SIZE_32K |
- MPU_RGN_PERM_NOEXEC |
- MPU_RGN_PERM_PRV_RW_USR_NO |
- MPU_RGN_ENABLE);
- /* stack guard: -- */
- MPURegionSet(3, (unsigned long)pulStack[0],
- MPU_RGN_SIZE_4K |
- MPU_RGN_PERM_NOEXEC |
- MPU_RGN_PERM_PRV_NO_USR_NO |
- MPU_RGN_ENABLE);
- /* real stack: RW */
- MPURegionSet(4, (unsigned long)pulStack[1],
- MPU_RGN_SIZE_4K |
- MPU_RGN_PERM_NOEXEC |
- MPU_RGN_PERM_PRV_RW_USR_NO |
- MPU_RGN_ENABLE);
- MPUEnable(MPU_CONFIG_PRIV_DEFAULT /* | MPU_CONFIG_HARDFLT_NMI */);
复制代码 链接脚本:(程序是在内存中调试的,所以所有的地址都为片内地址,LM3S9B92总共有96KB SRAM)- MEMORY
- {
- /* FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 */
- ROM (rx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
- SRAM (rw) : ORIGIN = 0x20008000, LENGTH = 0x0000E000
- STACK (rw) : ORIGIN = 0x20016000, LENGTH = 0x00002000
- }
- SECTIONS
- {
- .text :
- {
- _text = .;
- KEEP(*(.isr_vector))
- *(.text*)
- *(.rodata*)
- /* _etext = .; */
- } > ROM
- . = ALIGN(8);
- _etext = .;
- .data : AT(ADDR(.text) + (_etext - _text)/*SIZEOF(.text)*/)
- {
- _data = .;
- *(vtable)
- *(.data*)
- _edata = .;
- } > SRAM
- .bss :
- {
- _bss = .;
- *(.bss*)
- *(COMMON)
- _ebss = .;
- } > SRAM
- .stack :
- {
- *(.stack);
- } > STACK
- }
复制代码 如上配置后,运行程序大约半小时,出现MPU异常,现场如下:
{r = {0xc000000, 0x82f1, 0x0, 0x82f1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82f1, 0x20017ef4, 0xc000000, 0x20002dff}, xPSR = 0x20017f38, FSR = {CFSR = 0x1, xFSR = {MFSR = 0x1, BFSR = 0x0, UFSR = 0x0}}, HFSR = 0x0, DFSR = 0x0, AFSR = 0x0, AR = {MMAR = 0xffffffff, BFAR = 0xffffffff}}
MMAR地址无效,栈中的PC(0x20002dff)指向如下代码中的红色指令:- /* IP header check sum */
- unsigned short ip_check_sum(void *data, int len)
- {
- 20002de8: b580 push {r7, lr}
- 20002dea: b084 sub sp, #16
- 20002dec: af00 add r7, sp, #0
- 20002dee: 6078 str r0, [r7, #4]
- 20002df0: 6039 str r1, [r7, #0]
- /home/hugeice/Work/judp/lm3s/epiudp/checksum.c:324
- unsigned short chksum;
- chksum = ~check_sum(0, data, len);
- 20002df2: f04f 0000 mov.w r0, #0
- 20002df6: 6879 ldr r1, [r7, #4]
- 20002df8: 683a ldr r2, [r7, #0]
- 20002dfa: f7ff fec1 bl 20002b80 <check_sum_opt_c4>
复制代码 栈中PC指向这里:- 20002dfe: 4603 mov r3, r0
复制代码- 20002e00: ea6f 0303 mvn.w r3, r3
- 20002e04: 81fb strh r3, [r7, #14]
- /home/hugeice/Work/judp/lm3s/epiudp/checksum.c:325
- return (0 == chksum) ? 0xffff : chksum;
- 20002e06: 89fb ldrh r3, [r7, #14]
- 20002e08: 2b00 cmp r3, #0
- 20002e0a: d001 beq.n 20002e10 <ip_check_sum+0x28>
- 20002e0c: 89fb ldrh r3, [r7, #14]
- 20002e0e: e001 b.n 20002e14 <ip_check_sum+0x2c>
- 20002e10: f64f 73ff movw r3, #65535 ; 0xffff
- /home/hugeice/Work/judp/lm3s/epiudp/checksum.c:326
- }
- 20002e14: 4618 mov r0, r3
- 20002e16: f107 0710 add.w r7, r7, #16
- 20002e1a: 46bd mov sp, r7
- 20002e1c: bd80 pop {r7, pc}
- 20002e1e: bf00 nop
复制代码 栈中PC指向调用子函数“check_sum_opt_c4”返回后的下一条指令,但是此指令并没有内存操作(“mov r3, r0”),是否意味着是前一条指令造成的MPU异常?那么是不是前一条指令调用函数在返回阶段造成的MPU异常呢?(比如栈被破坏)
在这种情况下还有什么办法能够更进一步的定位出现问题的地方呢?
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|