《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 设计应用 > TMS320VC5410 DSP的DSP/BIOS扩展寻址的实现
TMS320VC5410 DSP的DSP/BIOS扩展寻址的实现
唐 冰 周 勇 骆云志
摘要: TMS320VC5410的程序空间通常被限制在64K地址空间内,当应用程序超出64K时,则需增加目标系统存储区和附加逻辑,实现对系统的扩展。介绍了如何配置及使用DSP/BIOS接口来实现扩展寻址功能,分析了API函数调用和中断触发过程,并以DSP并行自举引导方式实现程序的脱离仿真运行。
Abstract:
Key words :

    摘  要: TMS320VC5410的程序空间通常被限制在64K地址空间内,当应用程序超出64K时,则需增加目标系统存储区和附加逻辑,实现对系统的扩展。介绍了如何配置及使用DSP/BIOS" title="DSP/BIOS">DSP/BIOS接口来实现扩展寻址功能,分析了API函数调用和中断触发过程,并以DSP并行自举" title="自举">自举引导方式实现程序的脱离仿真运行。 

    关键词: DSP/BIOS  扩展寻址  API  并行自举引导

 

1 DSP/BIOS 接口

    DSP/BIOS接口提供了基本的运行服务,如应用程序实时分析功能、时钟周期函数、I/O模块、优先级的任务调度等。DSP/BIOS接口提供支持汇编语言和C语言的API接口函数,这些API函数绝大部分都是用汇编语言实现的,因此汇编语言可以直接调用API,而C语言调用API则要通过DSP/BIOS的C封装器。应用程序通过调用API函数来使用DSP/BIOS接口,如软件中断、背景线程和中断服务程序" title="中断服务程序">中断服务程序等都可以调用DSP/BIOS的函数。当DSP/BIOS要调用用户的C语言函数时,则要通过函数链接器,如图1所示。 

 

 

2 扩展程序空间

    TMS320VC5410的16位地址空间被划分为两块,低地址块定义为公共区(或未映射区),高地址块定义为映射区(或扩展区)。这两块的地址由目标系统的外部寄存器和存储区决定。值得注意的是,TMS320VC5410的数据区没有扩展存储区。 

    用户可以在映射区上定义多个物理存储区,它们覆盖整个映射区,但彼此间不重叠。当使用存储区的扩展页时,内部16位地址空间被扩展为32位的地址进行寻址,高16位代表扩展页的数目,低16位代表局部的16位地址。如使用扩展程序映射存储器(XPC)存放扩展页码,则XPC存放在数据空间地址为0x1E的位置,它的值要与.CMD链接文件中定义的扩展页码保持一致。图2所示的是一个扩展3页的程序区结构图。公共区的范围是0x0000~0x7FFF;映射区的范围是0x8000~0xFFFF;映射区为第一页,XPC要为0才能访问该区;映射地址空间存放两个扩展页,扩展程序映射寄存器限定了映射地址,使得每个扩展页的每个单元具有唯一的地址。当访问扩展页时,映射区将被覆盖。 

 

 

    TMS320VC5410的DSP/BIOS不仅支持64K程序页内的“近”访问模式,而且支持扩展程序的“远”访问模式,只需设置DSP/BIOS的属性即可实现扩展程序的“远”访问。要注意的是,汇编语言写的API只能在PAGE0页调用,而C语言写的API可以在任何页面调用。 

3 中 断

    当中断产生时,DSP的内部结构机制只能保存低16位页内的局部地址,而扩展寻址时程序地址需要23位,这就意味着调用和返回时将超出64K(16位地址)的范围,因此必须考虑怎样保存和恢复扩展地址。解决的方法是用中断服务程序(ISR)保存XPC的值,确保能正确计算中断向量,为此中断向量表" title="向量表">向量表必须放在公共区或映射区的64K程序页面上。当DSP/BIOS在公共区上时,ISR可以放在任何位置;如果不在公共区上,则ISR必须放在PAGE0上。 

    当OVLY=0时,为了能保证中断正确执行,必须在每一个页面上都要有中断向量表的拷贝。当OVLY=1时,只需在公共页面上(如0x7F80)作一份中断向量表的拷贝就可以了。 

4 程序实例

    下面通过一个简单的例子介绍DSP/BIOS如何实现程序地址的扩展。本例中有三个软中断:时钟中断PRD_POST_SWI,每100ms触发SWI_PAGE1(或SWI_PAGE2)一次;SWI_PAGE1,完成置XF高;SWI_PAGE2,完成置XF低。三个软中断执行的函数分别放在程序空间的不同页面上,即PRD_Post_SWI放在公共页面上(XPC=0),Page1Func和Page2Func分别放在扩展程序页面1和2上(XPC为1和2)。 

    #include “testfarcfg.h” 

    #pragma CODE_SECTION(Page1Func,“.FarPage1”) 

    #pragma CODE_SECTION(Page2Func,“.FarPage2”) 

    int pagenumber; 

    void main(void)         {pagenumber=0;} 

    void Page2Func (void)   {asm(“rsbx xf”);pagenumber=0;} 

    void Page1Func (void)   {asm(“ssbx xf”);pagenumber=1;} 

    void PRD_Post_SWI(void) 

    { if(pagenumber)  SWI_post(&SWI_PAGE2); 

    else   SWI_post(&SWI_PAGE1); 

    } 

5 DSP/BIOS的配置 

    如要把DSP/BIOS的程序映射到扩展程序空间,需要对其进行配置,步骤如下: 

    (1)建立一个新配置文件。启动仿真软件(Code Composer Studio),建立testfar.pjt工程,通过File中的New ——DSP/BIOS Config创建配置文件,选用sd54.cdb(54X EVM)配置。 

    (2)添加软件中断。右键打开软件中断管理器(Software Interrupt Manager),选择Insert SWI,创建SWI_PAGE1,属性配置为:function:_Page1Func;priority:2。用同样的方法创建function为_Page2Func的SWI_PAGE2。右键打开定时器功能管理器(Periodic Function Manager),选择Insert PRD,创建PRD_POST_SWI,属性配置为:period(ticks):50,function:_ PRD_Post_SWI,mode:continuous。 

    (3)设置OVLY位为1。打开System中的Global Settings的属性页,在PMST(6~0)项中填入使第5位为1的值,如MP=1,填入0x60。 

    (4)指定“远”调用模式。在Global Settings属性页面的Function Call Model选项中选择far,使全局变量Callmodel设置为far。 

    (5)在公共区中重新分配中断向量表。双击System中的MEM,右键打开VECT 的属性页,在base项中填入新的基地址,如0x7F80。 

    (6)配置扩展程序地址段。对于54X EVM评估板,已经有了两个扩展程序段EPROG0和EPROG1(如果没有的话,则需添加这两个段,选择Insert MEM,添加两个扩展程序段,重命名为EPROG0和EPROG1)。EPROG0属性为base:0x8000,len:0x4000,勾去create a heap in this memory选项,space:code;EPROG1与EPROG0的属性不同之处为base:0x18000。加入一个新的扩展程序段EPROG2,属性为base:0x28000,len:0x4000,space:code。 

    (7)将目标代码链接到扩展程序段。pragma伪指令告诉编译器的预处理器如何处理函数,语法为#pragma CODE_SECTION(Page1Func,“.FarPage1”),在名为“.FarPage1”的段中分配Page1Func的程序空间。这样,目标代码Page1Func就被链接到.FarPage1段的区域。 

    (8)创建一个新的链接命令文件(testfar.cmd)。其主要功能是把testfarcfg.cmd链接进去,并且告诉链接器把不同目标函数放在不同的扩展页面上。如: 

    -ltestfarcfg.cmd 

    SECTIONS 

    { .FarPage1:{} > EPROG1 PAGE 0 

      .FarPage2:{} > EPROG2 PAGE 0 

    } 

    (9)保存配置文件为testfar.cdb,然后将testfar.cdb,testfar.cmd、testfar.c文件加入工程中。 

    (10)配置编译器和汇编器支持远模式代码。打开菜单Project中的Build Options窗体,选择Compiler属性页,点击Category中的Advanced选项,勾选Use Far Calls (-mf)(C548 and higher)。此选项指定产生远调用代码模式。 

    (11)在调试器内描述并激活扩展寻址功能。仿真器的调试软件需要激活扩展寻址功能才能支持长指令的执行和扩展存储区的读/写,方便地对使用扩展寻址的程序进行调试。所以使用通用扩展函数GEL_XMDef()来定义映射寄存器(如XPC)和映射扩展空间的首地址。如当OVLY=1时,扩展程序区从0x8000开始,7位XPC放置在数据空间的0x1E单元中,并把下面两条语句加入到C5410.gel文件的C5410_Init()函数中。 

    GEL_XMDef(0,0x1e,1,0x8000,0x7f);  

    //0:映射程序空间;0x1e:XPC的地址;1:XPC 在数据空间中; 

    //0x8000:映射首地址;0x7f:XPC的大小,128页; 

    GEL_XMOn(); //使能扩展地址映射 

6 DSP/BIOS函数调用和中断触发过程

6.1 DSP/BIOS函数调用过程

    DSP/BIOS API 调用过程如图3中的实线所示。具体过程如下: 

 

 

    (1)产生PRD_F_swi,短调用C语言封装器的PRD_F_swi (),XPC=0。 

    (2)C语言封装器触发PRD_POST_SWI时钟软中断,然后检测SWI_PAGE1,产生执行DSP/BIOS调度表的分支。 

    (3)DSP/BIOS调度表保存当前PRD_POST_SWI上下文信息,调用函数链接器以触发SWI_PAGE1。 

    (4)函数链接器远调用SWI_PAGE1,执行相应的函数(Page1Func),XPC=1。 

    (5)SWI_PAGE1执行结束,远返回函数链接器。 

    (6)函数链接器又返回到DSP/BIOS调度表。 

    (7)DSP/BIO调度表恢复PRD_POST_SWI信息,返回到C语言封装器。 

    (8)执行上述(1)和(2),第(3)步触发SWI_PAGE2,函数链接器远调用SWI_PAGE2,执行函数(Page2Func),XPC=2。 

    (9)SWI_PAGE2执行结束,远返回函数链接器,然后顺序执行上述的第(6)和(7)。 

6.2 中断触发过程

    中断触发过程如图3中的虚线所示。 

    (1)PRD_F_swi发生,CPU把当前的16位PC指针压入堆栈,在中断向量表中取指令。 

    (2)中断向量程序把当前的XPC压入堆栈,产生一个配置中断服务程序的分支指令,执行中断服务程序,XPC=0。 

    (3)中断服务程序调用HWI_enter,触发PRD_POST_SWI软中断,接着调用HWI_exit,HWI_exit检测到SWI_PAGE1准备好,开始调用DSP/BIOS调度表。 

    (4)DSP/BIOS调度表保存当前的上下文信息,调用函数链接器以触发SWI_PAGE1。 

    (5)函数链接器远调用SWI_PAGE1,执行相应的函数,此时XPC=1。SWI_PAGE1执行完,远返回调用函数链接器,再到DSP/BIOS调度表,调度表恢复上下文信息,把程序指针交给PRD_POST_SWI软中断。PRD_POST_SWI结束。 

    (6)执行上述(1)、(2)步后,第(3)步检测到SWI_PAGE2准备好,第(4)步触发SWI_PAGE2,第(5)步函数链接器远调用SWI_PAGE2,XPC=2,顺序执行下去,直到PRD_POST_SWI结束。 

7 并行自举引导" title="自举引导">自举引导的实现

    TMS320VC5410上电复位后,检查到DSP处于MC(微计算机)工作方式,从片内ROM的0FF80h起执行程序。0FF80h地址存放的是中断向量表,它实为一条分支转移指令(BD 0F800h),使程序跳转至0F800h执行自举引导程序(Bootlooader)。并行自举引导是DSP自举引导常用的一种方式,Bootlooader首先从地址为0FFFFh的I/O口读取自举表首地址的内容,如果此内容不符合8位或16位的引导方式,就从地址为0FFFFh的数据存储器读取,进行8位或16位并行自举引导。若要完成自举引导功能,必须建立正确的自举表。 

    自举表的内容不仅包括欲加载的各段代码,而且包括各段代码的长度、各代码段存放的目标地址、程序入口地址等信息。自举表可由hex500格式转换器自动生成。hex500是一个通用程序,它将公共目标文件格式—COFF文件转换成各种FLASH(或EPROM)的编程格式。因此,在使用hex500工具之前,首先把testfar.pjt进行编译、链接,生成COFF格式的testfar.out文件,然后再通过设置适当的选项生成用户所要求的自举表,如转换文件的格式、外部数据存储器的字宽等选项。把testfar.out转换为testfar.hex文件后,再使用C语言编写一个转换程序,将hex文件转换为DSP烧写FLASH程序能识别的文件格式。根据文件信息就可以完成自举表的内容,如表1所示。最后使用FLASH的擦除、读写等操作指令把表1的内容烧入FLASH中。DSP上电复位,便可完成并行自举引导。 

 

 

    整个引导过程为:上电复位后,判断MP/MC=0处于微计算机工作方式,从片内ROM的0FF80h处执行中断向量表的分支转移指令(BD 0F800h),使程序跳转至0F800h处执行自举引导程序。自举引导程序完成初始化后读取数据空间的0FFFFh地址的内容,找到自举表首地址8000h,从8000h处开始读取内容,首先是16位自举标记(10AA),然后分别是寄存器SWWSR及BSCR的内容、程序入口地址、代码段长度、存放代码段的目标地址等信息,根据这些信息把FLASH中的8008H~A594H的程序搬运到片内RAM中,然后把Page1Func和Page2Func的代码搬运到0x180000和0x28000处,最后跳转至片内RAM的26FDH,即PC为26FDH,XPC为0,开始执程序。这样即完成程序的并行自举过程。 

    使用DSP/BIOS可以很好地实现扩展寻址功能,把程序烧写入FLASH后,复位DSP使其处于MC工作方式,便可使用示波器测试XF引脚,观察程序运行正确与否。 

参考文献

1 张雄伟,陈 亮,徐光辉. DSP集成开发与应用实例.北京: 电子工业出版社,2002.6 

2 Interrupt Handling Using Extended Addressing of the TMS320C54x Family. Application Report SPRA492,1998.11 

3 TMS320VC5410 Bootloader. SPRA609A   Copyright (c). TI,April 2000 

此内容为AET网站原创,未经授权禁止转载。