RT-Thread 之临界段保护

1、什么是临界段

临界段就是一段在执行的时候不能被中断的代码段。在RT-Thread里面这个临界段最常出现的就是对全局变量的操作。

  那么什么情况下临界段会被打断? 一个是系统调度,另一个是外部中断。在RT-Thread里面,系统调度,最终也是产生PendSV中断,在PendSV Handler里面实现线程的切换。所以还是可以归结为中断。既然这样,RT-Thread对临界段的保护就处理得很干脆了,直接把中断全部关了,NMIFAULT和硬FAULT除外。

2、cortex-M 内核快速关中断指令

为了快速开关中断,cortex-M 内核专门设置了一条CPS指令,有4种用法,具体如下:

CPSID I ;PRIMASK=1 ; 关中断
CPSIE I ;PRIMASK=0 ; 开中断
CPSID F ;FAULTMASK=1; 关异常
CPSIE F ;FAULTMASK=0; 开异常
PRIMASK 和 FAULTMASK 是 Cortex-M 内核里面三个中断屏蔽寄存器中的两个,还有一个是 BASEPRI,有关这三个寄存器的详细用法见下表。

 3、关中断

RT-Thread 关中断的函数在 contex_rvds.s 中定义,在 rthw.h 中声明,具体实现:
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC;         (1)
EXPORT rt_hw_interrupt_disable;      (2)
MRS r0, PRIMASK;                      (3)
CPSID I;                             (4)
BX LR;                               (5)
ENDP;                                 (6)    

(1)关键字PROC表示汇编子程序的开始

(2)使用EXPORT 关键字导出标号 rt_hw_interrupt_disable,使其具有全局属性,在外部头文件声明后(在rthw.h中声明),就可以在C文件中调用。

(3)通过MRS指令将特殊寄存器PRIMASK的值存储到通用寄存器r0中,当在C中调用汇编子程序返回时,会将r0作为函数返回值。所以在C中调用rt_hw_interrupt_disable()时,需要事先声明一个变量用来存储rt_hw_interrupt_disable()的返回值,即r0寄存器的值,也就是PRIMASK的值。

(4)关闭中断,即使用CPS指令将PRIMASK寄存器的值置1,

在这里,我敢肯定,一定会有人有这样一个疑问:关中断,不就是直接使用 CPSID I 指令就行了嘛,为什么还要第三步,即在执行 CPSIDI 指令前,要先把 PRIMASK 的值保存起来?这个疑问接下来在“临界段代码的应用”这个小结揭晓。

(5)子程序返回

(6)ENDP表示汇编子程序结束,与PROC成对使用。

4、开中断

RT-Thread 开中断的函数在 contex_rvds.s 中定义,在 rthw.h 中声明,具体实现见:
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC;         (1)
EXPORT rt_hw_interrupt_enable;       (2)
MSR PRIMASK, r0                      (3)
BX LR;                               (4)
ENDP;                                (5)

 (1)关键字PROC表示汇编子程序开始。

(2)使用EXPORT导出标号rt_hw_interrupt_disable(),使其具有全局属性,在外部头文件中声明后(在rthw.h中声明),就可以在C文件中调用。

(3)通过MRS指令将通用寄存器r0的值存储到特殊寄存器PRIMASK中,当在C中调用汇编子程序返回时,会将第一个形参传入到通用寄存器r0。所以在C中调用rt_hw_interrupt_disable()的时候,需要传入一个形参。该形参是进入临界段之前保存的PRIMASK的值。这个时候又有人会问,开中断,不就是使用 CPSIE I 指令就行了

嘛,为啥跟我等凡人想的不一样?其中奥妙将在接下来“临界段代码的应用”这个小结揭晓。
(4)子程序返回
(5)ENDP汇编子程序结束,与PROC成对使用。
原文地址:https://www.cnblogs.com/tansuoxinweilai/p/14956689.html