应对stm32 cortex-m3 hardfault异常

应对stm32 cortex-m3 hardfault异常

ID:22458352

大小:1.19 MB

页数:10页

时间:2018-10-29

应对stm32 cortex-m3 hardfault异常_第1页
应对stm32 cortex-m3 hardfault异常_第2页
应对stm32 cortex-m3 hardfault异常_第3页
应对stm32 cortex-m3 hardfault异常_第4页
应对stm32 cortex-m3 hardfault异常_第5页
资源描述:

《应对stm32 cortex-m3 hardfault异常》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、STM32Cortex-M3HardFaultHardfault(硬错误,也有译为硬件错误的)是在STM32(如无特别说明,这里的STM32指的是Cortex-M3的核)上编写程序中所产生的错误,造成HardFault错误的原因也是最为纷繁复杂的。由于能导致该错误的原因很多,所以一但出现,比较难找到其原因。网上有很多类似的这种方法,现在我将其稍加整理,并结合我曾经遇到过的问题,详细说明。硬fault是总线fault、存储器管理fault以及用法fault上访的结果。如果这些fault的服务例程无法执行,它们就会成为“硬伤”——上访(es

2、calation)成硬fault。另外,在取向量(异常处理是对异常向量表的读取)时产生的总线fault,也按硬fault处理。在NVIC中有一个硬fault状态寄存器(HFSR),它指出产生硬fault的原因。如果不是由于取向量造成的,则硬fault服务例程必须检查其它的fault状态寄存器,以最终决定是谁上访的。1寄存器描述首先查看硬故障寄存器,判别原因。对于调试故障,有个调试故障寄存器,在0xE000ED30处,有详细介绍,不做探讨;对于取中断发生的,有两类原因,一是在取向量过程中发生总线fault,二是向量表偏移量设置有误。本文重

3、点介绍位30所示的,上访类错误。这样Fault类异常有了三类,用法错误,存储管理错误,总线错误。对于这些寄存器详尽的描述,见权威指南。2确定发生错误的地方2.1查找出错原因Cortex-M3有双堆栈功能,在带有操作系统时,一般都会使用。在Keil软件使用JTAG调试为例,系统的启动文件中,将断点打在下面4个地方。HardFaultExceptionBHardFaultExceptionMemManageExceptionBMemManageExceptionBusFaultExceptionBBusFaultExceptionUsage

4、FaultExceptionBUsageFaultException程序跑飞以后,就会停在上面的4个断点的一个地方。可以通过两种方式查找原因。第一种,在KEIL软件下,利用软件提供的功能查找故障原因。在点出的窗口中,可以大体确定是哪个寄存器、什么原因造成了HardFault。第二种,通过在内存观察窗口,直接输入上面那些寄存器的值来确定,通过观看寄存器那个位被置1了,确定出错原因。2.2确定出错地方然后查看左侧寄存器栏中Banked确定现在使用的是那个堆栈,MSP或者是PSP,确定以后,在内存查看窗口,输入堆栈的地址,以这个地址开始的8个

5、32位数值,应该依次是R0,R1,R2,R3,R12,R14,R15,XPSR的数值,据此判定你的堆栈地址是不是对的(有时需要考虑堆栈的增长方向)。R14,R15的地址就是我们出错的代码所在的地址,需要在这个地址基础上,首先偶数对齐,然后向上减去8个字节。需要考虑的是,在使用MSP的时候,有出错的地方并不一定在R14,R15处,而是在XPSR往后的第二个地址处,在这个附近查找,排除故障。3两个例子下面就我之前碰到过的,举例说明,这两个例子分析出结果后,会觉得很简单,但是查找原因的过程有点费劲。3.1memcpy内存拷贝函数引发总线故障寄

6、存器中IMPERCISERR位,标示不精确的数据总线访问错误,权威指南中对此有详尽的说明,“或者传送的数据单位尺寸不能为设备所接受,此时有可能是LDM/STM指令造成的”。Memcpy函数的原因是这样的void*memcpy(void*dest,constvoid*src,size_tn),其中src是源地址,dest是目的地址,n是要拷贝的字节长度。KEIL自带的函数中并不检查这三个参数是否有效,我所开发的程序中,源地址和目的地址都在外存(外部扩展的内存,本次大小是4M)中,假设size的大小是0xFFFFFFFF,这样的数值非常的大

7、,单纯的拷贝都需要10多秒。程序中定义了很多的变量都在外存,这个拷贝函数所在的任务优先级比较低,可能被中断或者其它的任务打断。我调试程序的时候,首先是发生在了中断的地方,外存数组地址到了0x21FF2200,原来定义在68021000,加起来立刻超出了外存大小。修改中断,最终确定是传入的参数n太大了,直接是0xFFFFFFFF,这样memcpy函数会在这里陷入死循环,一直到外存耗尽,地址再增加,找不到外存地址了,然后触发HardFault。3.2滥用临界区程序中的一些关键代码,有时候需要在临界区中执行,但是临界区若使用不当,则也会造成错

8、误。OS_ENTER_CRITICAL();。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。OS_EXIT_CRITICAL();#defineOS_ENTER_CRITICAL()

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。