临界段的保护
在进入临界段之前,会先把中断关闭,退出临界段时再把中断打开。对于中断的操作,Cortex-M内核专门设置了一条CPS指令,有4种用法:
CPSID I ; PRIMASK=1,关中断
CPSIE I ; PRIMASK=0,开中断
CPSID F ; FAULTMASK=1,关异常
CPSIE F ; FAULTMASK=0,开异常
关中断函数的汇编源码如下所示,该函数会先将PRIMASK寄存器的值保存在r0中,返回给调用者,然后再关闭中断。
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
开中断函数的汇编源码如下所示,该函数会用调用者传进来的值去设置PRIMASK寄存器。
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
这两个函数在使用时如下所示:
/* 临界段代码 */
{
/* 临界段 1 开始 */
level1 = rt_hw_interrupt_disable(); /* 关中断,level1=0,PRIMASK=1 */
{
/* 临界段 2 */
level2 = rt_hw_interrupt_disable(); /* 关中断,level2=1,PRIMASK=1 */
{
}
rt_hw_interrupt_enable(level2); /* 开中断,level2=1,PRIMASK=1 */
}
/* 临界段 1 结束 */
rt_hw_interrupt_enable(level1); /* 开中断,level1=0,PRIMASK=0 */
}
中断函数这样设计可以实现嵌套中断的临界段保护,有效防止中断被提前打开。