STM32出现HardFault_Handler故障的原因1. **内存溢出或访问越界** 2. **堆栈溢出**

STM32出现HardFault_Handler故障的原因

STM32系统中,HardFault_Handler故障主要有两个方面的原因:

  1. 内存溢出或访问越界
  2. 堆栈溢出

最近我遇到的问题是栈溢出,情况如下:

static char data[10000];

void fun1(unsigned char *buf) {
    int i = 0;
    for (i = 0; i < 5000; i++) {
        data = buf;
    }
}

void fun2(void) {
    unsigned char buf[5000];
    // 其他代码
    fun1(buf); // 执行完毕此函数后出现硬件错误 HardFault_Handler
    printf("data: %s\r\n", buf);
}

int main() {
    // 其他代码
    fun2();
    // 其他代码
    while (1);
}

问题分析

通过断点调试,在进入fun1(buf)函数时发现SP指向了数组data所开辟的空间,同时PC和其他寄存器的值也压入了栈。在循环执行data = buf时,修改了压入栈的数据,导致在退出fun1(buf)时PC指向了错误的位置。

问题一:为什么SP会指向数组data所开辟的空间?
原因是发生了栈溢出。

问题二:是什么导致了堆栈溢出?
我们可以查看相关资料,了解堆栈的概念。

startup_stm32f10x_md.s文件中,可以看到如下定义:

Stack_Size     EQU    0x00000400
Heap_Size      EQU    0x00000200

堆和栈的区别

  1. 栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量等,操作方式类似于数据结构中的栈。
  2. 堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收,分配方式类似于数据结构中的链表。
  3. 全局区(静态区)(static):全局变量和静态变量的存储,初始化和未初始化的变量分别存放在不同的区域,程序结束后由系统自动释放。
  4. 文字常量区:存放常量字符串等数据。
  5. 程序代码区:存放函数体的二进制代码。

示例

int a = 0;                    // 全局初始化区
char *p1;                     // 全局未初始化区

int main() {
    int b;                    // 栈
    char s[] = "abc";        // 栈
    char *p3 = "1234567";    // 文字常量区
    static int c = 0;        // 静态初始化区
    p1 = (char *)malloc(10); // 堆区
    strcpy(p1, "123456");    // "123456" 放在常量区
}

堆栈溢出原因分析

明白堆栈的分配原理后,我们可以确认是栈溢出而非堆溢出。导致栈溢出的原因在于unsigned char buf[5000];的定义,buf的开辟占用了较大的栈空间,超出了在startup_stm32f10x_md.s文件中定义的栈大小,从而导致栈溢出。

问题总结

  1. 当函数内部变量占用空间较大时,建议将其定义为全局变量或静态变量,以减少堆栈的占用。
  2. 通过使用指针解决数据复制问题,进一步降低内存占用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2401_87496566

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值