【FreeRTOS】临界资源管理
资源管理
如何实现互斥操作
像是的信号量、互斥量、队列、事件组,这些都是依靠上面的“谁可能和我抢,我就屏蔽谁”的方法来完成互斥和防干扰操作的。
屏蔽中断有两套宏:任务中使用、ISR 中使用:
任务中使用:taskENTER_CRITICAL()/taskEXIT_CRITICAL()
ISR 中使用:taskENTER_CRITICAL_FROM_ISR()/taskEXIT_CRITICAL_FROM_ISR()
任务中屏蔽中断
/* 在任务中,当前时刻中断是使能的
* 执行这句代码后,屏蔽中断
*/
taskENTER_CRITICAL();/* 访问临界资源 *//* 重新使能中断 */
taskEXIT_CRITICAL();
在 taskENTER_CRITICA()/taskEXIT_CRITICAL()之间:
低优先级的中断被屏蔽了:优先级低于、等于configMAX_SYSCALL_INTERRUPT_PRIORITY
高优先级的中断可以产生:优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY
但是,这些中断 ISR 里,不允许使用 FreeRTOS 的 API 函数
任务调度依赖于中断、依赖于 API 函数,所以:这两段代码之间,不会有任务调度产生
ISR中屏蔽中断
void vAnInterruptServiceRoutine( void )
{/* 用来记录当前中断是否使能 */UBaseType_t uxSavedInterruptStatus;/* 在 ISR 中,当前时刻中断可能是使能的,也可能是禁止的* 所以要记录当前状态, 后面要恢复为原先的状态* 执行这句代码后,屏蔽中断*/uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();/* 访问临界资源 *//* 恢复中断状态 */taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );/* 现在,当前 ISR 可以被更高优先级的中断打断了 */
}
在taskENTER_CRITICA_FROM_ISR()/taskEXIT_CRITICAL_FROM_ISR()之间:
低优先级的中断被屏蔽了:优先级低于、等于configMAX_SYSCALL_INTERRUPT_PRIORITY
高优先级的中断可以产生:优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY
但是,这些中断 ISR 里,不允许使用 FreeRTOS 的 API 函数
任务调度依赖于中断、依赖于 API 函数,所以:这两段代码之间,不会有任务调度产生
暂停调度器
/* 暂停调度器 */
void vTaskSuspendAll( void );/* 恢复调度器
* 返回值: pdTRUE 表示在暂定期间有更高优先级的任务就绪了
* 可以不理会这个返回值
*/
BaseType_t xTaskResumeAll( void );
使用示例
vTaskSuspendScheduler();
/* 访问临界资源 */
xTaskResumeScheduler();
这套vTaskSuspendScheduler()/xTaskResumeScheduler()宏,是可以递归使用的,它的内部会记录嵌套的深度,只有嵌套深度变为0时,调用taskEXIT_CRITICAL()才会重新使能中断。