1.原理概述

中断嵌套是指是指中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续执行。

2.技术实现

2.1应用举例

下面以at91sam9260开发板上的AIC(Advanced Interrupt Controller)为例,说明其在硬件上如何支持中断嵌套和在SylixOS下如何使用。at91sam9260上的AIC有32个中断源,8位中断优先级,有8位深度的硬件堆栈以保存每个中断源的中断号和中断优先级,支持最多8级的中断嵌套。

2.2硬件实现

AIC有32个AIC_SVRx(x=0-31)寄存器,芯片手册提示用户应该将该寄存器用来保存32个中断源的中断服务函数地址,但SylixOS下,AIC_SVRx寄存器的值用来保存每个中断源的中断号。AIC_SVRx寄存器如图 2- 1所示。

SylixOS 中断嵌套机制_中断抢占

2- 1 AIC_SVRx寄存器

AIC有32个AIC_SMRx寄存器,这些寄存器的[0:2]位用来设置每个中断源的中断优先级,AIC支持0-7种中断优先级的配置,0的优先级为最低,7的优先级为最高。要注意的是,0号中断源是FIQ,不支持中断优先级的配置。AIC_SMRx寄存器如图 2- 2所示。

SylixOS 中断嵌套机制_中断抢占_02

2- 2 AIC_SMRx寄存器

AIC有1个AIC_IVR寄存器和1个AIC_EOICR寄存器,AIC_IVR寄存器里存放当前中断的中断源的AIC_SVR寄存器的值。芯片手册说明中断服务函数必须以读取AIC_IVR寄存器的值为开始,以写AIC_EOICR寄存器为结束。在SylixOS下,AIC_SVRx里面存放中断号,所以,读取AIC_IVR可以获得当前中断源的中断号。另外读取AIC_IVR寄存器,AIC会判断是否是中断嵌套,如果是,AIC会自动将当前中断源的中断号和中断优先级保存进硬件堆栈,向AIC_EOICR写入任意值,AIC会自动将保存在硬件堆栈的值恢复,这样AIC在硬件上就支持了中断嵌套。AIC_IVR寄存器和AIC_EOICR寄存器如图 2- 3、图 2- 4所示。

SylixOS 中断嵌套机制_中断抢占_03

2- 3 AIC_IVR寄存器

SylixOS 中断嵌套机制_中断嵌套_04

2- 4 AIC_EOICR寄存器

2.3软件实现

在SylixOS下,有两种方式可以设置中断嵌套,第一种是在SylixOS的bsp工程下的bsplib.c文件下的bspIntInit函数下设置。bspLib.c文件路径如图2-5所示。

SylixOS 中断嵌套机制_中断抢占_05

2- 5中断嵌套设置路径

 

bspIntInit函数用来初始化中断系统,设置方式见程序清单 1所示。

程序清单 1中断系统初始化函数

VOID  bspIntInit (VOID)
{
    interruptInit();                                                    /*  中断控制器初始化            */

    /*
     *  设置1号中断向量为可抢占
     */
    API_InterVectorSetFlag(1, LW_IRQ_FLAG_PREEMPTIVE);
}


API_InterVectorSetFlag函数用来设置中断向量属性,LW_IRQ_FLAG_PREEMPTIVE为是否允许中断抢占的标志,程序清单 1代码设置后,比1号中断向量优先级高的中断源就可以打断该中断,实现中断嵌套。

第二种是在SylixOS的bsp工程下的bsplib.c文件下的bspIntHandle函数下设置,bspLib.c文件路径如图 2- 3所示。

bspIntHandle函数是SylixOS总中断服务函数的入口,设置方式见程序清单 2所示。

程序清单 2中断入口函数

VOID  bspIntHandle (VOID)
{
    REGISTER UINT32   uiVector = interruptVectorGet();                  /*  获得中断向量号              */  

    /*
     *  LW_TRUE表示中断可抢占
     */
    archIntHandle((ULONG)uiVector, LW_TRUE);

    interruptIrqService();                                              /*  调用中断结束处理            */
}


以上两种方式设置后,中断服务函数archIntHandle执行时,SylixOS就会将内核中断开关打开,AIC中断优先级控制器来确定是否产生中断。这样在硬件和软件上就分别支持了中断嵌套。