在许多DSP应用系统中,都需要DSP芯片能够在加电后自动从外部设备加载程序,也就是引导(Boot-load)。TI公司的TMS320C6000系列芯片有三种引导方式可供选择,分别是不加载、ROM加载和主机加载,详细工作流程如下:
不加载:CPU直接从地址0处开始执行代码。如果该处内存是SDRAM,那么CPU会先挂起,等待SDRAM的初始化完成。
ROM加载:位于外部CE1空间的ROM中的代码首先通过DMA/EDMA被搬入地址0处。加载过程在复位信号撤销后开始,此时CPU内部保持复位状态,由DMA/EDMA执行一个单帧的数据块传输。对于C620x/C670x,DMA从CE1空间中拷贝64 KB数据到地址0处。传输完成后,CPU退出复位状态,开始执行地址0处的指令。对于C62x/C67x,用户还可以指定外部加载ROM的存储宽度,EMIF会自动把相邻的8 b/16 b数据合成32 b的指令。
主机加载:也就是HPI加载。CPU停留在复位状态,芯片其余部分保持正常状态。引导过程中,外部主机通过主机接口初始化CPU的存储空间。主机完成所有的初始化工作后,向接口控制寄存器的DSPINT位写1,结束引导过程。此时CPU退出复位状态,开始执行地址0处的指令。
1 ROM加载的实现
究竟使用哪种引导方式取决于芯片引导模式设置,而引导模式由BOOTMODE[4:0]管脚确定。系统加电后,RESET信号有效,DSP芯片复位,在RESET信号上升沿处锁存BOOTMODE[4:0]管脚上的设置值,以此决定DSP芯片内存映射方式、地址0处的内存类型以及复位后芯片的引导模式。本例中C6701的BOOTMODE值设为01101,即8 b ROM加载。
ROM加载是工程中最常见的加载方式,这种方式可以把程序代码段和数据段保存在ROM,FLASH等非易失存储器中,加载过程完全由DSP自动完成,在实际应用中十分方便。ROM加载的具体步骤如下。
1.1 分配存储空间,生成目标文件(.out)
TI代码产生工具产生的目标文件是一种模块化的文件格式——COFF格式。程序中的代码和数据在COFF文件中是以段的形式组织的。对于C语言文件,编译器生成的代码段名为.text。全局变量和静态变量分配在.bss段中,而局部变量或寄存器变量分配到.stack段或使用寄存器。在DSP的配置文件中必须将这些代码段正确地分配到C6701的地址空间中去。
在TI提供的DSP软件开发平台Code Composer Studio(CCS)中,编写DSP系统的工作程序,并对DSP芯片的内存空间、EMIF接口等进行正确的配置后,程序编译通过,CCS就会自动产生目标(后缀为.out)文件,这种.out文件即为COFF格式的。
在ROM加载模式下,复位后C6701将通过DMA方式将FLASH中的前64 KB数据搬运到DSP的片内程序RAM执行,因此,必须将前面编译好的工作程序的代码段烧写到FLASH地址空间中的前64 KB,而数据段则应该烧写在FLASH首地址64 KB以后。这就需要在DSP芯片的内存段管理中,将数据段的加载地址(Load Address)配置为CE1空间FLASH上的指定地址,以保证DSP在复位后能正确地从FLASH上的不同地址读取代码和数据(见图1)。
利用CCS自带的DSP/BIOS配置工具,可以在类似Windows Explorer的窗口界面下直观方便地初始化DSP芯片的数据结构并设置不同的参数,而不需要再单独编写连接命令文件(link command file,后缀为.cmd)。保存该配置文件时,配置工具自动生成匹配当前配置的汇编源文件和头文件以及一个链接命令文件。当构建(Build)应用程序时,这些文件都会自动被链接进应用程序。在CCS中打开DSP/BIOS中的.cdb文件,操作System下的MEM(Memory Section Manag-er)模块就可以对DSP存储器映射空间进行配置,并可以设置程序编译后生成的代码段、数据段是如何分配到这些存储器空间的。这对ROM加载能否成功至关重要,要实现ROM加载必须把一些关键的代码和数据段装在系统的ROM中,但上电后仍在较快的DSP片内RAM中运行。这需要在DSP的内存映射空间上先划分出外部FLASH的起始地址和长度(如图2中的ED-FLASH段),并将CCS编译产生的各个段的运行地址(Run Address)和加载地址(Load Address)分配到合适的存储空间。需要特别注意的是,数据及代码初始化段的加载地址必需放在FLASH空间上(如图3),只读的段都可以放在FLASH上,非初始化段只需要分配运行地址。
下面是用DSP/BIOS配置工具在DSP内存空间中划分好的各段开始地址及长度,其中EDFLASH就是外部FLASH上用于二次加载的地址空间。代码则存放在FLASH的首地址,也就是0x1400000。
1.2 转换文件格式,得到烧写文件(.h)
程序编译好后输出的是COFF格式的.out文件,这种文件无法直接写进FLASH,所以只能将其转换为其他FLASH支持的格式。一般来说,对FLASH烧写的传统方法是通过CCS自带的格式转换器hex6x把.out文件转换为FLASH可识别的十六进制格式(如Motorola-S、ASCII-Hex等),再用专门的编程器将其烧写到FLASH芯片中保存。该方法的实现需要使用专门的FLASH烧写器,实际应用中较为不便,本工程中,在CCS环境下,通过JTAG口,完全由DSP控制对FLASH进行烧写和擦除,实现了对外部FLASH的在线编程。
由于烧写是在CCS程序中实现,所以首先要把.out格式的目标文件转换为工程中可包含的.h文件。根据前面提到的方法,需要把工作程序编译后得到的代码段和数据段分别写进FLASH中的不同地址,这就需要将COFF文件中的代码段和数据段分别提取出来。具体做法是:使用CCS中“FiIe-Data-Save"分别把代码段和数据段保存为dat文件(code.dat和data.dat),代码段和数据段的具体起始地址及长度可以参考程序连接后自动生成的连接过程结果说明文件(后缀为.map,其中记录了段的各种详细信息,从中还可以知道