第5章TMS320C54x软件开发•5.1软件开发过程及开发工具•5.2公共目标文件格式•5.3常用汇编伪指令•5.4链接器命令文件的编写与使用•5.5汇编语言程序编写方法•5.6TMS320C54xC语言编程•5.7用C语言和汇编语言混合编程5.1软件开发过程及开发工具1.建立源程序2.C编译器(CCompiler)3.汇编器(Assembler)4.连接器(Linker)5.调试工具6.十六进制转换公用程序(HexConversionUtility)图5-1TMS320C54xDSP软件开发流程编辑器利用CCS3.3,UltraEdit.EXE等文本编辑器编辑*.asm、*.c等源程序。C编译器(CCompiler)作用:将C代码编译成汇编语言。特点:1:完全符合标准C2:带有一个完整的运行支持库,包括字符串操作,动态存储器分配,数据转换,三角函数等。可以对运行库函数和用户定义函数库扩展。注意:区别于普通PC机的C编译器汇编器1、将汇编语言源程序编成一个可重定位的目标文件(.obj文件);2、如果需要的话,可以生成一个列表文件(.lst文件);3、将程序代码分成若干个段,每个段的目标代码都由一个SPC(段程序计数器)管理;4、定义(.def)和引用(.ref)全局符号,需要的话还可以在列表文件后面附加一张交叉引用表;5、对条件程序块进行汇编;6、支持宏功能,允许定义宏命令。链接器链接器各个目标文件•将各个段配置到目标系统的物理存储器中;•对各个符号和段进行重新定位,并给它们指定一个最终的物理地址;•解决输入文件之间未定义的外部引用。归档器:交叉引用列表器:调试工具•软件仿真器(Simulator)•评价模块(EVM)•可扩展的开发系统仿真器(XDS510)DVR系统•4通道图像输入•4通道语音输入•4片TMS320C6211•标准PCI总线•适合于图像监控、医疗仪器、多媒体处理等场合仿真器注:如果你使用3.3V的DSP,你必须使用3.3V5V兼容的仿真器你不能将5V的TTL信号直接加在DSP的输入上JTAG或MPSD标准仿真接口仿真器只提供接口标准,无任何目标系统资源,与目标无关不占目标系统硬件资源接口形式:PCI、ISA、并口支持TMS320全系列DSP兼容3.3/5V支持并行多片开发支持ARM+DSPTMS320C2XX/3X/C5X/C4X/C54X/C6X仿真器插卡TMS320DSP目标系统14芯/12芯仿真插头14芯/12芯仿真插座TMS320C2XX/3X/C5X/C4X/C54X/C6X仿真合仿真电缆仿真器5.2公共目标文件格式•5.2.1COFF文件的基本单元——段•5.2.2汇编器对段的处理•5.2.3链接器对段的处理•5.2.4重新定位•5.2.5程序装入•5.2.6COFF文件中的符号COFF的一般概念•COFF:公共目标文件格式•汇编器和链接器所生成的目标文件,都是COFF文件•COFF的特点:1、按照文本段和数据段编写汇编语言程序2、汇编器命令和链接器命令都是对各种段进行处理3、便于模块化编程和管理4、由若干个段(Section)组成段(Section)•概念:一块连续的储存空间,用于存放代码块或数据块•在编程时,“段”没有绝对定位,每个“段”都认为是从0地址开始的一块连续的储存空间,所以软件开发人员只需要将不同代码块和数据块放到不同的“段”中,而无需关心这些“段”究竟定位于系统何处•优点:便于程序的模块化编程;便于工程化管理:可将软件开发人员和硬件开发人员基本上分离开COFF文件中的段1、己初始化段•已初始化段中包含有数据或程序代码;•.text段和.data段都是己初始化段;•用.sect汇编命令建立的自定义段也是己初始化段。段有两类2、未初始化段在存储器图中,它为未初始化过的数据保留存储空间;.bss段是未初始化段;用汇编命令.usect建立的自定义段也是未初始化段。COFF文件中的段•一般地,COFF目标文件包含3个缺省的段:text段、data段、bss段.text(此段通常包含可执行代码〕.data(此段通常包含初始化数据〕.bss(此段通常为未初始化变量保留存储空间)•此外,汇编器和链接器可以建立、命名和连接自定义段(.sect、.usect).自定义段是程序员自己定义的段,使用起来与.data、.text以及.bss段类似。它的好处是在目标文件中与.data、.text以及.bss分开汇编,链接时作为一个单独的部分分配到存储器。4COFF文件中的段•汇编器——将各部分程序代码和数据连在一起,形成OBJ文件。•链接器——将各个段重新定位到目标存储器。5.2.2汇编器对段的处理-伪指令1.未初始化段•未初始化段主要用来在存储器中保留空间,通常将它们定位到RAM中。这些段在目标文件中没有实际内容,只是保留空间而已。程序可以在运行时利用这些空间建立和存储变量。未初始化段是通过使用.bss和.usect汇编伪指令建立的,两条伪指令的句法分别为:.bss符号,字数符号.usect“段名”,字数2.已初始化段•已初始化段包含可执行代码或已初始化数据。这些段的内容存储在目标文件中,加载程序时再放到TMS320C54X存储器中。三个用于建立初始化段的伪指令句法分别为:.text[段起点].data[段起点].sect“段名”[,段起点]3.命名段•命名段就是程序员自己定义的段,它与缺省的.text、.data和.bss段一样使用,但与缺省段分开汇编。产生命名段的伪指令为:符号.usect“段名”,字数.sect“段名”[,段起点]4.子段•子段(Subsections)是大段中的小段。链接器可以像处理段一样处理子段。采用子段可以使存储器图更加紧密。子段的命名句法为:基段名:子段名•子段也有两种,用.sect命令建立的是已初始化段,用.usect命令建立的是未初始化段。5.段程序计数器(SPC)•汇编器为每个段安排一个独立的程序计数器,即段程序计数器(SPC)。SPC表示一个程序代码段或数据段内的当前地址。开始时,汇编器将每个SPC置0,当汇编器将程序代码或数据加到一个段内时,相应的SPC增加。如果汇编器再次遇到相同段名的段,继续汇编至相应的段,且相应的SPC在先前的基础上继续增加。汇编器对“段”的处理总结•汇编器第一次遇到新“段”时,将该“段”的段程序计数器(SPC)置为0,并将随后的程序代码或数据顺序编译进该“段”中•汇编器遇到同名“段”时,将它们合并,然后将随后的程序代码或数据顺序编译进该“段”中•当汇编器遇到.text、.data和.sect伪指令时,汇编器停止将随后的程序代码或数据顺序编译进当前“段”中,而是顺序编译进遇到的“段”中•当汇编器遇到.bss和.usect伪指令时,汇编器并不结束当前“段”,而只是简单地暂时脱离当前“段”,随后的程序代码或数据仍将顺序编译进当前“段”中。•.bss和.usect伪指令,可以出现在.text、.data或.sect“段”中的任何位置,它们不会影响这些“段”的内容段伪指令应用举例.lst文件(部分)由4个部分(列)组成:第1部分(列)——源程序的行号;第2部分(列)——段程序计数器;第3部分(列)——目标代码;第4部分(列)——源程序。.lst文件.lst文件举例(续上页).lst文件分析在此例中,一共建立了5个段:.text段内有10个字的程序代码;.data段内有7个字的数据;vectors是一个用.sect命令建立的自定义段,段内有2个字的已初始化数据;.bss在存储器中为变量保留10个存储单元;newvars是一个用.usect命令建立的自定义段,它在存储器中为变量保留8个存储单元。图5-3例5-1产生的目标代码5.2.3链接器对段的处理•链接器对“段”的处理有2个方面:将输入“段”组合产生输出“段”将多个.obj文件中的同名“段”合并一个输出“段”也可将不同名的“段”合并产生一个输出“段”将输出“段”定位到实际的存储空间中MEMORY命令:用于扫描系统实际的硬件资源,定义目标系统的存储器配置图,包括对存储器各部分的命名,以及规定它们的起始地址和长度。SECTIONS命令:用于描述程序中定义了哪些“段”,这些“段”是否需要合并?如何合并?合并产生的输出“段”定位到实际硬件资源的何处?•链接器通过.cmd文件来获得上述这些信息•链接器还将检查各输出“段”是否重叠、是否超界,避免了人工检查边界带来的隐患图5-4链接器默认的存储器分配5.2.4重新定位1.链接时重新定位•将各个段定位到存储器中,每个段都从合适的地址开始。•将符号值调整到相对于新的段地址的数值。•调整对重新定位后符号的引用。2.运行时重新定位•将代码装入存储器的一个地方,而运行在另一个地方。利用SECTIONS命令选项让链接器定位两次。一些关键的执行代码必须装入在系统的ROM中,但希望在较快的RAM中运行。•链接器提供了一个简单的处理该问题的方法。利用SECTIONS命令选项让链接器定位两次。第一次使用装入关键字设置装入地址,再用运行关键字设置运行地址。5.2.5程序装入(1)硬件仿真器和CCS集成开发环境,具有内部的装入器,调用装入器的LOAD命令即可装入可执行程序。(2)将代码固化在片外存储器中,采用Hex转换工具(Hexconversionutility),例如Hex500将可执行的COFF目标模块(.out文件)转换成几种其他目标格式文件,然后将转换后的文件用编程器将代码写入EPROM/Flash。5.2.6COFF文件中的符号•COFF文件中有一个符号表,用于存储程序中的符号信息。链接器对符号重定位时使用该表,调试工具也使用该表来提供符号调试。•外部符号指在一个模块中定义,在另一个模块中使用的符号。可使用.def、.ref或.global汇编伪指令将符号定义为外部符号。.def在当前模块中定义,可以在别的模块中使用的符号;.ref在当前模块中引用,但在别的模块中定义的符号;.global可用于以上任何一种情况。