FreeRTOS操作系统学习——资源管理

资源管理

在实际的项目中,我们总是会遇到一些临界资源的访问,虽然可以用互斥量实现对资源的互斥访问,但是如果要实现安全的独占式单线程地访问临界资源,可以通过屏蔽/使能中断、暂停/恢复调度器等方法实现。

屏蔽中断

屏蔽中断有两套宏:任务中使用、 ISR 中使用:

任务中使用: taskENTER_CRITICA()/taskEXIT_CRITICAL()

ISR 中使用:taskENTER_CRITICAL_FROM_ISR()/taskEXIT_CRITICAL_FROM_ISR()

任务中屏蔽
c 复制代码
/* 在任务中,当前时刻中断是使能的
 * 执行这句代码后,屏蔽中断
*/
taskENTER_CRITICAL();
/* 访问临界资源 */
/* 重新使能中断 */
taskEXIT_CRITICAL();
  • 在 taskENTER_CRITICA()/taskEXIT_CRITICAL()之间,低优先级的中断被屏蔽了,优先级低于、等于
    configMAX_SYSCALL_INTERRUPT_PRIORITY;
  • 高优先级的中断可以产生,优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY。但是,这些中断 ISR里,不允许使用 FreeRTOS 的 API 函数。任务调度依赖于中断、依赖于 API 函数,所以:这两段代码之间,不会有任务调度产生。

这套taskENTER_CRITICA()/taskEXIT_CRITICAL()宏,是可以递归使用的,它的内部会记录嵌套的深度,只有嵌套深度变为0时,调用taskEXIT_CRITICAL()才会重新使能中断。

ISR中屏蔽

c 复制代码
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 函数,所以:这两段代码之间,不会有任务调度产生。

暂停调度器

如果有别的任务来跟你竞争临界资源,你可以把中断关掉:这当然可以禁止别的任务运行,但是这代价太大了。它会影响到中断的处理。如果只是禁止别的任务来跟你竞争,不需要关中断,暂停调度器就可以了:在这期间,中断还是可以发生、处理。

c 复制代码
/* 暂停调度器 */
void vTaskSuspendAll( void );
/* 恢复调度器
* 返回值: pdTRUE 表示在暂定期间有更高优先级的任务就绪了
* 可以不理会这个返回值
*/
BaseType_t xTaskResumeAll( void );

/*********************/
vTaskSuspendScheduler();
/* 访问临界资源 */
xTaskResumeScheduler();

这套vTaskSuspendScheduler()/xTaskResumeScheduler()宏,是可以递归使用的,它的内部会记录嵌套的深度,只有嵌套深度变为0时,调用taskEXIT_CRITICAL()才会重新使能中断。

相关推荐
帅云毅11 分钟前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链
豆豆12 分钟前
day32 学习笔记
图像处理·笔记·opencv·学习·计算机视觉
nenchoumi311933 分钟前
VLA 论文精读(十六)FP3: A 3D Foundation Policy for Robotic Manipulation
论文阅读·人工智能·笔记·学习·vln
学习噢学个屁36 分钟前
基于51单片机的超声波液位测量与控制系统
c语言·单片机·嵌入式硬件·51单片机
凉、介39 分钟前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci
SuperSwaggySUP44 分钟前
4/25 研0学习日志
学习
电鱼智能的电小鱼1 小时前
EFISH-SBC-RK3588无人机地面基准站项目
linux·网络·嵌入式硬件·机器人·无人机·边缘计算
电鱼智能的电小鱼1 小时前
基于 EFISH-SBC-RK3588 的无人机环境感知与数据采集方案
linux·网络·嵌入式硬件·数码相机·无人机·边缘计算
码起来呗1 小时前
基于SpringBoot的高校学习讲座预约系统-项目分享
spring boot·后端·学习
Yurko131 小时前
【C语言】全局变量、静态本地变量
c语言·学习