STM32 嵌入式操作系统的进入 HardFault_Handler分析

时间:2024-02-16 20:36:59

STM32在使用中,因为一般没有其他异常抛出,所以抛出异常一般都是HardFault_Handler.

导致产生该现象的原因有一下几点:

(1)数组越界操作;

(2)内存溢出,访问越界;

(3)堆栈溢出,程序跑飞;

(4)中断处理错误;

一,数组越界

毋庸置疑,程序中使用了静态数组,而在动态传参时数组赋值溢出。或者动态分配内存太小,导致程序异常。

二,内存溢出

重点检查RAM区域,程序编译后执行的RAM数据量大小为多少是否可能越界。一般不要设置到极致的情况,程序中的一些动态数组传参时会导致异常。

image

计算 RW-data+ZI-data 为需要存储在RAM区域的变量等。

检查程序编译后的.MAP文件。

对应手册,或者编译器查找到对应RAM存储空间区域。找到该区域分析,并对应。

image

例入 此芯片的RAM区域为0X20000000的48K的存储空间,检查这些变量,特别是全局变量的分配。

RAM区域内存分配不足时,检查某些变量是否可以申请为存在代码区域。

本设计中可以看到,由于申请了几个大的静态数组,RAM区域已经使用到了b790 离 C000的48K 内存已十分接近。

在这种问题下,尤其需要注意:

使用Printf,vsprintf,sprintf 格式化数据导致的内存问题,这些函数使用的内存空间较大,猜测是由于,该函数采用的拷贝数组的形式转换,内存耗费剧烈。

使用操作系统的若为 设置钩子函数抛出异常,则也会产生该问题。配置操作系统所用空间,包含消息量,消息队列,邮箱,任务堆栈等。

三,堆栈溢出

这在使用操作中问题尤其严重,在操作系统中,任务的变量均分配放置在任务所申请的堆栈空间中,例如FreeRTOS的

xTaskCreate

task. h

 

创建新的任务并添加到任务队列中,准备运行

 

Parameters:
pvTaskCode     指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环).
pcName     描述任务的名字。主要便于调试。最大长度由configMAX_TASK_NAME_LEN.定义
usStackDepth     指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数. 例如,如果堆栈为16位宽度,usStackDepth定义为 100, 200 字节,这些将分配给堆栈。堆栈嵌套深度(堆栈宽度)不能超多最大值——包含了size_t类型的变量
pvParameters     指针用于作为一个参数传向创建的任务
uxPriority     任务运行时的优先级( 0 : 优先级最低)
pvCreatedTask     用于传递一个处理——引用创建的任务
返回:
pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

所创建的任务需要指定堆栈大小,那么堆栈申请不足,则会出现异常,针对该问题可启动系统的钩子函数HOOK函数,抛出该异常。

四,中断处理异常

程序中开启了某些中断,例如USART,TIMER,RTC等。

但在程序执行中,满足中断条件,但并未能查找到该部分对应的中断服务函数,则会抛出该异常。