一 问题出现
1.1 出现的问题
应用环境:MDK 4.72a
目标芯片:STM32F103VE
错误情况:按键时偶尔死机。
错误详情:在程序进入界面之后,按住“向下键”数次后出现死机,经调试发现程序死在HardFault_Handler函数中。
1.2 关于HardFault
Cortex-M3/4的Fault异常是由于非法的存储器访问(比如访问0地址、写只读存储位置等)和非法的程序行为(比如除以0等)等造成的。常见的4种异常及产生异常的情况如下:
Bus Fault:在fetch指令、数据读写、fetch中断向量或中断时存储恢复寄存器栈情况下,检测到内存访问错误则产生Bus Fault。
Memory Management Fault:访问了内存管理单元(MPU)定义的不合法的内存区域,比如向只读区域写入数据。
Usage Fault:检测到未定义指令或在存取内存时有未对齐。
Hard Fault:在调试程序过程中,这种异常最常见。上面三种异常发生任何一种异常都会引起Hard Fault,在上面的三种异常未使能的情况下,默认发生异常时进入Hard Fault中断服务程序。
需要注意的是,在默认复位初始化时,Hard Fault使能,其它三者不使能,因此当程序中出现不合法内存访问(一般是指针错误引起)或非法的程序行为(一般就是数学里面常见的除0)时都将产生Hard Fault中断。
二 问题分析
在网上查找相关资料,发现这种问题主要有以下原因:
1 内存溢出或者访问越界,通常为数组或结构体访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。
2 堆栈溢出。增加堆栈的大小。
3 在uCos-III系统中,任务切换时要关中断。
4 没有打开相应的硬件模块但操作了相应的硬件而导致了错误
5 Jlink的问题,禁止用Jlink供电就可以了。在Jlink
6程序在添加全局变量的时候会出现sprintf 输出的浮点数不正常,因此尽量不用sprintf函数。
根据大家经验,第一个原因,也就是数组或结构体越界产生的问题的概率最大。
三 问题查找
1 在stm32f10x_it.c中,添加软件断点,一旦调试时出现Hard Fault则会在停在__breakpoint(0)处。
2 打开Call Stack窗口,在HardFault_Handler中的右键选择“Show Caller Code”
3 程序定位到出错的代码行段。
4 分析出错代码。这段代码是用于字符串复制的。因此可以判断是字符串操作过程中出现错误。
继续查找问题,使用Ctrl + F查找“copystr”函数。查找到如下代码。
这是一个结构体的成员进行操作,非常有可能是这个结构体或其成员出现越界。分析出现问题时MenuDisplayIndex值。鼠标选中MenuDisplayIndex,然后右键点击,选择Add to
发现值为102。
而定义MenuData的代码为,可见只有10个成员,是此处发生的结构体越界!
四 问题小结
百度文库地址
http://wenku.baidu.com/view/085b6fbe5022aaea988f0f48