DSP编程技巧:main函数运行之前,你需要知道的
Radow 2022-06-16

  作者:paradoxfx

  在一个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,则_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段,然后建立并初始化栈的指针。其中,栈需要被分配在单一的、连续的一段地址中,起始点为低地址,终点为高地址,栈指针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++的实时运行库环境,否则我们的程序将无法正常运行,甚至根本无法运行。 

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • 处理器
  • DSP
  • CPU
  • GPU
  • 基于DSP的运动控制器的研究

      由于DSP将超强的高速实时处理能力和丰富的外设功能集于一身,目前,以DSP为核心的嵌入式运动控制器已经成为开放式运动控制器的发展主流,并获得广泛的应用。本文

    08-03
  • DSP在自动目标识别中的应用

      自动目标识别(ATR)算法通常包括自动地对目标进行检测、跟踪、识别和选择攻击点等算法。战场环境的复杂性和目标类型的不断增长使ATR算法的运算量越来越大,因此

    08-03
  • 多核DSP提升RNC分组处理能力

      由于与频率提高相关的功耗/散热问题日益突出,指令级并行架构(ILP)及存储能力已近极限,硅芯片已难以支撑处理器性能的大幅度提升。在单芯片上集成多个核,每个核

    08-03
  • DSP编程代码优化技巧

      前面我们提到了使用编译器的优化选项进行不同级别的代码优化的方法。俗话说“好马配好鞍”,即使我们有了强大的代码优化工具,使得我们书写的符合ANSI/ISOC/

    08-02
  • 基于DSP的JPEG图像压缩设计

      一、引言    JPEG算法是一种数字图像压缩编码算法,具有压缩比例高、失真小的特点,并已被确定为国际标准。该标准被广泛应用于数码相机、监视系统、手机、可视

    08-01
  • DSP在电能表中的应用

      实时数字信号处理、超大规模集成电路技术的飞速发展,不断地推动着数字信号处理器性能的提高,使其在信号处理、军事及民用电子技术领域发挥着越来越重要的作用,其应用

    08-01
  • 流式数据处理,它能做什么?怎么使用它最好?

      今日,流式数据处理是大数据里的很重要一环。原因有不少,其中包括:  1.商业(竞争)极度渴望更快的数据,而转换成流计算则是一个好的方法来降低延迟。  2.海

    07-19
  • CPU、GPU5个被误解的概念

      从英特尔1971年推出第一款商用微处理器4004到现在,处理器已经走过了三十多年的历程,目前,CPU处理器已经从服务器、PC发展到嵌入式、工控、消费、医疗等

    07-19
  • 数据指针DPTR的应用特性是什么?

    [导读]它用于存放即将发送或者已经接收的数据,它在SFR块中,只有一个字节地址,但实际上是由发送缓冲器和接收缓冲器组成。这两个缓冲器都是独立的寄存器,当即将发送

    07-12
  • DSP编程技巧的一些问题

      在我们有关DSP的论坛、博客和一些互动活动中,网友经常会问一些有关“编程技巧”的问题。  关于编程技巧的定义,也没有一个统一的标准,例如实现一个很复杂的多层

    07-07
  • LEC对ASIC的重要性

    "ASIC芯片是用于供专门应用的集成电路(ASIC,ApplicationSpecificIntegratedCircuit)芯片技术,在集成电路界被认为是一种

    07-06
  • 采用DSP的谐波控制器设计方案

      当今电力系统中的电能质量问题越来越突出,一方面,大量敏感性负荷对电能质量的要求越来越高,而另一方面,越来越多的非线性负荷不断接入电网,使电力系统总体的电能质

    07-04
下载排行榜
更多
广告