原理概述
SylixOS开发人员在编写中断驱动时经常会遇到多个中断源共用一个中断号的情况,但在驱动中为了保证代码独立性,各个外设的中断服务函数应该放在各自的C文件中编写,用统一的中断服务函数是不合理的。为了适应这种情况,SylixOS支持队列类型中断向量,即SylixOS内核将同一中断向量号的多个中断服务函数链接成队列,执行时依次执行。
技术实现
应用举例
下面以at91sam9x25处理器为例,该处理器的调试串口,tick时钟等外设共用1号中断向量。如图2-1所示。
图2-1 中断向量
中断向量详见AT91SAM9X25芯片手册8.2节Peripheral Identifiers部分。
代码分析
SylixOS开发人员需要将1号中断向量设置成队列类型中断向量,设置方法如程序清单1所示。
程序清单 1 中断初始化
VOID bspIntInit (VOID)
{
interruptInit(); /* 中断控制器初始化 */
API_InterVectorSetFlag(ID_SYS, LW_IRQ_FLAG_QUEUE); /* 设置ID_SYS为单向量、多服务 */
}
bspIntInit函数位于bspLib.c中,用来初始化中断控制器。
ID_SYS是1号中断向量,LW_IRQ_FLAG_QUEUE宏是队列类型中断向量的标志,该标志必须在安装任何一个驱动前设置, 且设置后不能再取消,因此应该在 bspIntInit函数中完成设置。
API_InterVectorSetFlag函数用来设置中断向量属性,代码实现如程序清单2所示。
程序清单 2 中断向量属性设置函数
LW_API
ULONG API_InterVectorSetFlag (ULONG ulVector, ULONG ulFlag)
{
INTREG iregInterLevel;
PLW_CLASS_INTDESC pidesc;
if (_Inter_Vector_Invalid(ulVector)) {
_ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
return (ERROR_KERNEL_VECTOR_NULL);
}
pidesc = LW_IVEC_GET_IDESC(ulVector);
LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel); /* 关闭中断同时锁住 spinlock */
if (LW_IVEC_GET_FLAG(ulVector) &am