1. 临界段代码保护
临界段代码也叫做临界区,是指那些必须 完整运行,不能被打断的代码段。适用于:
外设:要严格按照时序初始化的外设(IIC、SPI)
系统:系统自身需求
用户:用户需求
但是,例如中断、任务调度可以打断当前程序的运行!
1.1 临界段代码保护函数
临界区是直接屏蔽了中断,系统任务调度靠中断,ISR也靠中断。FreeRTOS在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断。
任务级临界区调用格式:
taskENTER_CRITICAL();
{
.... /*临界区*/
}
taskEXIT_CRITICAL();
中断级临界区调用格式:
uint32_t save_status;
save_status = taskENTER_CRITICAL_FROM_ISR();
{
.... /*临界区*/
}
taskEXIT_CRITICAL_FROM_ISR(save_status);
1.2 特点
- 成对使用
- 支持嵌套
- 尽量保持临界段耗时短
2. 任务调度器的挂起和恢复
- 与临界区不一样,挂起任务调度器,未关闭中断;
- 仅仅是防止任务之间的资源争夺,中断照样可以直接响应;
- 挂起调度器的方式,适用于临界区位于任务与任务之间;既不用去延时中断,又可以做到临界区的安全;
使用格式:
vTaskSuspendAll(); /*挂起任务调度器*/
{
... /*内容*/
}
xTaskResumeAll(); /*恢复任务调度器*/
调用一次挂起调度器,变量uxSchedulerSuspended
就加一,该变量会影响Systick触发PendSV中断,即影响任务调度;
调用一次恢复调度器,变量uxSchedulerSuspended
就减一,如果等于0,则允许调度:
- 将所有在
xPendingReadyList
中的任务移到对应的就绪链表中 - 移除等待就绪列表中的列表项,恢复至就绪列表,直到
xPendingReadyList
列表为空