(二) 链接器对块的处理
链接器对块的处理有两个功能:其一,将COFF目标文件中的块用来建立程序块和数据块,并将这些块组合成可以被DSP芯片执行的COFF输出模块;其二,链接器为输出块指定存储位置。
链接器提供两个命令实现上述功能:MEMORY和SECTIONS。MEMORY命令定义目标系统的存储器,程序员可以定义每一块存储器并指定起始地址和长度;SECTIONS命令用来定义输入块的组合和输出块在存储器中的存放位置。若不用MEMORY和SECTIONS命令,链接器采用缺省的分配算法;推荐使用这两个命令,但要注意这两个命令在CMD文件(链接器命令文件)中使用。
下面分析一个TMS320F240芯片的典型CMD 文件。(假设文件名EX1.CMD)
1、 CMD文件的构成及其详细解释
- BOOT.OBJ /* F240的中断矢量表,参见后面的说明 */
- EX1.OBJ /* 源程序编译后对应的目标文件 */
- /* 若程序有多个目标文件,一块写在这里 */
- -STACK 0X400 /* 设定系统堆栈 */
- -C /* ROM初始化 */
- -O EX1.OUT /* 输出的文件名 */
- -M EX1.MAP /* 输出映像文件名 */
- -L RTS2XX.LIB /* 链入RTS2XX.LIB库 */
- MEMORY /*MEMORY命令规定系统的存储器配置 */
- {
- PAGE 0:ROM0: origin=0000h,length=003fh /* FLASH ROM */
- PAGE 0:ROM1: origin=0040h,length=0200h /*FLASH ROM */
- PAGE 0:ROM2: origin=0240h,length=3000h /* FLASH ROM */
- PAGE 1:RAM_B2:origin=0060h,length=0020h /* 内部RAM B2 */
- PAGE 1:RAM_B1:origin=0300h,length=0100h /* 内部RAM B1 */
- PAGE 1:RAM_B0:origin=0100h,length=0100h /* 内部 RAM B0 */
- PAGE 1:RAM_EX:origin=0d000h,length=2800h /* 外部扩展RAM */
- }
- SECTIONS /* SECTIONS 命令规定了程序中块的具体分配方法 */
- {
- .vectors:load=ROM0 /* 规定矢量表的存放位置 */
- .cinit: load=ROM1 /* C初始化表的存放位置 */
- .text: load=ROM2 /* 系统程序的存放位置 */
- .bss load=RAM_B0 /*未初始化数据的存放位置 */
- .const load=RAM_B1 /* 已初始化数据的存放位置 */
- }
2、TMS320F240链接时所需的中断矢量表文件
TMS320F240的目标文件在链接时要用到中断矢量表,中断矢量表用汇编语言编写,和具体的DSP芯片有关,假设TMS320F240的中断矢量表对应的汇编程序为BOOT.ASM,汇编后的文件名为BOOT.OBJ。
下面是一个典型的矢量表文件(假设程序名为BOOT.ASM)。
- .port /* 定义中断函数的名字 */
- .globl _c_int0 /* 中断0对应的函数名 */
- .globl _c_int1 /* 中断1对应的函数名 ,以下语句的意义相同*/
- .globl _c_int2 /* 可以将中断函数名看作中断入口地址 */
- .globl _c_int3 /* 矢量表的存放不需程序员干预 */
- .globl _c_int4
- .globl _c_int5
- .globl _c_int6
- .globl _c_int7
- .globl _c_int8
- .sect “.vectors”/*用.sect命令自定义一个块,用于存放中断矢量表 */
- RSVECT B _c_int0 /* 中断0发生后,程序的跳转目的地址 */
- INT1 B _c_int1 /* 中断1发生后,则跳到c_int1()函数处 */
- INT2 B _c_int2 /* 意义同上,下同 */
- INT3 B _c_int3
- INT4 B _c_int4
- INT5 B _c_int5
- INT6 B _c_int6
用汇编器汇编该程序,命令形式:DSPA BOOT.ASM –V2XX 生成BOOT.OBJ文件供链接器使用。这样,我们就可以按如下形式在C源程序中编写中断函数:
void c_intx() /* x为1—8中之一 */
{
中断程序的C语句系列;
}
注意事项:c_int0()是系统入口函数,用户不能编写。
经过上面对命令文件(CMD文件)和中断矢量表的介绍,接下来可以链接命令文件来生成所需要的OUT文件供DSP芯片执行或进行软仿真。
命令形式:DSPLNK CMD文件名 例如:DSPLNK EX1.CMD
另一种情况是,不使用CMD文件,使用缺省配置,简单介绍如下:
命令形式:DSPLNK OBJ文件名 参数
例如 DSPLNK EX1.OBJ BOOT.OBJ –O XX1.OUT –M XX1.MAP
以上三步可以用下图描述:
四 程序的仿真
EMURST 仿真器复位命令
EMU2XXW EX1.OUT 载入COFF格式的二进制代码仿真运行,有关调试器的使用限于篇幅在此就不做讨论了。
五 程序的固化
程序仿真运行正确后,需要固化到FLASH ROM中,TMS320F240内部有16K字的FLASH ROM可以用来固化程序,而不需要外扩EPROM(程序不大于16K字的情况下)。
TI公司提供有固化程序的软件,可以通过仿真器经JTAG口将程序写入芯片内。目前发展了一种新的固化技术,可以通过串口写入DSP芯片,特别适合于现场调试。下面介绍通过JTAG口的固化方法。
首先用EMURST命令复位调试器,然后执行下面三个批处理文件。
第一步,执行BC0.BAT 批处理文件,将FLASH ROM 清除(CLEAR),使全为0。
第二步,执行 BE0.BAT 批处理文件,将FLASH ROM 擦除(ERASE),使全为1。
以上两步不需要修改软件包中自带的这两个BAT文件。
第三步,执行BP16K.BAT 批处理文件,将自己的OUT文件写入到DSP内部的FROM中。
执行这一步之前,要先修改BP16K.BAT,将待写入的OUT文件替换成自己的OUT文件,下面看一下这个批处理文件。假设软件包的安装目录为C:\DSP,该目录下有一个子目录SRC。
prg2xx -p 240 -m 0x0006 -w 6 src\c2xx_bpx.out 要写入的OUT文件
如果要将EX1。OUT写入到DSP的FLASH中,则执行下面的命令:
prg2xx -p 240 -m 0x0006 -w 6 src\c2xx_bpX.out c:\dsp\EX1.out
经过以上步骤既完成了程序固化,可以将系统放到现场实验了。
注意:固化程序时,CPU的一定要工作在20MHz的频率下。在SRC子目录下有一个配置文件C240_CFG.I文件,读者可以根据程序说明并结合自己系统的外部晶振频率将CPU的工作频率设为20MHz(写入时的频率)。
结 论
本文以TMS320F240的开发为例,介绍了怎样用C语言开发DSP系统的全过程,希望对读者会有所启发和帮助。有关怎样用C语言编程使用 TMS320F240内部其他资源(如:定时/比较器、ADC、SCI、SPI、中断器)和怎样扩展DSP的外围电路等编程技术见后面的叙述。