如何确定嵌入式软件所需最小的栈空间大小


文章转载请标注来自:https://blog.csdn.net/XG_2013/article/details/107411967

栈的原理

在这里插入图片描述
如上图:栈是一块内存区域主要有如下功能,增长方向是向下生长
1.保存局部变量
2.保存返回地址(函数调用深度越大,栈的开销越大)
3.函数参数,一般情况下函数的参数是R0-R3(cortex M0),如果函数的参数大于4个一般就需要通过栈进行辅助参数,所以函数一般不建议编写大于4个参数,如果大于4个参数的函数一定要完成一个比较大的功能
4.中断的上下文切换,中断的时候会通过栈保存现场
5.其它特殊情况

本文不在这详细阐述栈的原理,主要探讨如何判断一个嵌入式软件所需最小的栈的大小。在讨论这个问题之前,我们先看看为什么嵌入式软件系统很难评估出所需栈的实际大小?

为什么嵌入式软件系统很难评估出所需栈的实际大小

1. 难找到最大深度的函数

原则上一些工具好像能通过调用关系能够分析出那个调用深度最深的函数,但是函数指针的使用使得函数最大深度的计算变的更加困难,甚至有些程序完全是2个不同的工程,工程编译的代码通过函数指针去直接跳转。所以很难有一个比较好的分析方法和工具去计算这个最大深度是多少。

2.可抢占的中断让这个问题变得更加复杂

由于中断可以发生在任意时刻,且大多数嵌入式芯片都支持中断抢占,那么最大深度变的更加扑簌迷离。

Mon 27 空闲程序A 中断B 中断C 中断E 现有任务

如上图最大的深度肯定在中断E,由于中断发生实际受事件和场景驱动,没法计算那个点的会产生最大的深度。
综合1和2点我们很难有个计算或者分析的方式评估出栈的大小。那么我们设置栈的大小呢?

如何设置栈的大小

没有中断驱动的情况,且很容易找到最大深度的函数

在这里插入图片描述
如上图,栈是向下增长的,代码开始计算栈顶的位置,代码最深的地方计算最低的位置,然后代码结束的时候打印一些栈的使用情况。
注意上图只是分析一个思路:正常的嵌入式代码的main函数肯定不会结束的,我们既可以在最深的地方打印栈的使用情况,也可以在main函数轮询的时候打印,当然为了不频繁打印可以触发某个深度打印一下。

有中断驱动的情况,且很难找到最大深度的函数一

在这里插入图片描述
如上图我们打开一个定时器中断,且优先级设为最高,典型的中断频率在10-250 kHz。我们很容易就能找到最低的位置。

  • 为什么可以这样做?因为我们定时的频率足够快一定可以抢占在最深的时候函数情况,抢占它。所以一定要保证中断优先解最高,且速度足够快。
  • 测试的时候一定要保证系统软件跑到最够多的场景和最够长的时间。

有中断驱动的情况,且很难找到最大深度的函数二

第一个方法虽然非常好且很大部分的嵌入式软件系统都能够部署(确定好了栈的大小后就可以去掉这个功能,减轻中断的负载)。但是很多嵌入式软件可能会被这个定时中断破坏了工作,特别是通过IO模拟通信实现的时候会被打断等。如果第一个方法真的很难实现的话,还有一个比较好的方式。

在这里插入图片描述
如上图我们在栈和全局变量之间填充一大块守卫区域,这个区域填充一些特殊的pattern。比如0xcd。程序运行后我们在空闲时候检查这个区域是否发生变化。发生改变就减少guard区域的大小,不发生变化就增大区域。不断实验测出来实际的栈的大小。

注意:一般栈的大小设置不够系统运行起来会出现hardfault,这不意味着栈异常一定会产生hardfault,通过不断设着栈大小,观察是否出现hardfault的方法是不太严密的

[1]: Mastering stack and heap for system reliability

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
嵌入式软件开发技术通常包括以下方面: 1. 编程语言:常用的嵌入式软件开发语言包括C、C++和汇编语言。C语言是最常用的嵌入式开发语言,因为它具有高效的执行速度和低级别的硬件访问能力。 2. 操作系统:嵌入式系统通常需要运行在实时操作系统(RTOS)或者裸机环境下。常见的RTOS包括FreeRTOS、ThreadX和VxWorks等,它们提供了任务调度、内存管理和驱动支持等功能。 3. 微控制器和硬件平台:嵌入式软件开发需要选择适合的微控制器或硬件平台。常见的微控制器包括ARM Cortex-M系列和PIC系列等,而硬件平台可以是Arduino、Raspberry Pi等。 4. 驱动开发:嵌入式软件通常需要与外设进行交互,如传感器、执行器和通信设备等。驱动开发涉及到硬件接口层的编程,需要了解相关的通信协议和接口标准。 5. 嵌入式系统架构:了解嵌入式系统的架构是开发嵌入式软件的基础。这包括了解处理器架构、内存管理单元(MMU)和外设的工作原理等。 6. 调试和测试:嵌入式软件开发需要进行调试和测试,以确保软件的正确性和稳定性。这包括使用调试工具、代码覆盖率工具和性能分析工具等。 7. 版本控制和团队协作:嵌入式软件开发通常是团队协作的工作,使用版本控制系统(如Git)可以方便团队成员之间的代码管理和协作。 请注意,以上只是嵌入式软件开发技术的一些方面,具体的技术可能会根据项目需求和行业特点有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

XG_2013

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

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

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

打赏作者

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

抵扣说明:

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

余额充值