历史上的今天
今天是:2025年01月08日(星期三)
2020年01月08日 | IAR开发STM32堆栈设置
2020-01-08 来源:eefocus
一、前言
关于堆栈的定义在此就不赘述,详细内容可以看这篇博客。
堆栈溢出会导致野指针,返回地址错误等问题,通常程序已经无法正常运行,进入 HardFault 异常中断。为了避免这种情况,一般会分配较大的空间用做栈,可是如果仅仅为了安全就分配大空间的栈势必导致内存浪费。本文介绍两种获取栈最大消耗的方法,以方便合理设置栈的大小。
二、方法
1、方法一
栈指针 SP 指向的位置可以反应出当前栈的消耗量。在 STM32 中,栈是向下生长的,如果我们定期的获取栈指针 SP 的值,比较后得到一个最小值,就代表了栈的最大消耗量。而如何才能定期去获取栈指针 SP 的值呢?可以使用定时器产生一个周期性的中断,在中段函数中获取栈指针 SP 的值。最简单的方法就是在系统滴答定时器(SysTick)的中断函数中调用栈分析函数。具体可以参看如下的函数。在程序运行结束后,再去获取最大栈消耗量。
static uint32_t max_stack_usage = 0xffffffff;
void stack_parse()
{
int a = 0;
if((uint32_t)&a < max_stack_usage)
{
max_stack_usage = (uint32_t)&a;
}
}
uint32_t get_max_stack_usage()
{
return max_stack_usage;
}
由于这个函数是周期执行的,必然对程序的运行性能产生影响,不过这只是为了分析,最终是要移除的。另外由于是周期执行,所以可能会错过一些周期性的压栈,以至于获取的数值并不是最大值。不过,这种方法还是有它的参考意义的。
2、方法二
在 IAR 中,可以开启栈使用分析(IAR Embedded Workbench Stack Usage Analysis),让 IDE 在编译链接阶段就推算出这个程序的栈最大使用量。不过这种方法无法分析使用函数指针的方式调用的函数,也不能确定递归函数的嵌套次数,因此这两种情况下需要使用配置文件来指出这种调用的压栈空间,比较麻烦,具体可看官方手册。不过函数指针和递归函数毕竟是少数情况,大多数的函数都是显示调用的。因此 IDE 会分析出一条最长的调用路径,从而分析出最大的栈使用量。步骤如下:
1、开启 options > linker >Advanced > Enable stack usage analysis
2、编译后查看 map 文件中的 STACK USAGE 部分
内容类似于:
*******************************************************************************
*** STACK USAGE
***
Call Graph Root Category Max Use Total Use
------------------------ ------- ---------
Program entry 8 600 8 600
Uncalled function 256 1 332
三、总结
栈空间用来存放局部变量,部分函数参数,返回地址,以及保存函数调用时主调函数的寄存器内容等。为了减少栈的分配,一定要注意不要在函数中放置很大的局部数组。上文所需的 8600 字节的栈空间,就是因为程序中有一个函数中分配了一个 8192 字节的数组,如下。
int decode_subframe_lpc(FLACContext *s, int32_t* decoded, int pred_order)
{
int sum, i, j;
int64_t wsum;
int coeff_prec, qlevel;
int coeffs[2048]; //8k, use heap to save stack
int32_t* output;
int32_t* reader;
int* pcoeffs;
...
}
可以使用两种方式来修改。其一,将 coeffs 这个数据变成 static 局部静态变量,这样做可以将这个变量从栈中移到 .bss 区域中,不过这种方式并不灵活,相当于 8192 B 的空间被占用,而其他函数无法使用。所以本质上和放在栈空间中区别不大。其二是通过 malloc 的方式灵活申请和释放内存,当不在需要这部分空间时,可以将其释放。
上一篇:STM32添加路径报错
史海拾趣
|
就是附件的这种D24V电动推杆 我想请教的问题是1.工作循环:最大15%或者2min持续使用,休息15分钟,怕烧坏元件吗?这是为什么? 2.快速释放功能,指的是什么? 3.可配高感应的传感器,配传感器有什么用途? 我想深入的学习下电动推杆,哪位老师 ...… 查看全部问答> |
|
节能环保招聘需求(重点,急聘) 产品研发总监 20W/Y ? 招聘数量:若干 ? 工作职责 负责能源统计分析系统、能源审计预测系统研究; 负责能源管理系统总体设计; 掌握产 ...… 查看全部问答> |
|
如何用方向键来控制鼠标移动,我做了一个,按方向键后鼠标位置是移动了,但是鼠标一动又回到原来位置,为什么啊? 如何用方向键来控制鼠标移动,我做了一个,按方向键后鼠标位置是移动了,但是鼠标一动又回到原来位置,为什么啊?… 查看全部问答> |
|
把WINCE设备做成U盘,连到PC怎么不见U盘盘符出现?设备管理器的设备列表也显示一个黄色的感叹号,为什么?难道还需要特别的U盘驱动程序? 把WINCE设备做成U盘,连到PC怎么不见U盘盘符出现?设备管理器的设备列表也显示一个黄色的感叹号,为什么?难道还需要特别的U盘驱动程序?… 查看全部问答> |
|
找了半天也没找到以前的那个讲usb时序的帖子,就新开一个了。现在在做一个usb的boot,基本功能已完成,只是下载速度不快,读取:50KB左右,下载20KB左右。 升级一个512K的芯片需要约22秒。不知道理论可以做到多少,是因为双缓冲的 ...… 查看全部问答> |
|
在LM3S上跑LWIP,RAW方式。在一个FOR循环中调用了TCP_WRITE()函数发送数据,发现循环次数多了的话,后面的数据会发送失败。请教,TCP_WRITE可以连续调用多少次,由哪个选项决定?… 查看全部问答> |
|
【MSP430共享】基于射频技术的工程机械仪表无线通信解决方案 针对大型工程机械各类信号与驾驶操控室仪表异地显示的通信问题, 提出基于射频模块 n R F 2 4 0 1 实现无线数据通信的设计方案,详细介绍射频芯片 n R F 2 4 0 1 的工作原理及特点, 并给出了无线通信系统硬件结构、 接口电路及相应程序框图。系统 ...… 查看全部问答> |
|
作为一个多用户、多任务的操纵系统,Linux下的文件一旦被删除,是难以恢复的。尽管删除命令只是在档节点中作删除标记,并不真正清除文件内容,但是其它用户和一些有写盘动作的进程会很快笼盖这些资料。不外,对于家庭单机使用的Linux,或者误删档 ...… 查看全部问答> |
|
某天某日某产房,你诞生了(power up , 上电运行),结果你不哭,医生把你提起来,屁股上狠狠一巴掌,你哇哇大哭(reset, 复位成功),护士给你检查,看有没有传染病(EMI测试)、然后打预防针(绝缘处理),没有问题后作记录(QC pass),你的父母来接你回去(客户验收 ...… 查看全部问答> |




