===================   FreeRTOS 中实现临界区的两种途径  ==========================

具体使用时,如果有可能被中断打断,则关闭中断,如果有可能被高优先级的任务打断,则可以关闭任务调度。

1. 关闭中断:
最简单的保护临界段的方法,就是关闭中断,以及关闭任务调度。也就是暂时禁止中断和其他任务执行,等到临界段执行完毕后再恢复。 

注意!这种“关闭”是临时的,执行完临界段之后,必须要恢复允许中断和任务调度的状态。否则,中断和其他任务就无法运行了。

此外,由于执行临界段时,关闭了任务或任务调度,系统无法响应其他的实时事件,会降低系统的实时性;所以我们编写代码时,需要准确识别临界段,使得临界段尽量短,即只把需要保护的最小的一段代码保护起来即可。

在任务中,taskENTER_CRITICAL(),用于进入临界段前保护;taskEXIT_CRITICAL(),用于临界段执行完之后,退出保护。

另外,如果想要在中断服务程序中进入临界段,要使用另一套函数来保护临界段:taskENTER_CRITICAL_FROM_ISR(),用于进入临界段前保护;taskEXIT_CRITICAL_FROM_ISR( x )用于临界段执行完之后,退出保护。

一旦关闭中断,则freeRTOS的任务切换功能也被禁止了,所以,它同时能够保护中断和任务间的临界段冲突。

2. 关闭任务调度:
上述的freeRTOS定义的临界区保护的操作,是直接关闭中断;而实际上,有时有的临界段中断里不访问,只用保护不被其他任务打断即可;这时也可以临时关闭任务调度功能,来实现临界段的保护。

freeRTOS系统中定义了关闭任务调度和开启任务调度的函数:

vTaskSuspendAll()、xTaskResumeAll()

这两个函数也需要成对使用,关闭任务调度后,然后执行临界段,最后一定要恢复到开启调度的状态。

Note:关闭调度后,不能再使用任何会引起任务切换的函数,如之前讲到的延时vTaskDelayUntil、vTaskDelay,以及以后会讲到的信号量、消息队列等函数;直到重新开启任务调度。