当前位置: 首页 > news >正文

2025最新超详细FreeRTOS入门教程:第十三章 FreeRTOS临界区与原子操作

2025最新超详细FreeRTOS入门教程:第十三章 FreeRTOS临界区与原子操作

摘要

在多任务系统中,多个任务可能会同时访问同一资源(如全局变量、外设寄存器、缓冲区)。如果没有采取保护措施,可能会发生:

  • 数据竞争(Race Condition)
  • 任务/中断交叉修改数据
  • 死锁

临界区(Critical Section)原子操作(Atomic Operation) 是解决上述问题的基础机制。
在 FreeRTOS 中,它们提供了一种轻量级的数据保护方式,与互斥量、信号量相比,开销更低,效率更高。

2025最新超详细FreeRTOS入门教程

文章目录

  • 2025最新超详细FreeRTOS入门教程:第十三章 FreeRTOS临界区与原子操作
    • 摘要
    • 一、什么是临界区?
    • 二、FreeRTOS 提供的临界区机制
      • 1. 任务级临界区
      • 2. 支持嵌套的临界区
      • 3. 调度器挂起/恢复
    • 三、原子操作
    • 四、临界区 vs 互斥量
    • 五、使用示例
      • 示例1:任务中保护共享变量
      • 示例2:中断与任务共享数据
    • 六、临界区的工作机制
    • 七、调试与优化
    • 八、常见问题与解决方法
    • 九、经验总结
    • 十、总结


一、什么是临界区?

临界区指一段需要 独占访问共享资源 的代码。在多任务系统中,为了保证这段代码不被打断,必须采取措施:

  • 禁止任务切换(避免其他任务抢占 CPU)
  • 禁止中断访问(避免 ISR 修改共享数据)
访问共享变量
访问共享变量
访问共享变量
任务A
临界区
任务B
中断
冲突: 数据错乱

二、FreeRTOS 提供的临界区机制

1. 任务级临界区

taskENTER_CRITICAL();// 临界区代码
taskEXIT_CRITICAL();

特点:

  • 禁止 中断和任务切换
  • 不可嵌套使用(多次调用会造成问题)

2. 支持嵌套的临界区

UBaseType_t uxSavedStatus = taskENTER_CRITICAL_FROM_ISR();
// 临界区代码
taskEXIT_CRITICAL_FROM_ISR(uxSavedStatus);

特点:

  • 可在 ISR 中使用
  • 可多次嵌套,退出时恢复原状态

3. 调度器挂起/恢复

vTaskSuspendAll();
// 临界区代码(调度器暂停)
xTaskResumeAll();

特点:

  • 只禁止任务切换
  • 中断仍然可用
  • taskENTER_CRITICAL 粒度更细

三、原子操作

某些变量(如 8 位或 16 位寄存器)在大多数 MCU 上是原子访问的,但 32 位变量在 8/16 位 MCU 上不是原子操作。

FreeRTOS 提供了原子操作宏:

#define taskENTER_CRITICAL()    portENTER_CRITICAL()
#define taskEXIT_CRITICAL()     portEXIT_CRITICAL()

此外,用户也可以使用 C11 原子库CMSIS 提供的 __LDREX / __STREX 指令


四、临界区 vs 互斥量

特性临界区互斥量
粒度CPU 级别(禁止中断/调度)任务级别(优先级继承)
开销极低较高
可嵌套支持(带 FROM_ISR 版本)不支持
使用场景简单数据保护共享外设、复杂资源

五、使用示例

示例1:任务中保护共享变量

volatile int sharedCounter = 0;void vTaskIncrement(void *pvParameters)
{for(;;){taskENTER_CRITICAL();sharedCounter++;taskEXIT_CRITICAL();vTaskDelay(100);}
}

示例2:中断与任务共享数据

volatile uint32_t ulISRValue = 0;void vTaskHandler(void *pvParameters)
{for(;;){taskENTER_CRITICAL();printf("共享值=%lu\n", ulISRValue);taskEXIT_CRITICAL();vTaskDelay(500);}
}void TIM2_IRQHandler(void)
{BaseType_t xHigherPriorityTaskWoken;uint32_t oldStatus;oldStatus = taskENTER_CRITICAL_FROM_ISR();ulISRValue++;taskEXIT_CRITICAL_FROM_ISR(oldStatus);portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

六、临界区的工作机制

taskENTER_CRITICAL
阻止ISR和任务切换
taskEXIT_CRITICAL
正常调度
临界区
禁止中断
临界区结束

七、调试与优化

  1. 避免长时间占用临界区
    • 临界区代码必须简短
    • 否则会影响系统实时性
  2. 使用嵌套版本
    • 推荐使用 taskENTER_CRITICAL_FROM_ISR
    • 确保中断退出时状态恢复正确
  3. 避免死锁
    • 不要在临界区中使用阻塞 API(如 xQueueReceive()

八、常见问题与解决方法

问题原因解决方法
系统响应变慢临界区占用过长缩短临界区代码
死锁临界区中调用阻塞 API避免阻塞调用
中断丢失过度使用临界区优化设计,缩短屏蔽时间

九、经验总结

📌 开发建议

  1. 临界区适合保护简单的共享数据(如变量 ++)
  2. 对于复杂外设访问,用 互斥量 更合适
  3. 临界区必须尽可能短,避免影响实时性
  4. ISR 中推荐使用 taskENTER_CRITICAL_FROM_ISR

十、总结

通过本章学习,你已经掌握:

  • FreeRTOS 临界区的基本概念
  • taskENTER_CRITICALvTaskSuspendAll 的区别
  • 临界区与互斥量的对比
  • 如何在 ISR 中正确保护共享数据

临界区与原子操作是 FreeRTOS 最底层的数据保护机制,理解它们才能设计出高效、稳定的系统。


🔗 FreeRTOS专栏 👉 下一章:2025最新超详细FreeRTOS入门教程:第十四章 FreeRTOS空闲任务与钩子函数 ——我们将学习 FreeRTOS 的 Idle 任务、空闲任务钩子、Tick Hook、Malloc Failed Hook。



文章转载自:

http://W3HAVJz8.csnch.cn
http://FsSXUlLw.csnch.cn
http://KqgKLjmb.csnch.cn
http://ei1SNRYY.csnch.cn
http://tAaZONyG.csnch.cn
http://4TkBMs4L.csnch.cn
http://SedTaAxR.csnch.cn
http://rFLVkF3B.csnch.cn
http://hN7dVPq3.csnch.cn
http://laoDtIxN.csnch.cn
http://vVocK7Xc.csnch.cn
http://tGloy5RZ.csnch.cn
http://GAp9EC5n.csnch.cn
http://vycs9ic0.csnch.cn
http://M4KwvqTq.csnch.cn
http://TrINCX5i.csnch.cn
http://vuPYUnXE.csnch.cn
http://GIGXUM1z.csnch.cn
http://YB1glsjq.csnch.cn
http://Qrt1YKOj.csnch.cn
http://F1n68BmY.csnch.cn
http://BhpEuzRO.csnch.cn
http://vrK7QotO.csnch.cn
http://aUq1vOQQ.csnch.cn
http://IKfwaByX.csnch.cn
http://MWv8KaGh.csnch.cn
http://Pjy6dT1Y.csnch.cn
http://SWcBqHis.csnch.cn
http://kXJ7eKU3.csnch.cn
http://KFiHly6I.csnch.cn
http://www.dtcms.com/a/379258.html

相关文章:

  • 玩转Docker | 使用Docker部署dufs文件管理工具
  • 计算机组成原理:定点乘法运算
  • PyQt5 主窗口状态栏实时显示当前路径的实现与分析
  • 利用conda打包/复刻生信环境
  • glide介绍
  • vscode 中通义灵码显示登录过期
  • 【VScode】ssh报错
  • STM32 norflash W25Q64移植FatFS
  • 【Git】版本控制-Gitee
  • Qt常见问题
  • 泛函Φ(u)驻点的方程与边界条件 / 求给定泛函驻点满足的方程及边界条件
  • 统一权限管理平台登录不了怎么办?
  • 中级统计师-统计法规-第四章 统计管理体制
  • java反射(详细教程)
  • 【Leetcode】高频SQL基础题--1327.查找拥有有效邮箱的用户
  • Redis(集群)
  • 吾爱小工具!一键屏蔽流氓软件!
  • 告别网络监控“盲区”!OpManager全新升级解锁轻量监控新纪元!
  • 实验室试管架 | 塑料、金属等多种材质与规格 | 支持多种试管尺寸 | Sigma-Aldrich
  • .net 类库生成的DLL源码混淆加密
  • 北京-测试-入职金融公司第四周-加班&未发现bug
  • Story2Board: A Training-Free Approach for Expressive Storyboard Generation论文
  • 纯`css`轻松防止滚动穿透
  • 30天Java速成计划:从零基础到能刷算法题!
  • 【点云分类】简述对pointnet和pointnet++的理解
  • 【202509新版】Hexo + GitHub Pages 免费部署个人博客|保姆级教程
  • PigX整合knife4j
  • 安全审计-Ubuntu防火墙ufw
  • 编译器的相关知识(入门时著)
  • 开始 ComfyUI 的 AI 绘图之旅-Flux.1 ControlNet (十)