基于rtos的应用中,每个任务都拥有自己的堆栈空间。堆栈设置过大,会造成内存资源浪费;设置过小,可能导致运行过程中的任务栈溢出,从而导致一些奇怪的系统行为。
事实上,当应用程序行为“奇怪”时,我们首先想到的就是堆栈大小不足。
但任务所需的堆栈大小与具体应用相关,如何确定任务堆栈的大小?
通过分析任务实现,我们可以通过手动计算的方法获取任务所需的堆栈空间:
1. 所有函数嵌套调用所需的内存
对于每个层级的函数调用:
根据cpu架构,存储一个指向函数调用返回地址的指针。一些cpu实际上将函数返回地址保存在特殊寄存器中(通常称为链接寄存器lr)。但如果该函数嵌套调用其它函数,则调用者必须保存链接寄存器的内容,因此,计算时我们假设指针也被压入堆栈。
函数调用时,传递参数所需的内存。参数通常使用寄存器传递,但同样,如果一个函数调用其它函数,寄存器内容需要保存到堆栈中。因此,假设使用堆栈传递所有参数以确定任务堆栈的大小。
存储函数的局部变量所需内存空间。
用于函数运行过程中内部状态保存所需的堆栈空间 。
2. 完整的cpu上下文存储空间,上下文通常指cpu的寄存器现场,如果需要fpu功能,还需保存相应的fpu寄存器
3. 中断处理现场保存。如果没有独立的中断堆栈,还需在任务堆栈中为每个可能嵌套的isr增加存储cpu上下文的空间,以及isr中的局部变量所需的堆栈空间。
将所有这些信息加起来是一件繁琐的工作,而得到的数字仅是堆栈的最低需求。计算是假定已知代码的确切路径,但有时并不可能。例如调用printf()函数时,很难猜测printf()需要多少堆栈空间。为了应用安全,我们还需要在计算值的基础上,乘以一些安全系数,如1.5到2.0。推算出任务堆栈值后,我们可以通过调试手段进一步优化设置。
许多ide的调试器都提供了内核感知插件,该插件允许用户查看某些内核数据结构如任务的状态,如图1所示,iar提供了freertos感知插件。通过ide的内核感知插件,应用停止运行时,可以查看当前任务堆栈使用情况,基于插件提供的信息调整任务堆栈设置,但只能获得某个瞬间的快照。
图1 ide提供的内核感知功能
为了实时监控任务堆栈使用,优化堆栈设置,我们还可以借助rtos的可视化分析工具,如tracealyzer,在运行时监控堆栈使用情况。通过堆栈使用视图显示随时间的变化,每个任务使用或未使用的堆栈数量,从而调整任务堆栈设置,优化内存使用。
图2 tracealyzer的堆栈使用捕获
一般来说,任务堆栈可以从一个比较大的堆栈空间开始,在运行时监视堆栈空间的使用情况,以查看应用程序运行一段时间后实际使用了多少堆栈空间。基于可视化分析,用户可以更清晰直观的掌握系统中内存的使用情况,进而开发出更高质量的代码。
NVIDIA打造的创业生态活动展示落幕
爱普生发布WorkForce DS
数据分析用到工具有哪些
哪款充电宝最小最薄,轻薄易携带的充电宝推荐
中芯国际为什么要急于换帅?
RTOS中如何确定任务堆栈的大小?
不忘初心、回归本初不变最初小米平板的小米平板3开箱图赏
Xilinx Adapt 技术大会中国站,来了!
ETC不止是高速公路
美国对华为将成为5G技术的全球领先者而感到焦虑
5G超级SIM卡助力运营商增长新动能
自动驾驶行业深度投资者对自动驾驶行业的呼吁
SIMV纺粘无纺布在线瑕疵检测系统的特点介绍
2019第十八届北京国际消费电子博览会
安科瑞针对太阳能发电开发Acrel-2000 V8.0光伏发电监测系统
嵌入式数据库扩展医疗设备的功能并提高安全性
闪烁LED构成的闪光电路
日本最新型的水下无线光通信设备连接器已正式商用
Lightspeed头戴式耳机Performance耳封Zulu系列详情
浪潮与江西省签署战略协议 共推江西政府数据开放