1、基于 C 语言设置 TMS320 DSP 中断向量表 65573基于 C 语言设置 TMS320 DSP 中断向量表摘要: 随着 DSP 芯片应用的不断深入,用 C 语言开发 DSP 芯片,不仅可以使 DSP 芯片的开发速度大大提高,也使得程序的修改和移植变得十分方便。C 语言设置 TMS320 系列 DSP 中断向量表是高级语言开发 DSP 的一个具体应用。关键词: C 语言,中断,中断向量表,DSP。Setting TMS320 DSP Interrupt Vectors Table in CAbstract Along with the development of DSP chip,
2、the exploiture of DSP in C not only accelerate the evolution of DSP ,but also make the program easy to modify and transplant. This is a practice application that setting TMS320 DSP interrupt vectors table in C.Key Words C language, Interrupts, Interrupt vector table, DSP.1、 引言DSP(数字信号处理器)自二十世纪 70 年代
3、末 80 年代初诞生以来,得到了突飞猛进的发展,在信号处理、通讯、雷达等方面应用越来越广泛,而且开发手段和开发设备也越来越多样化。其中 C 语言在DSP 开发应用中起着越来越重要的作用,以 C 语言编写的 DSP 应用程序具有可读性、可移植性,易于维护和修改。另外在 DSP 应用系统中,中断是完成数据传递、实时处理等的重要手段,因而用 C 语言完成对 DSP 中断设置是 DSP 开发的重要内容。DSP 中断的设置主要包括中断服务程序的编写,中断向量表的设置,中断寄存器的初始化等内容。本文以 TI 公司 TMS320 系列DSP 为例,说明用 C 语言设置中断向量表的方法。并给出实例进行说明。2
4、、 中断向量表的定位中断服务程序的地址(中断向量)要装载到存储器的合适区域。一般这些向量都定位在 0x0 开始的程序存储器中。但有些处理器要求或者可以在其他的存储区域安装中断向量。对于微处理器模式下的TMS320C25、TMS320C26、TMS320C28、TMS320C30、TMS320C31,中断向量定位于 0x0 开始的地址。对于微计算机/程序引导模式下的TMS320C31 的中断向量定位于 0x809fc1,TMS320C26 的中断向量定位于 0xffa0。TMS320C5X 复位向量定位在 0x0,其他中断向量可以定位于任何 2K 字的程序存储器中,中断向量表的定位是与 PMST
5、 寄存器的 IPTR 位有关,有效的中断向量表的基地址是0x0,0x800,0x1000,0x1800,0x2000,0xf800。TMS320C4X 的复位向量定位在四个地址之一,这四个地址由外部引脚 RESETLOC0 和 RESETLOC1 决定。TMS320C4X 的中断向量可存在于任何 512 字范围的存储器中,中断向量表的地址由中断向量表指针(IVTP)寄存器决定。另外,TMS320C4X 的自陷(trap)中断向量可存放在 512 字范围的存储器中,自陷向量表的地址由自陷向量表指针(TVTP)寄存器决定。有效的中断或者自陷向量表的基地址是0x0,0x200,0x400,0x800
6、,0xa00,0xc00,0xe00,0x1000,0x12000xfffffe00,如表 1 所示。有两种方法可以初始化中断向量表,下面讲解这两种方法:方法一:利用已命名的 ASM 段生成向量表的最直接方法就是用汇编指令.sect 来生成一个表。这个表包含中断向量的地址和跳转指令。表 1处理器 向量表基地址 说明TMS320C2X 0x0 不包括微计算机/程序引导模式下的TMS320C26TMS320C26 0xffa0 微计算机/程序引导模式TMS320C30 0x0 TMS320C31 0x0 微处理器模式TMS320C31 0x809fc1 微计算机/程序引导模式TMS320C4X 复
7、位 0x0,0x7fffffff,0x80000000,0xfffffff 外部引脚 RESETLOC0和 RESETLOC1 决定中断向量 任意 512 字范围 IVTP 寄存器决定自陷向量 任意 512 字范围 TVTP 寄存器决定TMS320C5X 复位 0x0 中断向量 任意 2K 字数据页 PMST 寄存器的 IPTR位决定在微计算机/程序引导模式下 TMS320C2X、TMS320C5X 和 TMS320C31 从中断向量的位置处执行代码,因而要用跳转指令来代替中断向量,如 TMS320C31 用 24 位指令 BR 来实现:INT1: BR _c_int01在微处理器模式下 TM
8、S320C30、TMS320C31 和 TMS320C4X,中断向量是下一条存取指令的地址,因而中断服务程序的地址用汇编指令.word 存储在中断向量处。例如,TMS320C4X 中断 1 可用汇编语言定义如下:INT1: .word _c_int01因为中断服务的标识符在汇编语言模块外部被声明,所以标识符必须用.ref 或.global 来声明。下面的例子是一个汇编语言模块(vecs.asm)定义了一个包含 TMS320C5X 跳转指令的段。.ref _c_int0, _c_int1 ;在外部定义中断向量.sect “vectors” ;声明一个一命名的段RS: b _c_int0 ;转至复
9、位向量 I1: b _c_int1 ;转至中断向量 1? 处理保留和未使用的区域有时中断向量表中包含保留的地址,例如微计算机/程序引导模式下的 TMS320C26 或者 TMS320C4X 和 TMS320C5X 的复位和中断向量不连续的情形。TMS320C31 也会发生这种情形,系统中并不是所有的中断都能被用到。为了处理向量映象中的保留地址,就要使用汇编指令.space。注意对于定点设备.space 保留的是位,对于浮点设备.space 保留的字。例如,微计算机/程序引导模式下 TMS320C26,假设所有中断都是可用的.sect “vectors” ;为复位和中断向量定义已命名的段.spa
10、ce 2*16 ;保留的空间b _c_int1 ;INT0b _c_int2 ;INT1b _c_int3 ;INT2b _c_int4 ;TINTb _c_int5 ;RINT b _c_int6 ;XINTb _c_int7 ;TRAP注意.space 指令为复位向量保留的位置在程序引导方式下不能使用,因为复位会启动程序引导功能。使用.space 时 vectors 段链接到0xfa00,不使用.space 指令该段链接到 0xfa02。但是,如果定时器和自陷中断向量被使用时,可用.space 指令对向量表进行如下的定义:.sect “vectors” ;为复位和中断向量定义已命名的段.s
11、pace 2*4*16 ;保留的和 3 个未使用的向量b _c_int4 ;TINT.space 2*2*16 ;2 个未使用的向量b _c_int7 ;TRAP注意在中断和自陷向量表中未使用的部分可用来存储数据。但为了保证中断处理的正确,一定要确保中断和自陷向量不被破坏。? 链接到存储器映象已命名段产生后,TMS320 链接器就会把向量表链接到存储器的合适位置,共分三步进行:1. 链接汇编语言模块;2. 根据中断向量表的定位定义链接器的 MEMORY 段;3. 在链接器的 SECTIONS 命令中,定位这些已命名的段。下面是 TMS320C5X 的命令文件,将 vectors 定位到 040
12、h。-cvecs.objmain.obj-l rts50.libMENORYPAGE0:VECTORS:origin = 0000h, length = 003fhROM :origin = 0040h, length = 007cfhSECTIONS“vectors” : VECTORS.text : ROM.方法二:安装一个运行时的向量这种方法在开发和调试时很有用的,这种方法是用 C 语句在装载中断服务程序地址时建立一个运行时的向量。该方法适用于微处理器模式下的 TMS320C30 和 TMS320C31,以及 TMS320C4X,因为它们只用地址,而不用跳转指令作为中断向量。其重点就是将
13、中断服务程序的地址放到合适的存储器空间,例如,TMS320C30 地址 0x1 对应于外部中断 0(INT0) ,在该地址安装中断服务程序 c_int01。使用如下语句“*(void (*) () )0x1) = c_int01;这里,0x1 被转换成指向函数的指针,因为它包含函数 c_int01 的地址。NextPage3、 向量表指针TMS320C4X 和 TMS320C5X 都可以不将中断向量表放在 0x0 开始的位置。这两个系列的 DSP 都是由寄存器来确定中断向量的位置。TMS320C4X 的复位向量地址是由处理器的引脚确定的四个地址中的一个。中断能够被正确的处理,首先必须在接收到中
14、断之前对中断向量表进行初始化。下面几个例子是用来说明初始化与中断有关的寄存器的方法。例 1:在 C 中嵌入汇编语句这个例子,利用在 C 语言中嵌入汇编语句来设置 TMS320C4X 的中断向量,其起始地址为 0x0,方法是通过将 IVTP 寄存器的值设置为0x0。asm(“ PUSH R0”);asm(“ LDI 0h, R0”);asm(“ LDPE R0, IVTP”);asm(“ POP R0”);例 2:利用 TMS320C4X 的 PRTS这个例子,利用 TMS320C4X 的并行运行支持库来设置中断向量表,起始地址为 0x02ff800,利用 PRTS 库函数 set_ivtp()
15、设置 IVTP寄存器的值使向量表定位于 RAM0 存储器的开始地址。当使用 PRTS时,不需要用户命名中断向量段,而是在运行时使用 PRTS 函数install_int_vector()将向量定位在预先定义的段.vector 中。这种方法要求向量在运行时安装,以防止程序和数据被修改。另外,首先要把 PRTS 库链接到程序,并在命令文件中预先定义.vector 段,把.vector 段定位在 ROM0 存储器的开始地址。命令文件如下所示:-l prts40.libMEMORYRAM0:org = 0x2ff800 , len = 0x400SECTIONS“.vector”: RAM0主程序中必
16、须包含头文件 intpt40.h。函数 set_ivtp()使用预定义的参量 DEFAULT 才能被调要,这样设置 IVTP 寄存器可使.vector 段按命令文件中定义定位。中断向量可使用函数install_int_vector()来安装,如下所示:#include void c_int99(void)for( ; ; ); void main(void)set_ivtp(DEFAULT);install_int_vector(void *) c_int99,2);例 3:链接时指定 TMS320C4X 或 TMS320C5X 的符号当 TMS320C5X 的编辑器中没有 PRTS 库而不能
17、设置向量表指针时,还有一个方便的方法可以达到同样的目的。那就是使用在链接时指定符号的方法。这种方法的主要思想是利用包含复位和中断向量的汇编语言段(.sect)以及用链接器映射中断向量在内存中的分布。C 程序可以获得这个地址并把它装载到中断向量表指针(TMS320C4X 的 IVTP 寄存器或者 TMS320C5X 的 PMST 寄存器) 。本例为 TMS320C5X 芯片,中断向量定位于汇编语言模块中,标号IVECS 指向中断向量表的基地址,下面说明如何获取中断向量地址。.def IVECS.ref _c_int0, _c_int1, _c_int2.sect “reset”b _c_int0
18、.sect “vectors”IVECS .space 2b _c_int1b _c_int2在链接器中,用链接器指定的标号初始化链接器定义的变量。如下所示:cvecs.obj lrts50.lib_vecTable = IVECS MEMORYPAGE 0: VECTORS: origin = 00000h, length = 0003fhROM: origin = 00040h, length = 007CFhP_RAM: origin = 00800h, length = 023FFh. . .SECTIONS”reset” VECTORS”vectors” P_RAM.text: RO
19、M.cinit: ROM.bss: RAMB0_D.stack: INT_RAM在 C 程序中,将 vecTable 声明为外部的无符号指针:extern unsigned int *vecTable;将它装载到 PMST 寄存器中。unsigned int *pmst = (unsigned int *) 0x07; *pmst |= (unsigned int) vecTable;4、 结束语随着 DSP 芯片性能价格比的不断提高,DSP 芯片会在更多的领域内得到更为广泛的应用。利用高级语言特别是 C 语言开发的 DSP 应用系统将会得到不断推广,从而可以提高 DSP 芯片的开发速度。参考文献1 张雄伟,曹铁勇编著.DSP 芯片的原理与开发应用(第 2 版).北京:电子工业出版社,20012 Setting Up TMS320 DSP Interrupts. Texas Instruments Co. ,1995