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未来已来】**交流
> 感谢阅读