目录

1、taskENTER_CRITICAL

2、vTaskSuspendAll

3、Mutexes

3.1、Usage


临界区的概念在任何的 SoC 都存在,比如,针对一个寄存器,基本操作为:读->改->写;在不带 OS 的系统下,普通代码希望对某个寄存器进行读->改->写,此刻,一个 IRQ 打断了这个操作,也同时对这个寄存器进行 读->改->写,中断返回,后,普通代码又继续进行,这样就会导致逻辑错误;

在带 OS 的情况下,不光是有 IRQ,而且存在任务切换,这样,同一个资源在 ISR 和不同任务之间修改,这造成了临界区;临界区的资源需要保护起来,临界区保护的不是代码,而是数据;

所以,在设计阶段尽早识别哪些是临界区,以及采取对应的策略,避免后续出现很难查的问题;

FreeRTOS 针对临界区资源,存在几种保护的方式:

1、taskENTER_CRITICAL() 和 taskEXIT_CRITICAL()

2、vTaskSuspendAll() 和 xTaskResumeAll()

3、Mutexes

4、Gatekeeper Tasks

接下来就看看他们的具体概念以及用法;

1、taskENTER_CRITICAL

这是个最强悍的临界区保护调用,它总是和 taskEXIT_CRITICAL 成对出现,即:


  1. taskENTER_CRITICAL();

  2. {

  3. ............. // 临界区

  4. }

  5. taskEXIT_CRITICAL();

  • 1

为何称之为强悍,因为它直接屏蔽了中断,OS 调度靠中断,ISR 也靠中断;

也就是说,在这之间的对数据的操作,是绝对安全!

适用场景是,临界区可能存在于中断和任务中;

使用 taskENTER_CRITICAL 的时候,尽量保证这个临界区很短小,因为它暂停了所有的活动,来满足这段临界区,外部其他的任何响应,都无法阻止他;

它的实现是

注意:

1、在 ISR 中使用 taskENTER_CRITICAL_FROM_ISR() 和 taskEXIT_CRITICAL_FROM_ISR();

2、taskENTER_CRITICAL 和 taskEXIT_CRITICAL 必须成对出现;

taskENTER_CRITICAL 和 taskEXIT_CRITICAL  支持嵌套使用,因为里面维护了一个引用计数;

2、vTaskSuspendAll

上面那种关闭中断的方式,需要尽快退出临界区,以免引起中断延时处理,任务被延时处理;

FreeRTOS 还提供了一种挂起调度器的方式的临界区,它通过调用 vTaskSuspendAll 和 xTaskResumeAll 来建立临界区:


  1. vTaskSuspendAll();

  2. {

  3. ............. // 临界区

  4. }

  5. xTaskResumeAll();

  • 1

这种方式和 taskENTER_CRITICAL 不一样的地方在于,它仅仅是挂起了调度器,而没有去关闭中断;换言之,资源争夺的场景中,它仅仅是防止了任务之间的资源争夺,中断照样可以直接响应;

所以,挂起调度器的方式,适用于,临界区位于任务与任务之间;既不用去延时中断,又可以做到临界区的安全;

3、Mutexes

3.1、Usage

互斥量是二值信号量的特殊形式 (它也是通过 Queue 实现),与二值信号量不同,互斥量用于控制多个任务之间共享资源的访问,也就是互锁;

不同于上面两种,互斥量不但开放了中断,同时也不挂起调度器;

使用互斥量,需要定义 configUSE_MUTEXES 为 1

用于互锁的互斥量可以充当保护资源的令牌。当一个任务希望访问某个资源时,它必须先获取令牌。当任务使用完资源后,必须还回令牌,以便其它任务可以访问同一资源。

互斥量和信号量使用相同的API函数,因此互斥量也允许指定一个阻塞时间。阻塞时间单位为系统节拍周期时间,数目表示获取互斥量无效时最多处于阻塞状态的系统节拍周期个数。

互斥量与二进制信号量最大的不同是:互斥量具有优先级继承机制。也就是说,如果一个互斥量(令牌)正在被一个低优先级任务使用,此时一个高优先级企图获取这个互斥量,高优先级任务会因为得不到互斥量而进入阻塞状态,正在使用互斥量的低优先级任务会临时将自己的优先级提升,提升后的优先级与与进入阻塞状态的高优先级任务相同。这个优先级提升的过程叫做优先级继承。这个机制用于确保高优先级任务进入阻塞状态的时间尽可能短,以及将已经出现的“优先级翻转”影响降低到最小。

在很多场合中,某个硬件资源只有一个,当低优先级任务占用该资源的时候,即便高优先级任务也只能乖乖的等待低优先级任务释放资源。这里高优先级任务无法运行而低优先级任务可以运行的现象称为“优先级翻转”。

为什么优先级继承能够降低优先级翻转的影响呢?举个例子,现在有任务A、任务B和任务C,三个任务的优先级顺序为任务C>任务B>任务A。任务A和任务C都要使用某一个硬件资源,并且当前任务A占有该资源。

先看没有优先级继承的情况:任务C也要使用该资源,但是此时任务A正在使用这个资源,因此任务C进入阻塞,此时三个任务的优先级顺序没有发生变化。在任务C进入阻塞之后,某硬件产生了一次中断,唤醒了一个事件,该事件可以解除任务B的阻塞状态。在中断结束后,因为任务B的优先级是大于任务A的,所以任务B抢占任务A的CPU权限。那么任务C的阻塞时间就至少为:中断处理时间+任务B的运行时间+任务A的运行时间。

再看有优先级继承的情况:任务C也要使用该资源,但是此时任务A正在使用这个资源,因此任务C进入阻塞,此时由于优先级A会继承任务C的优先级,三个任务的优先级顺序发生了变化,新的优先级顺序为:任务C=任务A>任务B。在任务C进入阻塞之后,某硬件产生了一次中断,唤醒了一个事件,该事件可以解除任务B的阻塞状态。在中断结束后,因为任务A的优先级临时被提高,大于任务B的优先级,所以任务A继续获得CPU权限。任务A完成后,处于高优先级的任务C会接管CPU。所以任务C的阻塞时间为:中断处理时间+任务A的运行时间。看,任务C的阻塞时间变小了,这就是优先级继承的优势。

优先级继承不能解决优先级反转,只能将这种情况的影响降低到最小。硬实时系统在一开始设计时就要避免优先级反转发生。

典型的,两个 Task A、Task B 都要访问同一个资源,他们通过互斥量来做互斥,

首先 A 获取到资源,进入临界区,

此刻 B 去获取资源,由于 A 还没用完资源,所有获取不到,进入阻塞;

A 执行完毕后,释放资源;

资源到位,B 解除阻塞,获取资源;

B 执行完毕,释放资源;

3.2、APIs

创建一个互斥量,使用 xSemaphoreCreateMutex

SemaphoreHandle_t xSemaphoreCreateMutex( void );
  • 1

有一个返回值,如果成功创建,返回句柄,否则返回 NULL;

进入/ 退出 互斥量的临界区使用和信号量一样的接口 xSemaphoreTake 和 xSemaphoreGive,

注意:ISR 中使用带 _FromISR 版本的 API

Example:


  1. static void prvNewPrintString( const char *pcString )

  2. {

  3. /* The mutex is created before the scheduler is started, so already exists by the

  4. time this task executes.

  5. Attempt to take the mutex, blocking indefinitely to wait for the mutex if it is

  6. not available straight away. The call to xSemaphoreTake() will only return when

  7. the mutex has been successfully obtained, so there is no need to check the

  8. function return value. If any other delay period was used then the code must

  9. check that xSemaphoreTake() returns pdTRUE before accessing the shared resource

  10. (which in this case is standard out). As noted earlier in this book, indefinite

  11. time outs are not recommended for production code. */

  12. xSemaphoreTake( xMutex, portMAX_DELAY );

  13. {

  14. /* The following line will only execute once the mutex has been successfully

  15. obtained. Standard out can be accessed freely now as only one task can have

  16. the mutex at any one time. */

  17. printf( "%s", pcString );

  18. fflush( stdout );

  19. }

  20. /* The mutex MUST be given back! */

  21. xSemaphoreGive( xMutex );

  22. }

FreeRTOS 资源管理之临界区相关推荐

  1. FreeRTOS临界区

      FreeRTOS临界区是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断. FreeRTOS 在进入临界区代码的时候需要关闭中断,当处理完临界区代 ...

  2. 【FreeRTOS】06 临界段的保护——关中断和关调度

    本节来讲一讲FreeRTOS如何保护临界段,先讲临界段的概念,再讲保护临界段的方法. 1)临界段的概念 简单来讲,临界段是一段执行时不允许被中断(或其他任务)打断的代码:如果被打断,就有可能运行出错. ...

  3. HAL库版FreeRTOS(上)

    目录 FreeRTOS 简介 初识FreeRTOS 什么是FreeRTOS? 为什么选择FreeRTOS? FreeRTOS 的特点 商业许可 磨刀不误砍柴工 查找资料 FreeRTOS 官方文档 C ...

  4. FreeRTOS笔记篇:第七章 -- 资源管理(互斥锁、二进制信号量、死锁)

    测试环境如下 stm32F103C8T6 MDK keil5 stm32cube + FreeRTOS 概述 在多任务处理系统中,如果一个任务开始访问资源,但在脱离运行状态之前没有完成其访问,则有可能 ...

  5. freeRtos学习笔(3)临界区管理

    freeRtos学习笔记 freeRtos临界区管理 freeRtos临界区 代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被中断,在进入临界段之前须 ...

  6. FreeRTOS临界区应用与总结

    https://blog.csdn.net/chipsea_mltsum/article/details/85612939 项目背景: 做一个测量阻抗脉搏波的设备,设备功能其中之一是采集阻抗信号,通过 ...

  7. FreeRTOS 临界区总结

    当一名嵌入式开发人员从裸机开发切换到 基于 FreeRTOS 的开发后就要注意 中断,资源竞争等等问题了. 下面,总结一下 FreeRTOS 临界区的知识及用法: 1. 应用程序使用临界区 1.1 深 ...

  8. 【STM32】FreeRTOS临界区

    00. 目录 文章目录 00. 目录 01. 概述 02. 任务级临界区代码保护 03.中断级临界区代码保护 04. 预留 05. 预留 06. 附录 07. 参考 01. 概述 临界段代码也叫做临界 ...

  9. FreeRTOS记录(四、FreeRTOS任务堆栈溢出问题和临界区)

    本来计划是消息队列.信号量.任务通知.事件集.邮件的文章 但是因为自己调试的时候遇到了一个问题,还是把堆栈溢出问题放到前面来说 ..增加临界区的使用说明 2021/11/7 ..临界区的使用部分增加任 ...

最新文章

  1. 游戏数仓分析(二)SpringBoot项目对数据进行可视化展示
  2. Spring事务隔离级别,事务传播行为
  3. 在C#中利用DirectX实现声音播放
  4. 课题申报书范文_课题申报书(范文5篇)
  5. 保护个人信息需出“重典”
  6. 什么是机器阅读理解?跟自然语言处理有什么关系?
  7. ScrollView常用属性汇总
  8. python精彩编程200例-python趣味编程100例(99个)
  9. 【AAAI 2020】微软亚洲研究院6篇精选论文在家必看!
  10. Nginx的Upstream负载均衡模块
  11. Teigha 4.0 Net 开发记录
  12. 【DJ-ZBS2 DH-70L两档切换漏电继电器】
  13. 免费主机,免费二级域名分发,免费建临时网站,免费扒网
  14. Welcome to MySQL Workbench:MySQL 复制表
  15. Web服务器是什么意思?
  16. CF755F PolandBall and Gifts
  17. 计算机网络典型的通信协议有,常用的通信网络协议有哪几种
  18. 时寒冰 --- 一如即往的支持你
  19. Mac终端关于ld: library not found for -lnetcdff错误的解决办法
  20. [CentOS Python系列] 五.阿里云部署web环境及通过IP地址访问服务器网页

热门文章

  1. 支持移动端裁剪图片插件Jcrop(结合WebUploader上传)
  2. 潭州教育python培训怎样
  3. 详细阐述磁浮列车目标速度曲线优化的研究展望
  4. 一百本英文原著之旅 ( 15 finished )
  5. 邻接表:两个顶点是否相邻
  6. Android 利用图片取色法巧妙制作彩虹调色圆环
  7. dlopen 和 dlsym 动态链接库调用函数
  8. 缓慢的update语句性能分析(r6笔记第61天)
  9. webrtc中的网络反馈与控制
  10. 定时器 setTimeout与setInterval的用法