您的位置 首页 系统

DSP编程技巧之21—在main函数运转之前,你需求知道的

在一个C/C++程序能正常运行之前,相关的C/C++运行时(run-time)环境首先要正确建立。在CCS软件编程的情况下,C/C++的实时运行库RTS的源程序库rts.src中包含了名为boot

  在一个C/C++程序能正常运转之前,相关的C/C++运转时(run-time)环境首要要正确树立。在CCS软件编程的情况下,C/C++的实时运转库RTS的源程序库rts.src中包含了名为boot.c或许boot.asm的发动程序(在一些TI的比如里,则运用了CodeStartBranch.asm来完结发动作业,它会主动调用库文件中的boot.asm),用于在体系发动后调用c_int00函数,并经过其间的操作来完结运转时环境的树立。一般情况下,c_int00函数坐落rts2800.lib库函数中的boot.obj(即TI官方编译boot.c或许boot.asm生成的方针文件)下,这也便是为什么咱们在C28x编程的情况下一般要把rts2800.lib库函数参加工程中的原因(其它器材则依据类型、系列增加对应的库文件;不然就会呈现初学者常常遇到的找不到boot.c之类的过错)。

  注:小型内存模型意义是已初始化的段被链接至低 64Kw(字)可寻址空间内的非易失性内存,它运用rts2800.lib。关于定点器材,假如运用大内存模型(超越64K字),则需求运用库 rts2800_ml.lib;关于含有FPU的器材,用于规范 C 言语代码的为 rts2800_fpu32.lib,或许用于 C++ 代码的 rts2800_fpu32_eh.lib(没有针对浮点器材的较小内存模型库)。在 CCS v5/v6 中,有一个针对库的“主动”设置,此设置可据项目的设置(例如,浮点支撑和内存模型挑选)让 CCS 主动挑选正确的库来运用。关于 DSP/BIOS 项目,DSP/BIOS 将担任将所需的库包含在内,咱们用户不需求在项目中包含任何运转支撑库。

  假如在链接器选项中咱们运用了–ram_model或许–rom_mode(详细意义请参阅http://www.eepw.com.cn/article/249328.htm),则_c_int00函数主动被装备为整个程序履行的进口点。此外,在CPU复位之后(相当于一个软件或许硬件的复位中止),咱们也可以把整个程序的进口点指向_c_int00,例如:

  .def _Reset

  .ref _c_int00

  _Reset: .vec _c_int00, USE_RETA

  则在履行CPU复位操作之后,体系主动跳转到_c_int00函数。

  在c_int00函数中完结的功用首要有:

  1. 设置/初始化CPU的状况和装备寄存器。

  2. 为体系的栈界说一个.stack段(关于各个段的意义,请参阅http://www.eepw.com.cn/article/256732.htm),然后树立并初始化栈的指针。其间,栈需求被分配在单一的、接连的一段地址中,起始点为低地址,结尾为高地址,栈指针SP的初始化值指向栈的顶端。

  3. 从初始化表中,把数据复制到.bss段中,然后初始化大局变量。假如运用了—ram_model选项在加载程序时就初始化变量,则在程序运转前,会首要运转一个加载程序来完结变量的初始化。假如运用了–rom_model选项,则运用.cinit中的运转时初始化表来完结变量的初始化。

  默许情况下,链接器运用–rom_model选项,在程序运转时完结变量的主动初始化。在程序运转时,.cinit段和其它初始化的段会被一同加载到内存中,然后使得C/C++的发动程序可以主动把.cinit中的初始化表格复制到.bss段中,完结大局变量的主动初始化。这种办法的特色在于,初始化的表格可以被存放在愈加廉价且大容量的ROM或许FLASH,而不是RAM中,而且可以在程序发动时再主动加载到RAM中,这种办法在咱们把程序烧写到FLASH中再运转的时分是常常运用的。关于Flash运转的更多信息,可以参阅TI的的一个运用陈述:http://www.ti.com.cn/cn/lit/an/zhca550l/zhca550l.pdf,从 TMS320F28xxx 数字信号处理器 (DSP) 上的内部闪存存储器上运转一个运用。

  假如运用—ram_model的链接器选项,则链接器会在.cinit段的最初中装备STYP_COPY位(0010h),告知加载器不要把.cinit段主动加载到内存中,而且把cinit这个符号设置为-1(默许情况下符号cinit指向初始化表格),然后向发动程序标明,内存中没有初始化表格,在发动时不需求履行运转时的初始化作业。在这种情况下,需求咱们自界说一个加载程序,然后在加载程序时就完结初始化,它的首要内容包含:

  ü 在方针文件中检测.cinit段的存在;

  ü 在.cinit段的最初装备STYP_COPY位,使得该段不会被主动复制到内存中;

  ü 需求咱们了解并正确遵从初始化表格的格局。

  这三个留意点形似比较复杂,不过有读者可能会问,咱们在直接把程序经过JTAG下载到DSP的RAM中并运转的时分,形似并没有装备这么费事的过程啊?那是由于CCS编程环境现已帮咱们承当了这一重要任务,在咱们用仿真器来调试、运转的时分常常会运用到这个办法。

  留意:在C/C++程序运转之前,一些大局变量有必要被赋予初始值。在ANSI/ISO C中,未清晰初始化的大局和静态变量在程序履行前都需求被初始化为0,C/C++的编译器并不会对它们进行主动初始化。在把程序加载到RAM而不是ROM中的情况下,比较便利的办法是直接把.bss段初始化为0。

  而在C28x DSP的编程中,假如一个大局变量的初值并不会对程序的运转成果发生任何影响,则咱们一般不必考虑给它们赋初值,由于编译器会运用.cinit段中的初始化表格来初始化变量,叫做主动初始化autoinitialization,其暗示图为:

  在运用了–ram_model或许–rom_mode选项的情况下,链接器在把一切C/C++模块中的相关变量初始化的内容链接入.cinit段之后,会主动在其结尾参加null关键字,来标明初始化表格的结尾。

  4.调用.pinit中的一切的大局结构函数。

  .pinit段中的内容相对简略,它首要包含了结构的地址列表。在.cinit初始化完结之后,结构函数的地址就呈现在结构函数地址列表中了。

  在运用了–ram_model或许–rom_mode选项的情况下,链接器在把一切C/C++模块中的结构函数的地址链接入.pinit段之后,会主动在其结尾参加null关键字,来标明结构函数地址的完毕。

  与.cinit段不同的时,不论运用–ram_model仍是–rom_mode选项,.pinit段都会在运转时被加载和处理。

  5.调用main()函数,履行咱们的程序。

  6.在main()函数回来时,调用exit函数。

  依据需求,咱们可以自界说发动函数,可是一定要确保咱们的自界说函数可以正确完结以上的过程以树立C/C++的实时运转库环境,不然咱们的程序将无法正常运转,乃至底子无法运转。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/117885.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部