临界段就是在执行不能被打断的代码段,最常见的就是对全局变量进行操作,临界段在系统调度和外部中断的时候会被打断。在RT-Thread中,系统调度最终也是产生PendSV中断,在PendSV里面实现线程的切换,所以对于RT-thread临界段的保护变成了把中断都关闭,NMIFAULT和硬FAULT除外。
Cortex-M内核快速关中断指令
Cortex-M内核专门设置了一条CPS指令,有4种用法,具体代码如下:
CPSID I ;PRIMASK=1 ; 关中断
CPSIE I ;PRIMASK=0 ; 开中断
CPSID F ;FAULTMASK=1; 关异常
CPSIE F ;FAULTMASK=0; 开异常
PRIMASK 和 FAULTMAST 是 Cortex-M 内核里面三个中断屏蔽寄存器中的两个,还有一个是 BASEPRI,有关这三个寄存器的详细用法见下表
名字 | 功能描述 |
PRIMASK | 是一个只有单一比特的寄存器,被置1后,就关掉所有可屏蔽的异常,只剩下NMI和硬FAULT |
FAULTMASK | 只有一个位的寄存器,当置1的时候,只有NMI才能响应,其他异常包括硬FAULT也关闭 |
BASEPRI | 寄存器有9位,定义了被屏蔽优先级的阈值。当被设定成某个值后,所有优先级号大于等于此值的中断都被关闭,设置成0,不关闭任何中断 |
关中断
rt_hw_interrupt_disable PROC; /* 关键字PROC表示汇编子程序的开始 */
EXPORT rt_hw_interrupt_disable; /* 使用EXPORT关键字导出标号rt_hw_interrupt_disable,在外部头文件声明后,就可以在C中调用 */
MRS r0, PRIMASK; /* 将特殊寄存器PRIMASK的值存储到通用寄存器r0 */
CPSID I; /* 关中断 */
BX LR; /* 子程序返回 */
ENDP;
开中断
rt_hw_interrupt_enable PROC;
EXPORT rt_hw_interrupt_enbale;
MSR PRIMASK r0
BX LR;
ENDP;