0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅谈如何评估TI C2000系列微控制器程序的堆栈使用情况

星星科技指导员 来源:TI 作者:Sheldon He 2023-03-24 09:36 次阅读

实时控制器往往拥有十分有限的存储器资源特别是片内的随机存储器(RAM)资源。能否合理、高效的运用这些资源不仅关乎到整个嵌入式系统的实现成本与性能,更涉及到系统在运行时是否会出现致命且不易被发现的错误。本文将对C2000系列微控制器的栈 (亦习惯性的被称为堆栈,这里请注意堆与栈之间的区别)做简单的介绍,并提出四种方法来对应用程序运行所需的栈空间大小进行追踪或评估,以帮助开发者在开发过程中(尤其是使用C/C++高级语言进行开发时)优化内存资源的使用并避免嵌入式程序可能存在的风险。

在计算机中,栈作为一种数据结构可以存放一系列的成员并且通过“入栈”和“出栈”操作来从栈定加入新的数据或从栈顶拿走数据。从类别上来看堆栈通常又可以分为软件堆栈和硬件堆栈两类,前者时常经由数组和链表在程序中实现而后者则与计算机架构相关并被用于实现内存的分配及访问。

本文要讨论的是C2000系列微控制器C28x内核中的硬件堆。该栈的典型特点为有一个固定的起始地址,或者说是寄存器复位值,和一个由编译器指定的可变的栈空间大小。C28x内核的堆栈指针(stack point)寄存器SP是16位寄存器,且在使用时高16位保持为0,故可以访问64K大小的内存空间。在芯片复位时,SP的内容变为0x00000400,且在使用时栈由低地址向高地址生长。堆栈的合法使用空间通常由编译器命令--stack_size= size来设定,其中size是一个常数,指定了栈空间的大小(以16位字为单位),栈的空间不得超过实际非初始化物理内存区域.stack大小也不得超出0xFFFF范围,否则将产生溢出。

一个嵌入式系统软件常常会因为多种原因而需要使用堆栈,这些原因包括:存储数学表达式的中间计算结果、在函数递归时存储每一次调用的函数返回地址、存放函数内的局部变量、存放传递进函数的参数等。随着软件流程变得越来越庞大复杂,如何正确的评估所需的堆栈空间就显得十分重要。分配过多的堆栈空间会“浪费”内存,堆栈溢出则可能造成堆栈信息丢失或者修改到邻近内存区域的数据并最终导致系统出错。

本文总结了四种适用于TI C2000系列MCU的堆栈使用评估方法,同时建议读者在有条件的情况下使用多种方法交叉验证以弥补单一方法使用过程中的局限性。这些方法通常情况下也适用于TI的其他部分嵌入式产品,对于其他各类嵌入式系统的堆栈测试、评估也有一定的借鉴意义。

一、使用TI提供的XML文件处理脚本生成函数调用图并进行静态分析

通过函数的调用关系可以静态的分析堆栈的使用情况,TI提供了一套基于Perl的脚本工具可以用于分析工程build过程中产生的XML文件以提供程序空间使用相关的信息。这里笔者需要用到的是该工具包中的call_graph.pl脚本来生成函数调用图(Call Graph)。

首先需要在wiki页面中下载并安装该工具包,可以在搜索引擎中检索关键字“Code_Generation_Tools_XML_Processing_Scripts”

并找到对应的ti.com页面进行下载安装。对于不熟悉命令行操作的读者可以按照以下三个步骤来使用该脚本。

1. 新建一个文件夹并以英文命名,并从CCS对应的C2000编译器目录拷贝odf2000.exe到该新建的文件夹中。(ofd2000.exe在C:ticcs901ccstoolscompilerti-cgt-c2000_18.12.1.LTSbin,路径随CCS版本、CCS安装路径及编译器版本不同会有差异)同时还需要从cgxml工具路径C:ticgxmlbin中拷贝call_graph.exe,从工程目录拷贝编译生成的.out文件到该文件夹中。

2. 打开命令行工具(可在windows开始菜单搜索“CMD”找到),在其中输入如下命令选取上一步中新建的文件夹为工作目录

cd C:ticgxmlutils

3. 在命令行中运行如下脚本获取输出结果,用户需要自行修改.out文件的文件名使其与第一步中复制到文件夹中的.out同名。

ofd2000 -xg gpio_toggle_cpu01.out | call_graph --stack_max

此时用户可以在命令行的输出中看到最恶劣情况下的堆栈占用情况,此处,函数c_int00是函数调用图的根,其调用在最大情况下会占用48个16位字的堆栈空间。但是这样的结果有两点限制条件将在本节的末尾部分指出。

pYYBAGQc_riAXMpEAAA3E1jUL4M782.png

如果使用--stack_max参数则可以获得更多的细节信息,具体的数据解读方法请参阅安装目录下的文档《call_graph.pdf》。

该方法简单易用,但是对于非直接调用的函数以及相互嵌套的中断服务,该工具则无法直接将其在脚本输出结果中表现出来。此时需要使用者结合call_graph输出的详细信息,借助自己对于程序流程的理解,分析得到最终的堆栈评估结果。

二、使用回调函数在运行时抓取栈指针(SP)最大值

C2000较新版本的编译器支持在函数的进入和退出过程中插入回调函数。开发者可以使--entry_hook选项为每个函数的开头部分插入一段读取堆栈指针(SP)的代码并在一定周期的程序运行中对堆栈指针的最大值进行抽取与比较从而获取统计学的极限堆栈使用情况。

以TI v18.12.2LTS Coder generation tool为例做一个测试,首先右击打开工程属性,并在“Advanced Options”中找到--entry_hook设置栏目,在后方的空格处输入回调函数的函数名称(以名为“entry_hook”的函数为例)。

poYBAGQc_riAIBGAAAGZDsPWlL0996.png

之后可以在c文件中定义函数entry_hook,其中使用的SP_current及SP_max为事先声明的int型全局变量。

void entry_hook(){

SP_current = getStackPointer();

SP_max = (SP_current > SP_max) ? SP_current : SP_max;

}

在该函数中使用了一小段汇编函数getStackPointer();用于获取堆栈指针(SP)寄存器的值,该函数的定义为:

_getStackPointer:

.asmfunc

MOV AL, SP

SUB AL, #2

LRETR

.endasmfunc

测试前还需要在头文件中对其做如下形式的函数声明:

extern int getStackPointer(void);

在完成设置后重新build工程,并点击CCS中的“Debug”按钮进入在线调试状态,此后可以进行全速运行。运行一段时间以后打开CCS的“View”,“Expressions”并点击绿色加号“Add new expression”输入变量名SP_max对最大堆栈占用情况进行观察。

通过回调函数做堆栈指针的采样统计不一定可以抓取到最极限的堆栈使用情况,实际的堆栈消耗会比用这种方法测量到的略大,因此笔者也提出了第三种测试方法。

三、在栈空间填充标识数据以检测栈空间使用情况

方法三的思路是在堆栈空间的特定内存区域中预先写入标志性数据如(0x5A)。经由程序的执行,使用过的堆栈空间内的数据会被其他数据覆盖掉,从栈尾开始向低地址走的标志性数据则因其内存空间未被使用而得以保留不变,当然这一切的前提是堆栈不发生溢出。通过寻找被修改数组的最大地址即可以判断出这一测试过程中程序实际所使用的最大堆栈规模。

该方法可以在连接仿真器的情况下进行堆栈占用情况的观察,也可以在芯片脱离仿真器运行之后再连接入仿真器(通过设置使目标芯片在连接时不被复位)并通过“Memory Browser”进行结果观察。该方法的准确性取决于软件执行的覆盖程度。

四、使用ERAD外设模块进行堆栈监测

ERAD(embedded real-time analysis and diagnostic)模块是F28004x系列MCU新增的外设,他独立于C28x内核之外,具有8个总线比较器和4个检测计数器子功能模块。由于该模块既可以被应用程序访问也可以被仿真工具访问因此能极大的增加调试的灵活性和便利性。

关于如何使用ERAD模块进行堆栈监控可以直接参考TI C2000ware软件包自带的范例程序,其参考位置为:C:tic2000C2000Ware_2_00_00_03driverlibf28004xexampleseradstack_overflow

其基本工作方式是对地址总线进行监控并根据HWBP_CNTL寄存器的配置,将地址总线内容与HWBP_REF寄存器中的参考值以指定方式进行对比(大于、大于等于、小于、小于等于),最终在比较事件发生时触发CPU的停止动作或生产RTOSINTn中断。通过这种方式的多次运用可以把堆栈空间的实际需求锁定在一个区间内便于参考。

总结:本文结合工程开发和调试的实际经验,对常用的四种C2000 MCU程序堆栈空间评估方法进行了总结,期待读者在阅读后能够结合实际情况选择一种或者多种方式确定出应用程序的堆栈需求并在工程属性中进行合理的配置,以实现最大程度的优化。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 微控制器
    +关注

    关注

    48

    文章

    6812

    浏览量

    147653
  • 控制器
    +关注

    关注

    112

    文章

    15235

    浏览量

    171213
  • 存储器
    +关注

    关注

    38

    文章

    7151

    浏览量

    162002
收藏 人收藏

    评论

    相关推荐

    rtthread编译后如何查看堆栈空间使用情况

    rtthread编译后如何查看堆栈空间使用情况,现在只能在编译完成后看到总大小,有没有办法能看到详细的使用情况。 由于RAM只有128K,除去内存池32k,想看看剩余的RAM在哪用了
    发表于 03-05 07:58

    通过Piccolo微控制器单元的模拟比较功能讨论

    简介  现在,越来越多的设计师开始转向电子微控制器,以在电机控制和数字电源系统中控制功率级。 使用微控制器(例如德州仪器 (TI) 的
    发表于 07-17 07:27

    基于微控制器集成模拟比较为电源降低电路板空间

    时,设计师仍局限于模拟域。 通过使用 TI C2000 Piccolo 微控制器系列的集成模拟功能,可以围绕单个控制器来设计系统,而不需要外
    发表于 07-19 07:38

    ucosiii堆栈使用情况检测使用率100%?

    用OSTaskStkChk函数检测堆栈使用情况,发现有两个任务使用情况为100%,堆栈设置为1024,增大堆栈到2048,依然使用率100
    发表于 04-20 22:56

    如何评估C2000系列微控制器程序堆栈使用情况

    行时是否会出现致命且不易被发现的错误。本文将对C2000系列微控制器的栈 (亦习惯性的被称为堆栈,这里请注意堆与栈之间的区别)做简单的介绍,并提出四种方法来对应用
    发表于 11-08 07:52

    C2000 MCU EtherCAT实现的特点和优势

    系列博文的第1部分介绍了用于C2000微控制器(MCU)的EtherCAT从站堆栈解决方案的市场机遇,并介绍了从站堆栈开发快速入门的三个
    发表于 11-09 06:42

    用于C2000微控制器的EtherCAT从站堆栈解决方案

    C2000实时控制微控制器(MCU)的EtherCAT从站节点的硬件开发。该博文概述了EtherCAT技术非常适合工业自动化应用中C2000 MCU的原因,以及为何
    发表于 11-09 07:01

    如何利用C2000 TMS320F28388D实时控制器自行开发EtherCAT从站控制器

    系列博客文章的第1部分介绍了用于C2000微控制器(MCU)的EtherCAT从站堆栈解决方案的市场机遇,以及从站堆栈开发快速入门的三个
    发表于 11-09 07:30

    针对 C2000 微控制器的集成微控制器 (MCU) 电源解决方案

    针对 C2000 微控制器的集成微控制器 (MCU) 电源解决方案
    发表于 10-13 10:43 9次下载
    针对 <b class='flag-5'>C2000</b> <b class='flag-5'>微控制器</b>的集成<b class='flag-5'>微控制器</b> (MCU) 电源解决方案

    基于TI C2000微控制器的分析与应用

    C2000微控制器 (MCU) 交错式功率因素校正 (PFC) 套件提供业界最佳效率、功率因素 (PF) 及总谐波失真 (THD) 性能,支持高级电能计量功能与交流 (AC) 线路。
    的头像 发表于 06-12 04:24 3790次阅读

    C2000微控制器的架构特点介绍

    C2000 微控制器培训课程(二)—架构概述(下)
    的头像 发表于 08-13 00:13 3742次阅读

    TI C2000的数字电源系统的微控制器架构介绍

    TI C2000在电动车辆上的数字电源应用系统微控制器架构
    的头像 发表于 04-26 06:17 3836次阅读
    <b class='flag-5'>TI</b> <b class='flag-5'>C2000</b>的数字电源系统的<b class='flag-5'>微控制器</b>架构介绍

    C2000微控制器的架构介绍 (1)

    C2000 微控制器培训课程(二)架构概述(上)
    的头像 发表于 04-19 06:10 4006次阅读
    <b class='flag-5'>C2000</b><b class='flag-5'>微控制器</b>的架构介绍 (1)

    如何评估TI C2000系列微控制器程序堆栈使用情况

    行时是否会出现致命且不易被发现的错误。本文将对C2000系列微控制器的栈 (亦习惯性的被称为堆栈,这里请注意堆与栈之间的区别)做简单的介绍,并提出四种方法来对应用
    的头像 发表于 10-20 20:09 272次阅读

    浅谈如何评估TI C2000系列微控制器程序堆栈使用情况

    浅谈如何评估TI C2000系列微控制器程序
    发表于 10-31 08:23 0次下载
    <b class='flag-5'>浅谈</b>如何<b class='flag-5'>评估</b><b class='flag-5'>TI</b> <b class='flag-5'>C2000</b><b class='flag-5'>系列</b><b class='flag-5'>微控制器</b><b class='flag-5'>程序</b>的<b class='flag-5'>堆栈</b><b class='flag-5'>使用情况</b>