FreeRTOS学习(临界区的保护)

原文链接(点击原文链接获取更多学习干货): 布尔青年

为什么要对临界区进行保护?

临界区一般是一些全局变量,多个场景需要对它进行更改,如一个全局变量C,A任务和B任务都需要对其进行修改和读取。在A任务执行的时间,对C进行了修改,然后A任务要对其进行读取。在修改后读取前,操作系统这时打断了A任务执行,切换到了B任务,B任务对C进行了修改。然后操作系统切换到A任务,A任务读取到B任务修改后的值 。这是A任务读取到错误的值了。

原子操作

那么对于以上问题,就衍生出一个操作——原子操作。原子操作是要么读写一起完成,要么读写一样都没完成。不可能发生只读不写,只写不读操作。

临界区保护

进入临界区可以理解为在此期间,不会有其他任务打断你的执行过程。这样该任务执行过程的值就不会被其他任务修改。FreeRTOS提供临界区保护的函数
如下

 taskENTER_CRITICAL(); //进入临界区
 taskEXIT_CRITICAL(); //退出临界区

FreeRTOS临界区的一些知识

在FreeRTOS进入临界区是关闭中断进入临界区的。
开关中断
多次进入临界区,只要一次关闭临界区就可以退出临界区

进入临界区A
进入临界区B
退出临界区B
就可以顺便A的临界区也退出了
这就是开关中断进入临界区
但是这样的会造成另一个问题

void funA()
{
	taskENTER_CRITICAL(); //进入临界区A
	funB();
	taskEXIT_CRITICAL();//退出临界区A
}

void funB()
{
	taskENTER_CRITICAL(); //进入临界区B
	taskEXIT_CRITICAL();//退出临界区B
}

本来只是退出B的临界区,结果是把A的临界区也退出了,这样会造成很多意想不到的后果。
因此在taskENTER_CRITICAL()和taskEXIT_CRITICAL()有记录嵌套次数,来来避免
以上情况。

中断函数进入临界区

每一个中断都是有优先级的,FreeRTOS有一个寄存器basepri,对这个寄存器写入某个数字,大于该数字的优先级的中断都会被屏蔽。(数字越小优先级越大)

往这个寄存器写入6,则大于6的中断都会被屏蔽。

有时一个中断很紧急,当它执行的过程中不允许其他中断打断它。但是它的优先级不高,如何在中断中做到不被其他优先级呢?

一个中断优先级为6的中断,当进入中断函数之后,先用一个局部变量先保存当前basepri寄存器的优先级。然后修改basepri寄存器的值为0,这样小于0的中断都被屏蔽了。没有其他中断能打断它。当要退出的时候,把basepri寄存器回复。否则后果严重。

在中断中,只能通常情况下调用中断特有函数

用ISR结尾的函数

欢迎关注技术公众号,获取更多硬件学习干货!
在这里插入图片描述

我们能为你提供什么?
技术辅导:C++、Java、嵌入式软件/硬件
项目辅导:软件/硬件项目、大厂实训项目
就业辅导:就业全流程辅导、技术创业支持
对接企业HR:培养输送优质性人才

THE END
分享
二维码
< <上一篇
下一篇>>
---->