FreeRTOS --(11)资源管理之临界区

2023-05-16

目录

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();

为何称之为强悍,因为它直接屏蔽了中断,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();

这种方式和 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 );
   
   

有一个返回值,如果成功创建,返回句柄,否则返回 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. }

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS --(11)资源管理之临界区 的相关文章

  • 【FreeRtos学习笔记】STM32 CubeMx——Timers(定时器)

    目录 1 软件定时器 2 示例程序 2 1 例程功能 2 2 步骤 2 3 实验结果 2 4 函数讲解 1 软件定时器 定时器是MCU常用的外设 我们在学习各种单片机时必然会学习它的硬件定时器 但是 MCU自带的硬件定时器资源是有限的 而且
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • freertos————互斥锁

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • FreeRTOS学习---“定时器”篇

    总目录 FreeRTOS学习 任务 篇 FreeRTOS学习 消息队列 篇 FreeRTOS学习 信号量 篇 FreeRTOS学习 事件组 篇 FreeRTOS学习 定时器 篇 FreeRTOS提供了一种软件定时器 用来快速实现一些周期性的
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • 有可用的 FreeRTOS 解释语言库吗?

    我在一家公司工作 该公司使用 FreeRTOS 为多个设备创建固件 最近 我们对新功能的要求已经超出了我们固件工程师的工作能力 但我们现在也无力雇用任何新人 即使进行微小的更改 也需要固件人员在非常低的级别上进行修改 我一直在为 FreeR
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站

随机推荐

  • Nuttx 驱动开发手册

    目录 Nuttx 代码获取编译 Nuttx 启动流程 Nuttx BootLoader 开发之源码分析 gpio 驱动分析 I2c驱动分析 PX4 框架分析 UORB 进程间通讯分析 PX4应用层驱动分析并实现例程 串口驱动GPS 驱动分析
  • 解析小觅中通过双目相机生成深度图的代码

    最近在使用双目摄像机生成深度图 xff0c 研读一下自带的代码 xff0c 做一个记录 第一部分 xff1a 第一部分是定义了一个命名空间 xff0c 其中包含许多个类 第一个类 xff1a 1 代码 GrabCallbacks类主要用于抓
  • altium designer PCB各层介绍+添加多层+设置正/负片+设置层的网络标号

    top layer 顶层 xff0c 用来走线 bottom layer 底层 xff0c 用来走线 mechanical 机械层 xff0c 用来定义PCB形状和尺寸 keepout layer 禁止布线层 xff0c 用来绘制禁布区 t
  • java死锁产生的条件

    以下四个条件同时满足时机会产生死锁 产生死锁的条件互斥 xff0c 共享资源 X 和 Y 只能被一个线程占用 xff1b 占有且等待 xff0c 线程 T1 已经取得共享资源 X xff0c 在等待共享资源 Y 的时候 xff0c 不释放共
  • PID--位置型PID和增量式PID比较

    一 位置型PID 位置型 PID 算法适用于不带积分元件的执行器 执行器的动作位置与其输入信号呈一一对应的关系 控制器根据第 n 次计算机采样结果与给定值之间的偏差 e 来计算出第 n 次采用后所输出的控制变量的值 以调节阀来简单说明 xf
  • 你可能不知道的室内无人机秘密都在这里(二 )

    接上篇 xff1a 你可能不知道的室内无人机秘密都在这里 xff08 一 xff09 如果说上一篇是无人机现状的一些科普知识篇 xff0c 那这篇就直接上干货了 xff0c 希望能真正帮助到喜欢无人机行业 想深入研究无人机的小伙伴们 具体我
  • 漫话程序员们的家庭装修——书房篇

    身为一名程序员 xff0c 辛辛苦苦码代码N年 xff0c 终于攒下钱买了自己的小窝 xff0c 不好好犒劳一下自己都对不起自己的近视眼和鼠标手 这就来分享一下我装修的心得 xff0c 从书房开始 xff01 书房作为程序员在公司战斗一天回
  • Windows下使用vscode 调试linux kernel

    安装WSL2 在microsoft store上安装Ubuntu xff0c 当不能安装时可能需要梯子window中访问Ubuntu的目录使用 xff1a wsl Ubuntu中需要修改软件源 xff1a 参考 https mirrors
  • 计算器算法----C语言实现(堆栈法)

    1 字符串去空格处理 实现一 xff1a span class hljs keyword void span spacess span class hljs keyword char span span class hljs keyword
  • 链接脚本

    本文转自 xff1a http www cnblogs com li hao p 4107964 html 一 概论 每一个链接过程都由 链接脚本 linker script 一般以lds作为文件的后缀名 控制 链接脚本 主要用于规定如何把
  • 记录2017/9/7趋势科技笔试题

    1 下面程序一共会在屏幕上输出多少个 xff1f include lt iostream gt include lt stdio h gt include lt sys types h gt include lt unistd h gt u
  • 字节对齐算法

    ps xff1a 遇见这种算法纯属一个巧合 xff0c 刚入职的我 xff0c 在忙着调用各种SDK中的API xff0c 无暇顾及代码的具体实现 xff0c 有些代码还被屏蔽了 xff0c 在写flash的过程中 xff0c 参考了前辈们
  • UCOSIII学习笔记

    目录 1 学习环境 2 滴答定时器 3 任务 3 1 UCOSIII系统任务 3 2 UCOSIII任务状态 3 3 UCOSIII任务调度 3 4 任务相关的API函数 3 5 钩子函数 4 UCOSIII的中断 5 UCOSIII的临界
  • QCC5125----GAIA

    1 描述 GAIA全称 xff1a Generic Application Interface Architecture xff0c 实现了端到端 xff0c 主机无关的生态系统 xff0c 支持主机应用程序访问设备功能 底层的数据包由8个
  • 【SQLserver】使用openrowset方法导入EXCEL表格数据

    一 前言 在之前的一篇博文中记录了用OPENDATASOURCE函数将EXCEL数据写入SQLserver表中的方法 这一方法需要表名sheet1为固定名称不可更改 实际业务中可能会遇到表名随着日期而改动的情况 xff0c 如果excel表
  • PDM

    PDM Pulse Density Modulation 1 Protocols Introduction1 1 PDM Introduction1 2 PCM Introduction1 3 PDM To PCM 2 PDM Struct
  • FreeRTOS --(1)链表

    Based On FreeRTOS Kernel V10 3 1 1 相关文件 链表结构是 OS 内部经常使用到的 xff0c FreeRTOS 自然也不例外 xff0c 在深入分析各个模块的工作原理之前 xff0c 首先来分析 FreeR
  • FreeRTOS --(3)任务管理之创建任务

    目录 1 描述任务的结构 2 任务创建 2 1 xTaskCreate 2 2 prvInitialiseNewTask 2 3 pxPortInitialiseStack 2 4 prvAddNewTaskToReadyList 在 Fr
  • FreeRTOS --(9)信号量之概述

    目录 1 Binary Semaphores 1 1 Usage 1 2 APIs 1 2 1 xSemaphoreCreateBinary 1 2 2 xSemaphoreTake xSemaphoreTakeFromISR 1 2 3
  • FreeRTOS --(11)资源管理之临界区

    目录 1 taskENTER CRITICAL 2 vTaskSuspendAll 3 Mutexes 3 1 Usage 临界区的概念在任何的 SoC 都存在 xff0c 比如 xff0c 针对一个寄存器 xff0c 基本操作为 xff1