- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
在编写STM32程序代码时由于自己的粗心会发现有时候程序跑着跑着就进入了 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler中断,按照经验来说进入 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler故障的原因主要有两个方面
1:内存溢出或则访问越界。
2:堆栈溢出。
发生异常后我们可以首先查看LR寄存器的值,确认当前使用的堆栈是MSP还是PSP,然后找到相对应的堆栈指针,并在内存中查看相对应堆栈的内容,内核将R0~R3,R12,LR,PC,XPRS寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。
那么Cortex-M3?内核HardFault错误调试定位方法有:
方法1 如何精确定位出问题代码的所在位置:
以访问越界为例:(对STM32F103C8T6内部flash模拟EEPROM)
#define STM32_FLASH_SIZE 64
#define STM32_FLASH_WREN 1
#define FLASH_SAVE_ADDR 0
#define FLASH_HIS_ADDR 0
...
FLASH_SAVE_ADDR是开始存储的基地址,STM32F103C8T6内部flash大小是64K,在STM32的内部闪存(FLASH)地址起始于0一般情况下,程序就从此地址开始写入。因此STM32F103C8T6的结束地址应该是64*1024转换成16进制后加上单片机flash的基地址得到的结果就是0那么以上代码设置了FLASH_SAVE_ADDR为0经超出了该单片机的范围,因此如果在用此单片机操作flash是如果对这个地址进行写和读的会发生错误。现在假设你在不知情的状况下对这个地址进行了操作,然后程序运行时进入
HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler中断中。那么要找出错误代码在哪个地方,可以使用以下方法(调试软件MDK):
1:进入调试调试界面在 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler的while(1)处打上断点。
3:等待代码运行到此,这时查看LR寄存器的
如果是正常运行那么显示的寄存器类似下图所示:
如果进入 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler中断,那么显示的寄存器如下图所示:
发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。
在Cortex_M3权威指南中可以看到如下图所示:
看到LR寄存器中的值是0xFFFFFFF9,因此我应该去看MSP的地址,找到该地址的地址然后如下图所示打开内存,输入上面找到的寄存器地址,右键选择以long型查看地址如下所示:
然后查看这个地址向下数六个long地址,为什么是6个long地址呢,因为由于异常发生时,内核将R0~R3、R12、Returnaddress、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址;大概是0x08xxxxxx这样开始的即为出错的代码位置,然后可以反汇编查看,如下图所示:
可以看到是对应的C语言程序是在读FLASH函数中发生了错误,因此可以判断为访问越界的问题。
方法2 :
①首先更改startup.s的启动文件,把里面的 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler代码段换成下面的代码
②然后把 HYPERLINK /zyboy2000/article/details/7668331 HardFault_Handler_c的函数放在c文件的代码中,代码如下:
void hard_fault_handler_c(unsigned int * hardfault_args)
{
static unsigned int stacked_r0;
static unsigned int stacked_r1;
static unsigned int stacked_r2;
static unsigned int stacked_r3;
s
文档评论(0)