软件开发工具主要有源程序编辑器(Editor)、编译器(Compiler)、汇编器(Assemb-ler)、链接器(Linker)、归档器(Archiver)、运行时支持库(Run-Time-Support Library)、库建立程序(Library-build Utility)、HEX转换程序(Hex Conversion Utility)、绝对列表器(Absolute Lister)及调试工具(Debugging tools)等。
(1)编译器
CCS的C/C++编译器接收标准ANSIC/C++源文件(.c或.cpp),并将其编译成C28x的汇编语言源文件。编译器是整个CCS的外壳程序(Shell Program)的组成部分之一。外壳程序是CCS的基本组成部分,它由编译器、汇编器和链接器组成,可以使用户一次完成对源程序的编译、汇编以及链接等功能。CCS的C/C++编译器由三个软件包组成:编译器本体、优化器(Optimizer)以及交互列表器(Interlist Utility)。优化器用于对编译生成的汇编代码进行优化和修改,以提高C/C++程序的运行效率。交互列表器用于将C/C++表达式编译后的汇编指令输出,借助这个工具,用户可以查看C/C++语句所对应的汇编语句。
图4-2 软件开发流程框图
(2)汇编器
CCS的汇编器是其外壳程序的第二部分,用以将汇编语言源文件(扩展名为.asm)翻译成机器语言COFF目标文件(.obj)。汇编语言源文件可以来自C/C++编译器,也可以由用户直接编辑生成。汇编语言源文件除了包含程序指令,也包含汇编器命令(Assembler Di-rective)和宏命令(Micro Directive)。汇编器命令采用一种指令形式的描述性语言来对汇编过程进行编程和控制。宏命令则提供了一种用户可以自定义指令的方式,用户可以将一个复杂的汇编语言代码块或重复使用的代码块定义为一个宏,在源文件中,通过引用宏不仅可以简化文件的编写,也可减小文件的长度。COFF(Common Objective File Format,公共目标文件格式)是一种二进制目标文件格式,这种格式的特点是将程序代码和数据块分成段(Sec-tion)。段是目标文件中的最小单位,每个段的代码和数据最终占用连续的存储器地址,一个目标文件中的各段都是互相独立和有区别的。
(3)链接器
CCS的链接器是其外壳程序的第三部分,用于将汇编器生成的多个COFF目标文件组合成一个可执行的COFF可执行输出文件(.out)。通常,汇编器生成的COFF目标文件中各代码段或数据段(如.text、.data和.bss)只具有相对地址,它与系统的物理存储器地址之间没有任何关系,必须对其进行地址定位和分配后,这些目标文件才能变成可执行的文件。CCS的链接器有三个主要的作用:①支持用户将COFF文件中的各代码段和数据段分配到实际目标系统的物理存储器中;②根据用户的分配要求,对各代码段和符号重新进行安排,并赋予其最后确定的物理地址;③处理多个文件之间那些没有被定义的外部引用(变量名或函数名等)。用户可以通过链接命令文件(.cmd)来描述实际目标系统的物理存储器地址并进行段的分配,链接器将调用该命令文件实现对目标文件的链接工作。
(4)归档器
为了重复利用源代码,减小源代码的编写工作量,使用宏是一种有效的办法,而大量的宏可以被组织在一起形成一个专门的库。同样,通用函数的编写也会节省代码量。例如,将一个算法程序写成专门的函数,这是实现模块化编程一般采用的方法,大量这样的函数被组织在一起形成一个库文件。当编写一个新的用户程序时,有效地利用这些宏库或者函数库不仅可以大大节省程序的开发工作量,而且还可以方便地实现程序移植。归档器就是用于建立这样的宏库或函数库的非常有用的软件工具。归档器可以帮助用户将许多单个的文件组成一个库文件,这些文件可以是源文件,也可以是汇编后的目标文件。无论是汇编器或者是链接器都接受由归档器建立的库文件作为输入,汇编器接受源文件库作为输入,而链接器则接受目标文件库作为输入。例如,当汇编器对用户源程序进行汇编时,它遇到一个宏引用,则汇编器会搜索归档器建立的宏库以找到被引用的宏并将其嵌入引用宏的位置。同理,当链接器对用户程序进行链接的时候,当它遇到一个外部函数的调用,它会解析这个函数名,并且到归档器建立的目标文件库中去寻找这个同名函数,并为其安排相同的物理地址。归档器除了可以创建库,也可以对库进行修改,比如对库成员进行删除、替换、提取和添加等功能。
(5)运行时支持库
运行时支持函数是C/C++编译器的一个重要组成部分。C/C++用户经常调用一些标准ANSI函数来执行一个任务,如动态内存分配、对字符串的操作、数学运算(如求绝对值、计算三角函数和指数函数等)以及一些标准的输入/输出操作等,这些函数并不是C/C++语言的一部分,但是却像内部函数一样,只要在源程序中加入对应的头文件(如stdlib.h、string.h、math.h和stdio.h等)就可以调用和使用。这些标准的ANSI函数就是C/C++编译器的运行时支持函数。C28x的C/C++编译器所有的运行时支持函数,其源代码均被存放在一个库文件rts.src内,这个源库文件被C/C++编译器汇编后可生成运行时支持目标库文件。C28x的C/C++编译器包含了两个经过编译的运行时支持目标文件库:rts2800.lib和rts2800_ml.lib。前者是标准ANSIC/C++运行支持目标文件库,而后者是C/C++大存储器模式运行支持目标文件库,两者都是由包含在文件rts.src中的源代码所创建。所谓的大存储器模式是相对标准存储器模式而言的,在标准存储器模式下,C/C++编译器的默认地址空间被限制在存储器的低64KW,地址指针也是16位。而C28x编译器支持超过16位的地址空间的寻址,这需要采用大存储器模式。在此模式下,C/C++编译器被强制认为地址空间是22位的,地址指针也是22位的,因此C28x全部22位地址空间均可被访问。在rts2800.lib和rts2800_m1.lib中,除了标准的ANS IC/C++运行时支持函数外,还包含一个系统启动子程序_c_int00。运行时支持目标文件库作为链接器的输入,必须与用户程序一起被链接,才可以生成正确的可执行代码。
(6)库建立程序
C28x的C/C++编译器允许用户对标准的运行时支持函数进行查看和修改,也可以创建自己的运行时支持库,这通过归档器或建库器来完成。比如,用户可以利用归档器从rts.src中提取某个运行时支持函数的源代码进行修改,然后调用编译器对其进行编译和汇编,最后再利用归档器将汇编后的目标文件写入运行时支持目标库(如rts2800.lib)中。按照同样的步骤,用户也可以创建新的运行时支持库。不过,通过建库器来创建新的运行时支持库有时更加方便和灵活。比如,编译器的不同配置条件和编译选项有时会对生成的运行时支持库有影响,不同条件下生成的运行时支持库未必能完全兼容,此时为了建立合适自己的运行时支持库,经常不需要改变源代码,而仅仅是修改编译器的配置和选项,这样在使用建库器时就更加方便了。(www.daowen.com)
(7)HEX转换程序
用户程序经过C28x的编译器和链接器生成可执行的COFF文件,可以将该文件下载到目标系统的SRAM中运行和调试,或直接烧写到DSP的片内Flash或者片外可编程存储器EPROM中。CCS提供一个Flash烧写程序,该程序接受标准COFF格式的可执行文件并通过JTAG仿真器实现对DSP片内Flash的编程。不过要将程序写入片外EPROM中,则一般情况下需要采用通用编程器来进行。尽管COFF这种格式非常有利于模块化编程以及提供了强大和灵活的管理代码段和目标内存的能力,但是大多数的EPROM编程器并不能识别这种格式,因此CCS提供HEX转换程序,用于把COFF目标文件转换成可被通用EPROM编程器识别的16进制目标文件格式。HEX转换程序还可以被用于其他需要将COFF文件转换为16进制目标文件的场合,如调试器和上电引导加载(Boot loader)应用。
(8)绝对列表器和交叉引用列表器
绝对列表器(Absolute Lister)和交叉引用列表器(Cross-Reference Lister)均为调试工具,其中绝对列表器接受链接后的目标文件作为输入,生成一些列表文件(扩展名为.abs),这些文件列举了链接后的目标代码的绝对地址,这个工作如果采用手工来完成,将需要很多非常烦琐的操作,绝对列表器可以帮助自动完成这个工作。交叉引用列表器也接受链接后的目标文件作为输入,生成一些交叉引用列表文件(扩展名为.xrf),这些列表文件中列举了所有的符号名、它们的定义以及在被链接的源文件中的引用位置。
(9)C++名称复原程序
一个C++源程序中的函数,在编译过程中其函数名会被编译器修改成链接层的名称,当用户直接查看编译器生成的汇编语言文件时,往往不能将其和源文件中的名称对应起来,此时借助C++名称复原程序(C++Name Demangling Utility),则可以将修改后的名称复原成源文件中的名称。
(10)调试器
除了提供代码生成的功能,CCS的另外一个重要的功能就是在线调试。CCS可以将链接生成的可执行的COFF文件通过JTAG仿真器下载到目标系统的RAM中运行,通过调试器(Debugger)来控制程序的运行。CCS的调试器提供了丰富的调试功能以帮助用户对其程序进行调试和修改。这些调试功能包括单步运行、设置断点、变量跟踪、查看寄存器和存储器内容以及反汇编等基本功能,另外还有一些高级功能,如图形工具(Graphic Tool)和探测点(Probe Point)工具。CCS调试器的图形工具,可以对保存在连续存储器区域的数据进行绘图处理。使用探测点工具可实现程序调试过程中数据的导入和导出,当遇到探测点时,可设定从PC将某原始数据文件导入到DSP的相应存储器,或者将存储器中的数据处理结果存储成某一个文本文件。利用探测点工具和断点工具配合可及时更新显示图形和动画。
(11)GEL语言
CCS还提供了一种GEL语言。GEL(General Extension Language,通用扩展语言)是一种类似于C语言的解释性语言,它被用来创建GEL函数,以扩展CCS的功能和用途。GEL是C语言的一个子集,即其语法结构遵从标准C的规定,不过它不能定义和声明变量,所有的变量必须在DSP的源程序中被定义。用户创建的GEL函数及其参数可用于对这些DSP源程序中定义的变量进行操作,比如进行赋值以及运算等。GEL函数的这个作用对于用户执行一个调试任务非常有用。例如,用户在调试程序时经常需要在线修改一个变量的值以测试程序的运行是否正常,如果在源程序里对这个变量进行赋值,则每次都要停止当前调试,修改变量值,然后对源程序重新进行编译、链接和下载,显然这种方法对于调试工作非常不利。采用GEL函数则可灵活实现上述调试任务,当用户在调试中需要修改变量值的时候,不用停止当前调试,只要编写一个GEL函数并运行(该函数实现对变量的赋值操作),即可完成修改操作,然后可继续执行用户后面的调试任务。GEL函数还可以用来在调试状态下动态控制和修改目标系统的配置(如对目标系统进行复位、禁止或使能看门狗、配置CPU时钟以及修改其各种外设的配置等),使用户对程序的调试更容易。另外,GEL函数可以用于创建不同风格的输出窗口,并且在窗口内显示变量内容。通过GEL函数用户能够在调试中访问存储器,创建输出窗口并显示寄存器、变量或者存储器内容等。
GEL函数可在任何能键入C表达式的地方调用,既可以在对话框中调用,也可以在其他GEL函数中调用。通常,GEL函数可写到一个GEL文件(扩展名.gel)中,然后利用CCS的GEL文件载入功能将其加载到CCS环境中,在加载的过程中,该GEL函数会被执行。还可以直接将GEL函数键入一个GEL命令窗口(在CCS的View菜单下打开GEL工具条即可显示该窗口),然后单击“执行”。对于28035,TI提供了一个专门的GEL文件f28035.gel,这个GEL文件中包含一个Startup()函数,每当CCS启动的时候,Startup()内定义的其他GEL函数会自动执行。f28035.gel可被添加到一个项目文件中或者通过CCS的配置工具被指定,运行它的结果是在CCS的GEL菜单下添加一系列的菜单命令(也即一系列的GEL函数),用户可以通过鼠标来选择执行这些菜单命令。
(12)DSP/BIOS
CCS中还集成了一个嵌入式实时多任务操作系统内核DSP/BIOS。它为用户提供了更加便捷和面向对象的软件开发途径,用户可以基于此操作系统内核开发自己的嵌入式DSP程序。DSP/BIOS具备一般操作系统的重要特征。DSP/BIOS由三个重要部分组成:应用程序接口(API)、对象配置工具以及实时分析工具(Real-Time Analysis Tool)。API是DSP/BI-OS的核心,用户程序通过调用API来使用DSP/BIOS。DSP/BIOS的API被分成许多对象模块,用户可以根据自己的需要选择使用这些模块,从而实现对DSP/BIOS尺寸的裁剪和定制。DSP/BIOS的对象配置工具主要用于静态创建API对象并设置其属性,创建的API对象将被用户程序调用。静态API对象在程序运行期间都是存在的,不能在运行时删除;当然,API对象也可以在运行时被动态创建和删除。静态创建API对象可以减小用户代码的长度,也可以减少动态创建对象的时间开销,不影响用户程序的实时性。此外,只有静态创建的API对象其运行特性能够由实时分析工具监测。DSP/BIOS的实时分析工具采用可视化的方法对目标系统中用户程序的运行情况进行实时监测,这包括程序的跟踪(显示程序运行中发生的各种事件、被执行的进程及其动态变化)、性能监控(统计目标系统的资源消耗,如CPU的负荷和时间开销)以及数据流记录(将目标系统驻留的I/O对象的数据流记录到PC的文件中)。与传统的调试工具不同,DSP/BIOS的实时分析工具利用API对象,在程序运行过程中采集数据并上传到PC,该工具对用户程序的实时性几乎没有影响;而传统的调试工具需要暂停程序的运行,然后收集寄存器或变量内容等信息进行上传。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。