freertos学习笔记12--个人自用-第18章 资源管理(Resource Management)

一:资源管理

除了互斥量(Mutex)之外,如何通过屏蔽中断 和暂停调度器来实现对临界资源的独占访问。

以下是该章节的核心内容总结:

1. 资源管理的不仅仅是互斥量

虽然之前的章节(如互斥量)介绍了通过"公平竞争"的方式(谁先拿到锁谁用)来保护临界资源,但本章介绍了更"强硬"的方法 :

  • 如果是中断跟任务抢资源:直接屏蔽中断。

  • 如果是其他任务跟当前任务抢资源:直接禁止调度器,阻止任务切换。

二:屏蔽中断(Critical Sections,临界区)

1. 在任务中屏蔽中断 (In Task)

在任务级代码中,我们使用一对宏来定义临界区。

  • 进入临界区 :taskENTER_CRITICAL()

  • 退出临界区 :taskEXIT_CRITICAL()

特性:

  • 这两段代码之间,优先级低于或等于 **configMAX_SYSCALL_INTERRUPT_PRIORITY**的中断会被屏蔽 。
  • 由于没有中断,任务调度也就无法进行,当前任务独占 CPU 。
  • 支持嵌套调用:宏内部有计数器,只有当退出次数等于进入次数时,中断才会真正重新开启

示范代码:

复制代码
/* 假设这里是一个任务函数 */
void vATaskFunction( void *pvParameters )
{
    for( ;; )
    {
        /* ... 其他非临界代码 ... */

        /* 进入临界区:
         * 执行这句代码后,受管辖的中断被屏蔽,任务调度停止 
         */
        taskENTER_CRITICAL(); 

        /* * --- 访问临界资源 ---
         * 这里是独占式访问,不会被中断打断,也不会被切换到其他任务
         * 注意:这里的代码必须尽可能快速地执行!
         */
        AccessSharedData();

        /* 退出临界区:
         * 重新使能中断,恢复任务调度 
         */
        taskEXIT_CRITICAL(); 

        /* ... 其他代码 ... */
    }
}

2. 在中断服务程序中屏蔽中断 (In ISR)

在中断服务程序(ISR)中,必须使用带有 FROM_ISR 后缀的宏。这一点非常重要,因为 ISR 的运行环境与任务不同。

  • 进入临界区 :taskENTER_CRITICAL_FROM_ISR()

  • 退出临界区 :taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus )

关键区别: ISR 版本需要保存进入临界区之前的中断状态。因为进入 ISR 时,某些中断可能已经被硬件或软件关闭了,退出时不能盲目打开所有中断,而是要恢复到之前的状态 。

示范代码:

C

复制代码
void vAnInterruptServiceRoutine( void )
{
    /* 定义一个变量,用来记录当前中断是否使能的状态 */
    UBaseType_t uxSavedInterruptStatus;

    /* * 进入临界区:
     * 1. 屏蔽中断
     * 2. 返回进入前的中断状态,保存在变量中
     */
    uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();

    /* * --- 访问临界资源 --- 
     * 这里的代码不会被更高优先级的中断打断(受 FreeRTOS 管理范围内)
     */
    AccessHardwareRegister();

    /* * 退出临界区:
     * 传入之前保存的状态变量,恢复中断状态 
     */
    taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );

    /* 现在,当前 ISR 可以被更高优先级的中断打断了 */
}

3. 注意事项与限制

虽然屏蔽中断使用起来很简单,但它对系统的实时性影响很大,被称为"粗鲁"的方法 。

执行时间要短 :在 ENTER 和 EXIT 之间的代码必须非常快。如果这里卡住了,系统将无法响应其他硬件中断,也无法切换任务,导致系统"卡死"或响应延迟 。

高优先级中断例外 :优先级高于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断不会 被屏蔽。这意味着这些极高优先级的中断仍然可以发生,但它们绝对不允许调用任何 FreeRTOS 的 API 函数 。

  1. 死锁风险:虽然屏蔽中断本身不会导致普通死锁,但如果临界区内调用了会阻塞的函数(等待队列、延时等),会导致系统彻底崩溃,因为调度器已经被暂停了。
相关推荐
小小de风呀2 小时前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习
李某学编程2 小时前
基于ARM的微机原理学习笔记(一)
arm开发·笔记·学习
Song_RsHt3 小时前
Redis 与微服务,什么场景下无可替代
java·redis·后端·学习·微服务
sbjdhjd3 小时前
AI产业周度动态:从“更强模型”走向“可执行、可治理、可计价”的系统竞争 (2026年10月19日—10月25日)
人工智能·笔记·ai·开源·gemini·信息差·claude code
ss2734 小时前
AI时代首先数据库-PostgreSQL实战笔记 27 PostgreSQL数据写入与读取流程解析
数据库·笔记·postgresql
深圳老胡5 小时前
压力检测空吸功能硬件方案全解析:主流压力传感器品牌与实现路径
笔记·单片机·代码规范
程序猿追5 小时前
返回 null 不一定入队成功:鸿蒙 KMP上的并发优先队列观察笔记
笔记·华为·harmonyos·kmp
~kiss~5 小时前
PRO-LONG: Programmatic Memory Enables Long-Horizon Reasoning 程序式记忆赋能长程推理
学习
程序猿编码5 小时前
不依赖 vLLM/llama.cpp:一套面向学习的 DeepSeek-R1 CUDA 推理实现
c++·学习·语言模型·llama·vllm·大模型推理
崔高杰6 小时前
【多论文阅读笔记】下一阶段,Agent记忆关注什么能力?
论文阅读·笔记