DSP

DSP编程时 c_int00是什么内容

2019-07-13 10:13发布

class="markdown_views prism-atom-one-light">

DSP编程时 c_int00是什么内容


写在前面的话:
关于DSP开发中更多的细节与小技巧在公众号【iFTrue未来已来】中有系列文章的多期发布。
查看方式:
1) 微信扫描下方二维码,关注公众号【iFTrue未来已来
在这里插入图片描述
2) 后台回复关键字 “【 Bootloader 】” 即可获取所有Bootloader相关文章的目录
3) 点击公众号菜单栏可以浏览DSP相关文章
c_int00(也作_c_int00)是C/C++程序初始化代码的入口地址,完成建立C程序的运行环境。它是运行支持库(如rts2800_ml.lib)中的一个重要函数。 DSP上电时,由Bootloader负责引导至c_ini00。

1 c_int00完成的工作

1) 定义系统栈.stack,并初始化栈指针,配置相关寄存器
2) 初始化全局变量(.cinit)
3) 若使用C++,还会完成全局对象构造(.pinit)
4) 调用main函数运行C程序
5) 当main函数return时,调用exit函数 用户可以对c_int00函数进行修改,但修改后的函数必须完成以上任务。

2 系统初始化

在TI官网找到了rts2800_ml.lib对应的boot.asm源文件,其中核心内容为c_int00函数,其中关于“定义系统栈.stack,并初始化栈指针,配置相关寄存器”等系统初始化的部分如下 该部分完成了C程序运行的基础条件设置,不包括对全局变量的初始化。此时如果进入main函数执行应用程序的话,需要注意所有全局变量将不再遵守C语言定义时初值的标准规定,也就是说,除非在程序中对全局变量重新赋值,否则全局变量的初值是随机的。需要说明的是除了全局变量初值随机,程序是可以完整准确运行的。这可以应用到用户自定义c_int00的场合,在程序开始执行后重新对所有全局赋值,从而减少该部分的工作量,例如二次Bootloader,当二次Bootloader执行完毕进入main之前重新调用c_int00即可。
(说明:二次Bootloader需要自定义c_int00的原因是希望C环境初始化完毕后不必进入main函数,而是进入二次Bootloader的主程序)

3 全局变量初始化

全局变量初始化(.cinit)分为两种初始化方式:运行时自动初始化、加载时初始化。
1) 运行时自动初始化
.cinit段与其他段一并从目标文件加载入存储器,链接器定义了一个名为CINIT的符号,用来标识初始化表的首地址。程序开始运行时,C启动程序将表中的数据复制给.bss段中特定的变量,这便允许将初始化数据放入ROM/FLASH中,在每次程序开始时将其复制到RAM中,从而达到ROM/FLASH保存初值、RAM中运行变量的目的。
.cinit段初始化表的格式如下图所示 >(图源:TMS320C28x Optimizing C/C++ Compiler v18.1.0.LTS User's Guide) 2) 加载时初始化:
连接器将.cinit段头中的STYP_COPY置位为1,并告知加载器不要把.cinit中的表加载入存储器并将符号CINIT赋值-1,告诉启动器初始化表不在储存器中,因此启动时不执行初始化。而由加载器直接把目标文件的.cinit复制到RAM的.bss中。 更详细的内容参考《TMS320C28x Optimizing C/C++ Compiler v18.1.0.LTS User’s Guide》7.9.3节

4 全局对象构造

全局对象构造(.pinit)用于C++变成环境,与全局变量初始化过程类似,不详细表述。

5 main函数与exit函数的调用

当完成以上过程之后,整个C程序运行环境就完整地构建好了,便可以进入main函数调用应用程序了 当main函数返回时调用的exit函数,但我们通常会在main函数中放置无限循环来保证main函数不被跳出。若main函数一旦跳出,将调用exit函数,保证程序能够安全退出并重新进入main函数。
阅读过程有疑问
微信扫描二维码
发私信交流
iFTrue
更多关于Bootloader的内容,可以微信扫下面二维码**【iFtrue未来已来】**交流 > 感谢阅读