DSP

DM6437的中断和事件

2019-07-13 19:10发布

中断的原理具体可以参考:TMS320C64x/C64x+ DSP CPU and Instruction Set Reference Guide第五章内容。 6437有优先级从高到低三种类型的中断:RESET NMI 可屏蔽中断(INT4-INT15) 对于我们一般使用INT4-15比较多,实现的步骤: 1 首先是把中断向量表定位到某一内存段中,我们可以在cmd文件中配置中断向量表的内存映射
MEMORY { VECS: o = 0x10800000 l = 0x00000400 MEMTEST: o = 0x10800400 l = 0x00000200 IRAM: o = 0x10800600 l = 0x0001FA00 DDR2: o = 0x80000000 l = 0x10000000 } SECTIONS { .bss > IRAM .cinit > IRAM .cio > IRAM .const > IRAM .data > IRAM .far > IRAM .stack > IRAM .switch > IRAM .sysmem > IRAM .text > IRAM .vecs > VECS .ddr2 > DDR2 } 2 .vecs.asm
* Copyright (C) 2003 Texas Instruments Incorporated
* All Rights Reserved
*
*
*---------vecs_timer1.asm---------
*
* Assembly file to set up interrupt service table (IST)
* *------------------------------------------------------------------------------
* Global symbols defined here and exported out of this file *然后建立一个.asm文件,用以配置中断向量表中的中断向量,我们需要声明一些全局变量,以便其他源文件可以引用这些变量或者引用其他*源文件的变量,如: *------------------------------------------------------------------------------
.global _vectors
.global _c_int00
.global _vector1
.global _vector2
.global _vector3
.global _vector4
.global _vector5
.global _vector6
.global _vector7
.global _vector8
.global _vector9
.global _vector10
.global _vector11
.global _vector12
.global _vector13
.global _extint14_isr ; Hookup the c_int14 ISR in main()
.global _vector15 *------------------------------------------------------------------------------
* Global symbols referenced in this file but defined somewhere else.
* Remember that your interrupt service routines need to be referenced here. *因为引用了rts_c_int00中断(实际_c_int00在其他文档中定义),即RESET中断,因此需要引入这个符号:
*------------------------------------------------------------------------------
.ref _c_int00
.ref _extint7_isr ; external interrupt INT 7 handler
.ref _extint8_isr ; external interrupt INT 8 handler
.ref _extint14_isr ; external interrupt INT 14 handler
*------------------------------------------------------------------------------
* This is a macro that instantiates one entry in the interrupt service table. *为了把中断服务例程的地址,即中断向量插入到中断向量表中,可以定义一个宏:
*------------------------------------------------------------------------------
VEC_ENTRY .macro addr
STW B0,*--B15 ;把B0内容保存到*B15,然后指针变量后移,相当于压栈
MVKL addr,B0 ;传入参数的地址给B0
MVKH addr,B0
B B0 ;程序跳转到B0指向的地址
LDW *B15++,B0 ;把之前保存的B0恢复;相当于pop
NOP 2
NOP
NOP
.endm
*------------------------------------------------------------------------------
* This is a dummy interrupt service routine used to initialize the IST. *为了初始化中断向量表中的中断向量,可以定义一个虚拟的中断向量:
*------------------------------------------------------------------------------
_vec_dummy:
B B3
NOP 5 *------------------------------------------------------------------------------
* This is the actual interrupt service table (IST). It is properly aligned and
* is located in the subsection .text:vecs. This means if you don't explicitly
* specify this section in your linker command file, it will default and link
* into the .text section. Remember to set the ISTP register to point to this
* table. *配置中断向量表 上面定义的宏起作用了,这里中断向量的名字,比如_c_int00,_extint14_isr相当于函数入口地址 *不同的在于C编译器会自动吧c_int00当做_c_int00来处理,这样地址就插入中断向量表中了。
*------------------------------------------------------------------------------
.sect ".vectors"
;.align 1024 _vectors:
_vector0: VEC_ENTRY _c_int00 ;RESET
_vector1: VEC_ENTRY _vec_dummy ;NMI
_vector2: VEC_ENTRY _vec_dummy ;RSVD
_vector3: VEC_ENTRY _vec_dummy
_vector4: VEC_ENTRY _vec_dummy
_vector5: VEC_ENTRY _vec_dummy
_vector6: VEC_ENTRY _vec_dummy
_vector7: VEC_ENTRY _extint7_isr
_vector8: VEC_ENTRY _extint8_isr
_vector9: VEC_ENTRY _vec_dummy
_vector10: VEC_ENTRY _vec_dummy
_vector11: VEC_ENTRY _vec_dummy
_vector12: VEC_ENTRY _vec_dummy
_vector13: VEC_ENTRY _vec_dummy
_vector14: VEC_ENTRY _extint14_isr ; Hookup the c_int14 ISR in main()
_vector15: VEC_ENTRY _vec_dummy *------------------------------------------------------------------------------ 3.C程序中指定定义的中断向量表,并且启用CPU中断功能 C程序中,用CSLIRQ模块来设置中断比较方便,在设置之前,需要外部链接上面的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 定义中断相关寄存器必不可少,一般放在头文件中,具体的地址可以参考相关的手册,定义寄存器的方法如下,例如: #define PARAMENTRY0 (0x01c04000) //确定基地址
#define OPT *((volatile unsigned int *)(PARAMENTRY0 + 0x00)) //确定寄存器地址 5 关中断 cpu的中断寄存器参考:TMS320C64x/C64x+ DSP CPU and Instruction Set Reference Guide 5.1.3 Summary of Interrupt Control Registers ,具体内容参考:2.7 Control Register File CSR=0x100; /* disable all interrupts */
IER=1; /* disable all interrupts except NMI */
ICR=0xffff; /* clear all pending interrupts */
ISTP = 0x10800400; 6 建立事件与中断的关联 Megamodule Interrupt Controller实际上是6437的一个外设(6437的外设可以参考:TMS320DM643x DMP Peripherals Overview),提供了一个中断分类的功能,让dsp的中断可以支持高达128个事件,它的寄存器具体参见:TMS320C64x+ DSP Megamodule Reference Guide 7.5节 具体的事件可参考:TMS320DM643x DMP Peripherals Overview:7.3 C64x+ Megamodule Events。更详细的关于一些芯片级的事件可以参考各个处理器的数据手册,如dm6437参考:TMS320DM6437 Digital Media Processor 6.8 Interrupts Table 6-21. DM6437 DSP System Event Mapping /*
INTC_EVTCLR0 = 0xFFFFFFFF;
INTC_EVTCLR1 = 0xFFFFFFFF;
INTC_EVTCLR2 = 0xFFFFFFFF;
INTC_EVTCLR3 = 0xFFFFFFFF;
// INTC_EVTFLAG1=0x00000000;
INTC_EVTMASK3 = 0xFFFFFFFF;
INTC_EVTMASK2 = 0xFFFFFFFF;
INTC_EVTMASK1 = 0xFFFFFFFF;
INTC_EVTMASK0 = 0xFFFFFFEF;
INTC_EVTSET1 = 0x00000004;*/
// INTC_INTMUX1 = 0x18000000; //CPUINT7 //24 VPSS-CCDC0
// INTC_INTMUX2 = 0x00000024; //CPUINT8 //34 EDMA3CC_GINT
INTC_INTMUX2 = 0x00000018; //CPUINT8 //24 VPSS-CCDC0
INTC_INTMUX3 = 0x00040000; //CPUINT14 //4 TINTL0 7 开中断 IER |= 0x00000102; //enable 7 8 14
// ISR = 0x00000100;
CSR =0x01 ; /* enable all interrupts*/ 8 初始化完成后,只需在主程序中加入对应的中断服务程序,如 interrupt void extint8_isr(void)
{
.... }