DSP+FLASH引导装载系统的设计与实现
javascript:window.open(this.src);" style="cursor:pointer;"/>
3 引导装载模型设计
3.1 引导装载原理
加电前,DSP设置为微处理器模式(MP=1)。加电后,DSP首先执行0xFF80处的中断向量表起始处的跳转命令,转向0xF800处的引导程序段并实现代码移植功能。完毕后,再次跳转到移植后的用户程序段的起始地址并执行之。
3.2 逻辑功能分块
引导装载系统包括引导程序段、用户程序段、中断向量表和连接命令文件四部分。引导程序段负责将用户程序段和中断向量表装载到目标地址,用户程序段是实现用户系统功能的核心代码,中断向量表包括加电后的跳转处理和中断服务程序的入口,连接命令文件则是分配各个程序段在DSP地址空间中的位置。
3.3 具体代码实现
引导程序段(load.asm)如下:
.def load_start
.sect "load_prg"
load_start:
ssbx intm ;关中断
rsbx sxm ;符号扩展模式设置为0
ld #0,dp ;定义数据页指针为0
nop
nop
nop
ld #0ff80h,a ;移植中断向量表,0xff80为中断向量表的旧起始地址
stm #VECT_NEW,ar1 ;VECT_NEW表示中断向量表的新起始地址
rpt #(VECT_LEN-1) ;VECT_LEN表示中断向量表的长度
reada *ar1+
nop
ld #MAIN_OLD,a ;移植用户程序段,MAIN_OLD表示用户程序段的旧起始地址
stm #MAIN_NEW,ar1 ;MAIN_NEW表示用户程序段的新起始地址
rpt #(MAIN_LEN-1) ;MAIN_LEN表示用户程序段的长度
reada *ar1+
endboot:
orm #020h,@1dh ;设置OVLY=1,使得内部RAM同时映射到DSP数据和程序空间
ld #MAIN_NEW,a
bacc a ;程序指针指向用户程序段的的起始地址
.end
用户程序段(main.asm)如下:
.def main_start
.sect "main_prg"
main_start:
USER_PRG ;此处添加用户程序段
.end
中断向量表(vect.asm)如下:
.mmregs
.ref main_start
.ref load_start
.def reset
.def nmi
.sect ".vectors"
reset: bd load_start ;加电后,跳转到自启程序段起始地址
stm #200,sp
nmi:rete ;此表中只包含NMI中断入口,也可以类似添加其它中断入口
nop
nop
nop
.end
连接命令文件(boot.cmd)的配置如下:
vect.obj
main.obj
load.obj
-o boot.out
SECTIONS
{
main_prg: load=MAIN_OLD,run=MAIN_NEW
vectors: load=0ff80h,run=VECT_NEW
load_prg: load=0f800h
}
4 写入目标代码
上述引导程序经过CCS编译及连接后,生成的目标文件boot.out是DSP能够识别的COFF格式。但是FLASH不支持这种模式,所以不能直接写入FLASH中。CCS自带有多种HEX类型的转换程序,比如常见的有Intel格式等。但是不同的HEX类型有不同的格式和头尾开销,比如Intel格式中除了数据之外还有起始符、字节个数、起始地址、类型以及校验位等各种信息,并非纯粹数据的HEX格式表示。了解了Intel格式的文件结构之后,就可以从中提取出需要写入FLASH中的代码的HEX格式有相应的地址,即对应上面提到的mydata和myaddress。然后就可以利用上面的方法,用DSP将引导系统各个部分的代码脱机运行前写入FLASH。
5 简单测试实例
利用上述方法,使得系统在脱机状态下实现引导装载,并且从DSP的XF端口输出均匀脉冲波形。直接修改用户程序段可用如下的代码取代用户程序段中的USER_PRG。
loop:rsbx xf
nop
ssbx xf
nop
b loop
经过编译、连接、格式转换以及写入FLASH之后,系统就可以实际脱机运行了。加电一段时间后,可以通过示波器测量得到XF端口的均匀脉冲波形,证明引导装载成功。