DSP

DM642的中断学习

2019-07-13 15:01发布

在非DSP/BIOS中使用CSL API进行设置如下(参考内容2中提到,在DSP/BIOS设置更简洁):
1. 编写中断服务例程 在.c源文件中编写ISR函数c_intXX,用于中断处理,如: interrupt void c_intXX (void) {            …; } 注:对于硬件中断而言,XX = 00~15。 2.初始化中断向量表,并在内存段中的中断向量表中配置好对应的中断向量            首先是把中断向量表定位到某一内存段中,我们可以在cmd文件中配置中断向量表的内存映射,如: MEMORY {            VECTORS:         org = 00000000h,       len = 00000400h            L2SRAM:            org = 00000400h,       len = 00100000h            SDRAM:             org = 80000000h,       len = 10000000h } SECTIONS {            .vecs                  :>            VECTORS            .data                  :>            L2SRAM            .text                   :>            L2SRAM            .switch               :>            L2SRAM            .stack                 :>            L2SRAM            .bss                    :>            L2SRAM            .cinit                   :>            L2SRAM            .far                     :>            L2SRAM            .cio                     :>            L2SRAM            .const                 :>            L2SRAM            .sysmem             :>            SDRAM            .tables                :>            L2SRAM }                    然后建立一个.asm文件,用以配置中断向量表中的中断向量,我们需要声明一些全局变量,以便其他源文件可以引用这些变量或者引用其他源文件的变量,如:    .global _vectors            .global _c_int00            .global _vector1         .global _vector2        .global _vector3        .global _vector4        .global _vector5        .global _vector6        .global _vector7        .global _c_int08      ; 对应main()函数的c_int08中断服务例程(假设处理的是EDMA中断)        .global _vector9                .global _vector10        .global _vector11          .global _vector12         .global _vector13          .global _vector14          .global _vector15                          因为引用了rts的_c_int00中断,即RESET中断,因此需要引入这个符号:    .ref      _c_int00        为了把中断服务例程的地址,即中断向量插入到中断向量表中,可以定义一个宏: VEC_ENTRY .macro addr         STW       B0,*--B15         MVKL      addr,B0         MVKH      addr,B0         B         B0         LDW       *B15++,B0         NOP       2         NOP           NOP   .endm                           为了初始化中断向量表中的中断向量,可以定义一个虚拟的中断向量: _vec_dummy:       B        B3       NOP      5                  接下来就可以配置中断向量表了: .sect “.vecs” .align 1024 _vectors: _vector0:       VEC_ENTRY _c_int00          ;RESET中断 _vector1:       VEC_ENTRY _vec_dummy ;NMI不可屏蔽中断 _vector2:       VEC_ENTRY _vec_dummy ;保留中断1 _vector3:       VEC_ENTRY _vec_dummy ;保留中断2 _vector4:       VEC_ENTRY _vec_dummy ;外部中断INT4 _vector5:       VEC_ENTRY _vec_dummy ;外部中断INT5 _vector6:       VEC_ENTRY _vec_dummy ;外部中断INT6 _vector7:       VEC_ENTRY _vec_dummy ;外部中断INT7 _vector8:       VEC_ENTRY _c_int08 ; EDMA控制器中断EDMAINT,对应于c_int08 ISR _vector9:       VEC_ENTRY _vec_dummy;JTAGRTDX中断 _vector10:      VEC_ENTRY _vec_dummy;EMIF_SDRAM_Timer中断 _vector11:      VEC_ENTRY _vec_dummy;McBSP_0_Receive中断 _vector12:      VEC_ENTRY _vec_dummy;McBSP_1_Transmit中断 _vector13:      VEC_ENTRY _vec_dummy;Host_Port_Host_to_DSP中断 _vector14:      VEC_ENTRY _vec_dummy;Timer0中断 _vector15:      VEC_ENTRY _vec_dummy;Timer1中断 3. 在C程序中指定定义的中断向量表,并且启用CPU中断功能 在C程序中,用CSL的IRQ模块来设置中断比较方便,在设置之前,需要外部链接上面的asm程序的中断向量表符号: extern far void vectors();//之所以为vectors,因为C编译器编译后自动改名其为_vectors 引用了中断向量表之后,就可以设置中断了:         IRQ_setVecs(vectors); //指向asm中定义的中断向量表         IRQ_nmiEnable();         IRQ_globalEnable();         IRQ_map(IRQ_EVT_EDMAINT, 8);        //把具体事件和中断号关联起来         IRQ_reset(IRQ_EVT_EDMAINT); 4.启动中断源,如EDMA控制器的中断 至此,中断服务例程c_int8就可以为EDMAINT中断服务了,其它硬件中断向量的配置同理。 5 .实际上述流程定义描述DM642中断的向量表文件,是使用TI公司提供的一个中断向量表文件模板:ves_dm642.asm。 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 中断函数_vectors的一般写法如下: _vectors: _vector0: VEC_ENTRY _c_int00 _vector1: VEC_ENTRY _vec_dummy _vector2: VEC_ENTRY _vec_dummy _vector3: VEC_ENTRY _vec_dummy ...... _vector15: VEC_ENTRY _vec_dummy 其中:_vec_dummy为空函数,VEC_ENTRY 为宏定义 VEC_ENTRY .macro addr stw b0, *--b15 mvkl addr, b0 mvkh addr, b0 b b0 ldw *b15++, b0 nop 2 nop nop .endm //////////////////////////////////////////////////////////////////////////// 我的疑惑是,VEC_ENTRY宏中,用到了两个寄存器,B15和B0,这两个寄存器有什么特殊用途? VEC_ENTRY .macro addr STW B0,*--B15 ;把B0内容保存到*B15,然后指针变量后移,相当于压栈 MVKL addr,B0 MVKH addr,B0 ;传入参数的地址给B0 B B0 ;程序跳转到B0指向的地址 LDW *B15++,B0 ;把之前保存的B0恢复;相当于pop NOP 2 NOP NOP .endm 从解释来看,感觉就只是完成一个简单的程序跳转功能,用别的寄存器应该也能实现,非要说有什么特殊用途的话,目前能想到也是在C64X平台下,只有A0、A1。A2、B0、B1、B2可以作为条件寄存器,但这个代码里并不存在条件执行。  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 中断服务程序--------->中断向量表存储初始化(存储地址说明)----------->中断向量表全局变量说明--------->引用变量说明------------>工具宏编写---------->中断向量表编写(用到以上的准备)--------------------->c语言中定位中断向量表----------------->中断复用寄存器设置(中断号和中断事件相对应)