3.7 临界段代码保护及调度器挂起和恢复

3.7 临界段代码保护及调度器挂起和恢复

临界段代码保护

什么是临界段?

临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段。

那么什么场合不能被打断?适用的场合:

1.外设:需严格按照时序初始化的外设:IIC、SPI等等 。软件IIC需要几微秒的延时,所以不能被打断。

2.系统:系统自身需求 。

3.用户:系统自身需求 。

问题:那么什么可以打断当前程序的运行?

中断、任务调度器(任务切换,低优先级的被高优先级的抢占)。

问题:如何不被打断?

直接关中断,关中断,一是可以把中断给关闭,二是任务调度器也打断不了。为什么关中断也会导致任务调度器也无法打断正在运行的程序呢?因为中断中有一个pendsv,他就是实现任务切换的一个中断,所以关中断也会导致任务调度器也打断不了现在正在运行的程序。

为什么关闭中断后,任务调度器也打断不了?

PendSV是实现我们任务切换的一个中断,而这个中断我们设置的是最低的优先级,我们关闭中断后,肯定是没有办法响应的(FreeRTOS所管理范围的中断,不在范围内的还是可以打断的)。

临界段代码保护函数

FreeRTOS 在进入临界段代码的时候需要提前关闭中断,为什么要提前关闭中断呢?

因为临界段代码的含义就是“不能被打断的代码”,所以肯定进入前要关闭中断,当处理完临界段代码以后再打开中断。

函数

描述

taskENTER_CRITICAL()

任务级进入临界段,其实就是关中断

taskEXIT_CRITICAL()

任务级退出临界段,其实就是开中断

taskENTER_CRITICAL_FROM_ISR()

中断级进入临界段

taskEXIT_CRITICAL_FROM_ISR()

中断级退出临界段

我们上节课所学的中断管理,也是开关中断,只不过所用的函数是:portDISABLE_INTERRUPTS()和portENABLE_INTERRUPTS(),那么这两个函数和上面的函数有什么不同呢?

其实表格中的函数的本质也是调用这两个中断函数,只不过多了嵌套的功能。为什么会多了嵌套功能呢?我查看了函数内部,其实就是设置了一个变量,每调用一次taskENTER_CRITICAL()函数,这个变量就会++,每调用一次taskEXIT_CRITICAL()函数,这个变量就会--。

任务调度器的挂起和恢复

任务调度器被挂起,就说明任务不能被切换了,但是中断依旧正常响应,就说明此函数不需要关闭中断。

函数

描述

vTaskSuspendAll()

挂起任务调度器

xTaskResumeAll()

恢复任务调度器

1、与临界区不一样的是,挂起任务调度器,未关闭中断;

2、它仅仅是防止了任务之间的资源争夺,中断照样可以直接响应;

3、挂起调度器的方式,算是一种任务与任务之间的“临界区”,只不过这个“临界区”既不用去延时中断,又可以做到临界区的相对安全。什么叫“延时中断”?因为中断特别是FreeRTOS中,不能太长时间,所以当临界区的代码过多,可能会导致执行的时间长,紧急中断如果被屏蔽,可能会导致严重的错误,所以就有了这两个函数。

黄金推荐

网吧是一个ip吗(网吧都是一个ip吗)
英国365网址是多少

网吧是一个ip吗(网吧都是一个ip吗)

✨ 07-05 💎 价值: 5723
花椒直播如何上热门
365bet官网网址

花椒直播如何上热门

✨ 07-12 💎 价值: 7832
泪奔!著名巴西球迷老爷爷离世,俩儿子带大力神杯替他看世界杯