中断系统
一、中断系统简介
-
在该片子上,每个CPU各有14条中断线,其中
INT13
和INT14
直接连接在了TIMER1
和TIMER2
上,其余的12条CPU中断线通过ePIE
连接在外设上。 -
整个中断的路径被分为三个stages
Peripheral
——>PIE
——>CPU
,每个stages都有各自的enable registers
和flag registers
,同时支持中断嵌套以及设置中断优先级。
二、中断链路图(寄存器手册P92)
- 每个
ePIE
block一共有16个中断,而该系统中每个CPU各有12个ePIE
block。(在下文中可以看到相应的映射关系) ePIE
一共支持五个外部中断,通过X-Bar
总线可以映射到任意的GPIO上。
1)Peripheral Stage
每个外设都有自己的中断配置,有些外设,支持多个事件触发容易个中断信号,因此,在下一个中断信号产生之前必须先清除中断标志位。
2)PIE Stage
当CPU收到中断时,它将从该组的ePIE
获得ISR
的地址,而PIE
将会返回组中编号最小的通道向量,编号越小代表着中断优先级越高
3)CPU Stage
CPU为每个CPU级的中断提供一个标志寄存器(IFR)和使能寄存器(IER),他们都是内部CPU寄存器,还有一个global中断屏蔽,可以通过宏定义DINT
、EINT
进行关闭全局中断和打开全局中断。
三、中断传递示例(寄存器手册P93)
当PIEx
、channel y
发生一个中断时,其整个过程如下图所示:
- 该中断被锁存在PIEIFRx.y中。
- 如果PIEIERx.y 被set,则中断传递。
- 如果PIEACK.x 被clear,则中断传递,同时将PIEACK.x set。
- 此时该中断锁存在IFR.x中
- 如果IER.x被set,则中断传递
- 如果INTM被clear,则CPU收到中断
- CPU将当前执行的命令保存到堆栈中
- IFR.x和IER.x被clear,INTM被set,EALLOW被clear
- CPU从PIE取出ISR向量,之后PIEIFRx.y被clear
- CPU跳转到ISR执行。
四、PIE Channel Mapping映射(寄存器手册P96)
五、CPU中断向量表(寄存器手册P97)
六、中断的配置
中断配置步骤:
- 关闭全局中断(DINT)
- 向
PIE
向量表中写入ISR向量地址。 - 将PIECTRL寄存器的ENPIE位置一,来使能PIE block
- 将需要设置的中断对应的PIEIERx.INTy位置一
- 将CPU IER相应位置一来使能对应的PIE组中断。
- 配置使能外设的中断
- 使能全局中断(EINT)
中断函数的处理
- 一定要在中断函数里清除PIEACK对应的位。
Example:
DINT; //第一步:关全局中断
InitPieCtrl(); //初始化PIE控制位
IER = 0x0000; //清除CPU中断使能
IFR = 0x0000; //清除CPU中断标志
InitPieVectTable(); //初始化中断向量表
EALLOW;
PieVectTable.XINT1_INT = &xint1_isr; //第二步:向PIE向量表写入对应的向量地址
PieVectTable.XINT2_INT = &xint2_isr;
EDIS;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //第三步:使能PIE block
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; //第四步:根据PIE map,将对应的PIEIERx.INTy置一
PieCtrlRegs.PIEIER1.bit.INTx5 = 1;
IER |= M_INT1; //第五步:使能CPU级的PIE组中断,PIEIERx对应M_INTx
EINT; //第六步:开启全局中断
Counfigure_XINT1_XINT2(); //第七步:配置外部中断
//第六步和第七步和换一下顺序,不影响。
interrupt void xint1_isr(void)
{
/*
* User Code
*/
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
interrupt void xint2_isr(void)
{
/*
* User Code
*/
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}