原创 TMS320VC5410 DSP的DSP-BIOS扩展寻址的实现(转帖)

2008-5-9 07:38 4262 7 7 分类: 处理器与DSP
摘  要:通常C5410程序空间被限制在64K地址空间内,当应用程序超出64K时,则需增加目标系统存储区和附加逻辑,实现对系统的扩展。本文介绍如何配置及使用DSP/BIOS实现扩展寻址功能,并分析了API调用和中断触发过程,最后以DSP并行自举引导方式实现程序的脱离仿真运行。

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

字串6


     一 DSP/BIOS 接口 字串3


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

字串3


11EG1ac4J0103060.jpg字串2


    二 扩展程序空间

字串7


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

字串4



    用户可以在映射区上定义多个物理存储区,它们覆盖整个映射区,但彼此空间不重叠。当使用存储区的扩展页时,内部16位地址空间被扩展为32位的地址来寻址,高16位代表扩展页的数目,低16位代表局部的16位地址。如使用扩展程序映射存储器(XPC)来存放扩展页码,XPC存放在数据空间地址为0x1E的位置,它的值要与.CMD链接文件中定义的扩展页码保持一致。如图二所示的一个扩展3页的程序区结构图。公共区的范围是0x0000-0x7FFF;映射区的范围0x8000-0xFFFF,映射区为第一页,XPC要为0才能访问该区;映射地址空间存放两个扩展页,扩展程序映射寄存器限定了映射地址,使得每个扩展页的每个单元具有唯一的地址。当访问扩展页时,映射区将被覆盖。
C5410的DSP/BIOS不仅支持64K程序页内的“近”访问模式,而且支持扩展程序的“远”访问模式,只需设置DSP/BIOS的属性即可实现扩展程序的“远”访问。要注意的是汇编语言写的API只能在PAGE0页调用,而C语言写的API可以在任何页面调用。

11EG1b3PU011FW.jpg

字串2



    三 中断 字串5


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

字串7


    四  程序实例 字串5


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


#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);
}

字串3



    五 DSP/BIOS的配置

字串6



    如要把DSP/BIOS的程序映射到扩展程序空间,需要对其配置,步骤如下。 字串9


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

字串5


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

字串5



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


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

字串2


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


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

字串1


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

字串4


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

字串6


-ltestfarcfg.cmd 字串9


SECTIONS

字串6


{ .FarPage1: {} > EPROG1 PAGE 0

字串4



.FarPage2: {} > EPROG2 PAGE 0

字串1


} 字串1


   9.     保存配置文件为testfar.cdb,然后将testfar.cdbtestfar.cmd testfar.c文件加入工程中。 字串8


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

字串4


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

字串1



GEL_XMDef(0,0x1e,1,0x8000,0x7f); 字串6


file://0/:映射程序空间;0x1eXPC的地址;1XPC 在数据空间中; 字串9


file://0x8000/:映射首地址;0x7fXPC的大小,128页; 字串2


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

字串9

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

字串8


1DSP/BIOS API 调用过程,如图三中的实线所示。 字串9


字串2



点击放大
字串7


产生PRD_F_swi,短调用C语言封装器的PRD_F_swi ()XPC=0字串6


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

字串6


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


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


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

字串8



函数链接器又返回到DSP/BIOS调度表。 字串7


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


执行上述⑴和⑵,第⑶步触发SWI_PAGE2,函数链接器远调用SWI_PAGE2,执行函数(Page2Func),XPC=2字串8


SWI_PAGE2执行结束,远返回函数链接器,然后顺序执行上述的第⑹和⑺。

字串6



2、中断触发过程,如图三中的虚线所示。 字串7


PRD_F_swi发生,CPU把当前的16PC指针压入堆栈,在中断向量表中取指令。 字串2


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

字串6



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

字串7


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

字串3



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

字串3



执行上述的①、②后,第③步检测到SWI_PAGE2准备好,第④步触发SWI_PAGE2,第⑤步函数链接器远调用SWI_PAGE2XPC=2,顺序执行下去直到PRD_POST_SWI结束。

字串2



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



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

字串4



整个引导过程为:上电复位后,判断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,开始执程序。完成程序的并行自举过程。
字串4


点击看大图 字串5


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /1 下一条