IAR 用于调试的HardFault异常处理

用于调试的hardfault 在编写STM32程序代码时由于自己的粗心会发现有时候程序跑着跑着就进入了
HardFault_Handler中断,按照经验来说进入HardFault_Handler故障的原因主要有两个方面:
1:内存溢出或则访问越界。
2:堆栈溢出。
发生异常后我们可以首先查看LR寄存器的值,确认当前使用的堆栈是MSP还是PSP,然后找到相对应的堆栈指针,并在内存中查看相对应堆栈的内容,内核将R0~R3,R12,LR,PC,XPRS寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。

/******************************************************************************/ /*Cortex-M4 Processor Interruption and Exception Handlers*/ /******************************************************************************/ void hard_fault_handler_c( unsigned int* hardfault_args ) { unsigned char svc_num; unsigned int stacked_r0; unsigned int stacked_r1; unsigned int stacked_r2; unsigned int stacked_r3; unsigned int stacked_r12; unsigned int stacked_lr; unsigned int stacked_pc; unsigned int stacked_psr; stacked_r0 = ( ( unsigned long )hardfault_args[0] ); stacked_r1 = ( ( unsigned long )hardfault_args[1] ); stacked_r2 = ( ( unsigned long )hardfault_args[2] ); stacked_r3 = ( ( unsigned long )hardfault_args[3] ); stacked_r12 = ( ( unsigned long )hardfault_args[4] ); stacked_lr = ( ( unsigned long )hardfault_args[5] ); stacked_pc = ( ( unsigned long )hardfault_args[6] ); stacked_psr = ( ( unsigned long ) hardfault_args[7] ); svc_num = ( ( char* )stacked_r0 )[-2]; /******************* Add yourdebug trace here ***********************/ hardfault_args[0] = stacked_r0 + stacked_r1; printf("r0: %x\r\n", stacked_r0); ......while(1) { } }#ifdefined ( __ICCARM__ ) void HardFault_Handler( void ) { __ASM("TST lr, #4\n"); __ASM("ITE EQ\n""MRSEQ r0, MSP\n""MRSNE r0, PSP\n"); __ASM("MOV r1, LR\n"); __ASM("B hard_fault_handler_c"); } #else//#if defined ( __CC_ARM )

注意上边汇编哪里 【IAR 用于调试的HardFault异常处理】IAR Embedded Workbench for ARM version 7.30 (and earlier) accepted constructions like:
[...] __ASM("ITE EQ"); __ASM("MRSEQ R0, MSP"); __ASM("MRSNE R0, PSP"); [...]

The above is a bug which is corrected in IAR Embedded Workbench for ARM version 7.40.1.
The code above will generate diagnostic messages like:
Error[Ta117]: IT-block ends prematurely, or there is a label within the IT-block
Discussion
The construction above is unsafe, as in-between the asm()-statements it was possible to place ordinary C source code.
Suggested rewrite
Change the construction into a single inline assebler statement, with multiple lines.
The above construction should be rewritten to:
[…]
__ASM(“ITE EQ \n”
“MRSEQ R0, MSP \n”
“MRSNE R0, PSP”);
[…]

    推荐阅读