C5402 DSP自举引导方法的分析与研究
扫描二维码
随时随地手机看文章
在DSP领域,TI公司(德州仪器公司)一直处于世界霸主地位,它生产的TMS320系列DSP芯片以其独特的哈佛结构、硬件密集型方案和灵活的指令系统成为数字信号处理器产业中的领先者[1]。其C5000系列DSP芯片具有功耗小、高度并行等优点,可以满足众多领域的实时处理要求。尤其是新近推出的TMS320VC5402及 TMS320UC5402(简称’C5402)以其独有的高性能、低功耗及低价位等优势,在推出之初便受到业界人士的普遍欢迎。
为充分利用DSP快速运行的优点,通常希望用户程序能在DSP中高速运行,这就需要运用DSP自举引导功能。本文以’C5402为例,说明自举引导的特点及自举表建立的步骤。
1 几种自举引导方式
1.1 自举引导方式简介
众所周知,欲获得全速的DSP运行速度,方法之一是在DSP芯片出厂前将用户程序掩膜在其片内的ROM上。这种方法对大部分应用场合并不适用,且成本很高。对大多数用户而言,可行的方法是利用DSP自举引导功能。
Bootlooader(自举引导程序,也称引导装载程序)是在出厂前固化在DSP芯片内ROM中的一段程序代码,其主要功能是在上电或复位时将用户程序从外部加载至程序存储器(片内RAM或扩展的RAM)中,以便实现高速运行。因此,用这种方法可以以较低的成本实现高速运行。不同型号的DSP,其Bootlooader也不同。如TMS320C54X系列的DSP提供了四种自举引导方法[2]:并行EPROM、并行I/O口、串行口及主机接口HPI自举引导方式,它们适用于不同的应用场合。
1.2 ’C5402 DSP自举引导方式
新近推出的’C5402 DSP片内ROM掩膜的Bootlooader程序与TMS320C54X系列的其它DSP有较大的不同,它包括以下五种自举引导方式:主机接口HPI、并行口、标准串行口、8位串行EEPROM及I/O口自举引导方式。
DSP上电复位后,首先检查其MP/引脚,如果该引脚为高电平,说明DSP被设置为微处理器工作方式,即从外部程序存储器0FF80h地址开始执行用户程序;若该引脚为低电平,说明DSP被设置为微计算机工作方式,即从片内ROM的0FF80h起执行程序。’C5402 DSP片内4K ROM掩膜了TI设计的几段程序,其中包括自举引导程序,具体内容如表1所示[3]。因此,为利用自举引导功能,必须将DSP设置为微计算机工作方式,即MP/=0。
由表1可见,从片内ROM的0FF80h地址开始存放的是中断向量表,它实为一条分支转移指令(BD 0F800h)。该指令使程序跳转至0F800h,并从此开始执行自举引导程序。
在执行自举引导搬移程序之前,首先进行初始化,其程序片段如下:
0000:F800
SSBX INTM ; INTM=1,使中断失效
STM #0FFFFh,IFR ; 清除IFR标志
LD #0h,DP ; DP=0,数据存储器页指针为0
ORM #02B00h,ST1 ; XF=INTM=OVM=SXM=1
ORM #020h,PMST ; OVLY=1
STM #07FFFh,SWWSR ; SWWSR=07FFFh
STM #07Dh,SP ; SP=07Dh
从以上程序可看出,初始化的内容主要包括:
①关闭所有可屏蔽中断(INTM=1);
②将片内DARAM映射至程序/数据存储空间(OVLY=1);
③将程序、数据及I/O存储空间均设置为7个等待状态(SWWSR=07FFFh)。
初始化完成后,根据外部设定的条件,选择不同的自举引导方式,判断条件是有先后顺序的,其流程如图1所示。
图1中各种自举引导方式各有特点[3]: [!--empirenews.page--]
①主机接口HPI自举引导方式
欲执行的程序代码通过HPI(主机接口总线)由外部主处理器加载至片内存储器中。一旦主处理器改变了被加载代码的起始地址(存放于内存007Fh处),便开始执行程序。
②8位串行EEPROM自举引导方式
自举引导程序通过一串联的EEPROM读取自举表,并按照自举表中指定的方式加载代码。该EEPROM与设置为clockstop模式的多通道缓冲串口McBSP1相连接。
③并行自举引导方式
自举引导程序通过外部并行接口总线读取存放于数据存储空间中的自举表。自举表的内容包括:欲加载的各段代码、各代码段长度、各代码段存放的目标地址、程序入口地址及其它配置信息。
④标准串行口自举引导方式
自举引导程序通过被设置为标准模式的多通道缓冲串口McBSP0读取自举表,并按照自举表中指定的方式加载代码。McBSP0及McBSP1分别支持16位及8位串行接收方式。
⑤I/O自举引导方式
自举引导程序通过外部并行接口总线从地址为0h的I/O口读取自举表。该外部并行接口总线使用了异步握手协议(利用XF及BIO引脚),使数据传输速度可按外部设备的要求设置。
2 并行自举引导方式
在’C5402的五种自举引导方式中,并行自举引导方式是最常用的一种。欲加载的各代码段存放在字宽为8位或16位的外部存储器中,在自举引导时,通过外部并行接口总线将这些代码从数据存储空间传送到程序存储空间。
在并行引导方式中,由于可重新设置SWWSR及BSCR寄存器的内容,所以当从快速的外部存储器EEPROM引导用户程序时,可采用较少的软件等待状态(默认为7个等待状态)。
并行自举引导方式流程图如图2所示。从图2可知,自举表首地址既可从地址为0FFFFh的I/O口读取,也可从地址为0FFFFh的数据存储器获得。两种方式中,后者更为方便,因为在单片的外部存储器EPROM或FLASH中可同时包含自举表内容及自举表存放的首地址。对’C5402而言,有效的外部数据存储器的地址范围为04000h~0FFFFh。
并行自举引导程序片段如下:
...
xentry .set 61H ;61h存放程序入口地址的XPC值
entry .set 62H ;62h存放程序入口地址
src .set 65H ;65h存放自举表首地址
... [!--empirenews.page--]
0000:F831
STM #0h, @xentry ;初始化程序入口地址
STM #boot, @entry ;
PORTR #0FFFFh,@src ;从I/O口读取自举表的首地址
MVDK @src,AR1 ;将自举表的首地址送至AR1中
LD *AR1+,A ;(AR1)→A, AR1=AR1+1
SUB #010AAh,A,B ;B=A-10AAh
BC par16,BEQ ;若B=0,执行16位并行自举程序
AND #0FFh,A ;屏蔽A高16位
SUB #08h,A,B ;B=A-08h
BC chk_data,BNEQ ;若B≠0, 程序跳转至chk_data
LD *AR1+,A ; (AR1)→A, AR1=AR1+1
AND #0FFh,A ;屏蔽A高16位
SUB #0AAh,A ;A=A-0AAh
BC par08,AEQ ;若A=0, 执行8位并行自举程序chk_data STM #0FFFFh,AR1 ;从数据存储器读取自举表首地址
NOP ;避免流水线冲突
NOP ;避免流水线冲突
LD *AR1+,A ;(AR1)→A, AR1=AR1+1
STLM A,AR1 ;将A低16位内容存入AR1中
NOP ;避免流水线冲突
NOP ;避免流水线冲突
LD *AR1+,A ;(AR1)→A, AR1=AR1+1
SUB #010AAh,A,B ;B=A-10AAh
BC par16,BEQ ;若B=0,执行16位并行自举程序
STM #0FFFFh,AR1 ;(0FFFFh)→AR1
NOP ;避免流水线冲突
NOP ;避免流水线冲突
LDU *AR1-,A ;(AR1)→A,AR1=AR1-1,符号位置0
AND #0FFh,A ;屏蔽A高16位
SUB #08h,A,B ;B=A-08h
BC ser_ini,BNEQ ;若B≠0, 程序跳转至ser_ini
LD *AR1+,A ;(AR1)→A, AR1=AR1+1
AND #0FFh,A ;屏蔽A高16位
SUB #0AAh,A ;A=A-0AAh
BC par08,AEQ ;若A=0,执行8位并行自举程序
ser_ini
... ;标准串行口自举引导程序
par08
... ;8位并行自举搬移程序
par16
... ;16位并行自举搬移程序
3 自举表的建立
自举表的内容不仅包括了欲加载的各段代码,而且包括各段代码长度、各代码段存放的目标地址、程序入口地址等信息。因此若想利用自举引导功能,首先必须正确建立自举表。自举表可由hex500格式转换器自动生成。hex500实际为一通用程序,它将公共目标文件格式——COFF文件转换成各种EPROM或FLASH的编程格式。因此,在使用hex500工具之前,首先必须对DSP的汇编语言、C语言或两者的混合编程语言进行汇编、编译、链接,生成COFF格式的.out文件,然后再通过设置适当的选项生成用户所要求的自举表。
为了书写及修改方便,可将hex500的所有选项及输入输出文件名以.cmd 批处理命令文件的形式保存。下面以一个DSP汇编语言程序example.asm为例,说明建立’C5402自举表的具体步骤。
第一步:对example.asm进行编译,生成example.obj文件。不论是用Windows 环境下的CCS(Code Composer Studio),还是用DOS环境下的asm500命令文件,编译时必须加选项—v548,且DOS的asm500版本必须在1.2以上,否则无法生成正确的’C5402自举表。
第二步:链接,生成example.out文件。
第三步:使用hex500格式转换工具,将example.out文件转换成example.hex文件,命令格式如下:
C:tic5400cgtoolsbin>hex500 example.cmd
注:在上面的命令行中,example的扩展名cmd一定要加上。
以下是命令文件example.cmd的内容:
example.out /*被转换的COFF文件名
-e 200h /*程序入口地址被定义为200h
-a /*转换为ASCII-hex格式文件
-o example.hex /*转换后文件名为example.hex
-memwidth 16 /*外部数据存储器字宽为16位
-romwidth 16 /*ROM字宽为16位
-boot /*将COFF文件中各段均转换至自举表
-bootorg 8000h /*存放自举表的首地址为8000h
如果example.asm是一个简单的求乘法累加运算,程序内容如下[2]:
*****************************************
* example.asm y=a1*x1+a2*x2+a3*x3+a4*x4 *
***************************************** [!--empirenews.page--]
.title ″example.asm″ ;源程序取名为example.asm
STACK .usect ″STACK″,10h ;为名为STACK的堆栈预留16个单元
.bss x, 4 ;在数据存储器中为未初始
.bss a, 4 化变量(续) x, a, y分别
.bss y, 1 预留4,4,1个单元
.def start ;
.data ;以下为数据段
table:.word 1, 2, 3, 4 ;在以标号table开始的8个
.word 8, 6, 4, 2 程序存储单元中存放8个已初始化数据
.text ;以下为程序段
start: STM # STACK+10,SP ;设置堆栈指针
STM # table, AR1 ;AR1指向table的首地址
STM # x, AR2 ;AR2指向存放变量x的首地址
STM # 7, AR0 ;AR0=7
LD # 0, A ;A=0
loop: LD *AR1+, A ;(AR1)→A, AR1=AR1+1
STL A, *AR2+ ;A→(AR2) , AR2=AR2+1
BANZ loop,*AR0- ;若AR0≠0,循环,AR0=AR0-1
CALL sum ;若AR0=0,调用sum子程序
end: B end ;
sum: LD #0, A ;A=0
STM #a, AR3 ;AR3指向存放变量a的首地址
STM #x, AR4 ;AR4指向存放变量x的首地址
RPT #3 ;
MAC *AR3+,*AR4+,A ;完成三次乘法累加运算
STL A,@y ;将结果存入预留的数据存储器中
RET ;返回主程序
.end ;结束汇编命令
则生成的example.hex文件的内容如表2所示。
如果将example.hex的内容烧写至16位EPROM中,则其数据存储器内部组织结构如表3所示。
由表3 的EPROM数据组织结构可看出,在0FFFFh地址处存放的是自举表首地址8000h。从8000h处开始是16位自举表的内容。自举表的第一个字是16位自举标记10AA,第二、三个字分别为寄存器SWWSR及BSCR的内容。从第四个字开始分别是程序入口地址、各代码段长度、存放各代码段的目标地址及各段代码(本例含有程序段及数据段),最后为块结束标志0000h。这样, 一个正确的自举表就建立起来了。
’C5402 DSP芯片为用户提供了丰富灵活的自举引导方式,用户可根据各自的需求选择不同的引导方式,其中并行自举是最常用的引导方式之一。正确建立自举表是充分利用自举引导功能的前提及关键。