DM642的中断学习

在非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语言中定位中断向量表----------------->中断复用寄存器设置(中断号和中断事件相对应)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值