工控机CPU为PPC,板卡外接为口VME总线。CPU通过PCI总线连接到universeII(PCI-VME转接桥),universeII连接到VME总线,如图:
完成中断处理主要在BSP如下文件中,syslib.c universe.c
1、系统启动时开启universe中断,从CPU看来所有的VME端中断经过universe转换,显示为一个PCI中断。
2、其中断寄存器初始化在 syslib.c 的sysHwInit()中将universe.c中定义的sysUniverseInit()加载进来,在sysHwInit2()中通过sysUniverseIntInit()初始化中断。挂接代码如下:
/* Connect Universe interrupt */
if (OK != intConnect (INUM_TO_IVEC (UNIV_INT_VEC), sysUnivVmeIntr, 0))
{
return (ERROR);
}
/* Enable Univers Interrupt in GPP interrupt controller */
intEnable (UNIV_INT_LVL);
其中,UNIV_INT_VEC为PCI管脚中断向量29,BSP定义。
3、无论VME端产生何种中断,CPU同将通过PCI引脚的中断向量29得知universeII产生了中断,进入中断处理函数sysUnivVmeIntr();
4、sysUnivVmeIntr函数在universe.c中定义,通过读取寄存器值UNIV_IN_LONG (UNIVERSE_LINT_STAT, &pendingIntr); 并对pendingIntr进行相应处理后,送入解算VME端中断向量和等级的函数sysUnivLevelDecode(),以确定到底是VME端来的中断中,来的是哪个,并且哪个是最高优先级,并返回vec_num,univIntLvl。
5、sysUnivLevelDecode函数的主要作用是通过pendingIntr量,将中断与VME中断信息表中的中断源对应起来,表如下,在universe.c中定义:
static INT_LEVEL_MAP univIntTable[UNIV_NUM_INT + 1] =
{
/* Int Bit Mask Int VectorInt Level Mask */
/* ------------------------ ------------------------ -------------- */
{0, 0, 0x00FFF7FF},
{UNIVERSE_VOWN_INT, UNIV_VOWN_INT_VEC, 0x00FFF7FE},
{UNIVERSE_LM1_INT, UNIV_LM1_INT_VEC, 0x00DFF7FE},
{UNIVERSE_LM2_INT, UNIV_LM2_INT_VEC, 0x009FF7FE},
{UNIVERSE_LM3_INT, UNIV_LM3_INT_VEC, 0x001FF7FE},
{UNIVERSE_MBOX0_INT, UNIV_MBOX0_INT_VEC, 0x001EF7FE},
{UNIVERSE_MBOX1_INT, UNIV_MBOX1_INT_VEC, 0x001CF7FE},
{UNIVERSE_MBOX2_INT, UNIV_MBOX2_INT_VEC, 0x0018F7FE},
{UNIVERSE_MBOX3_INT, UNIV_MBOX3_INT_VEC, 0x0010F7FE},
{VMEBUS_LVL1, -1, 0x0010F7FC},
{VMEBUS_LVL2, -1, 0x0010F7F8},
{VMEBUS_LVL3, -1, 0x0010F7F0},
{VMEBUS_LVL4, -1, 0x0010F7E0},
{VMEBUS_LVL5, -1, 0x0010F7C0},
{VMEBUS_LVL6, -1, 0x0010F780},
{VMEBUS_LVL7, -1, 0x0010F700},
{UNIVERSE_DMA_INT, UNIV_DMA_INT_VEC, 0x0010F600},
{UNIVERSE_LM0_INT, UNIV_LM0_INT_VEC, 0x0000F600},
{UNIVERSE_VME_SW_IACK_INT, UNIV_VME_SW_IACK_INT_VEC, 0x0000E600},
{UNIVERSE_PCI_SW_INT, UNIV_PCI_SW_INT_VEC, 0x0000C600},
{UNIVERSE_LERR_INT, UNIV_LERR_INT_VEC, 0x0000C400},
{UNIVERSE_VERR_INT, UNIV_VERR_INT_VEC, 0x0000C000},
{UNIVERSE_SYSFAIL_INT, UNIV_SYSFAIL_INT_VEC, 0x00008000},
{UNIVERSE_ACFAIL_INT, UNIV_ACFAIL_INT_VEC, 0x00000000}
};
其中,VMEBUS_LVL1-7的中断向量号将经过判断读寄存器后UNIV_IN_LONG (UNIVERSE_V1_STATID, &vector);,放入 vector中,其他的直接查表返回。
6、随后sysUnivVmeIntr函数中将进入VME中断向量表查找对应刚才得到中断向量号的中断服务程序,此服务程序需要在之前应用程序中通过sysVmeIntConnect函数,挂接到此中断向量表中。以供来中断时,查询对应中断调用。