FreeRTOS同步互斥与通信

本章简介:

本章是概述性的内容。可以把多任务系统当做一个团队,里面的每一个任务就相当于团队里的一个人。团队成员之间要协调工作进度(同步)、争用会议室(互斥)、沟通(通信)。多任务系统中所涉及的概念,都可以在现实生活中找到例子。 各类RTOS都会涉及这些概念:任务通(tasknotification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)等。 我们先站在更高角度来讲解这些概念。

同步与互斥的概念

我这里用韦东山老师举的例子

一句话理解同步与互斥:我等你用完厕所,我再用厕所。
什么叫同步?就是:哎哎哎,我正在用厕所,你等会。
什么叫互斥?就是:哎哎哎,我正在用厕所,你不能进来。
同步与互斥经常放在一起讲,是因为它们之的关系很大, 互斥 操作可以使用 同步 来实现。我“ 你用完厕所,我再用厕所。这不就是用 同步 来实现 互斥 吗?再举一个例子。在团队活动里,同事A 先写完报表,经理 B 才能拿去向领导汇报。经理 B必须等同事A 完成报表, AB 之间有依赖, B 必须放慢脚步,被称为同步。在团队活动中,同事A 已经使用会议室了,经理 B 也想使用,即使经理 B 是领导,他也得等着,这就叫互斥。经理B 跟同事 A 说:你用完会议室就提醒我。这就是使用 " 同步 " 来实现 " 互斥 "
有时候看代码更容易理解,伪代码如下:

假设有 A B 两人早起抢厕所, A 先行一步占用了; B 慢了一步,于是就眯一会;当 A 用完后叫醒B B 也就愉快地上厕所了。在这个过程中,A B 是互斥地访问 厕所 厕所 被称之为临界资源。 我们使用了“休眠-唤醒”的同步机制实现了“临界资源”的“互斥访问”。这里埋下伏笔,之后看源码就会恍然大悟, 同一时间只能有一个人使用的资源,被称为临界资源。比如任务A B 都要使用串口来打印,串口就是临界资源。如果A B 同时使用串口,那么打印出来的信息就是 A B 混杂,无法分辨。所以使用串口时,应该是这样:A 用完, B 再用; B 用完, A 再用。

裸机的同步与互斥

在裸机程序里,可以使用一个全局变量或静态变量实现互斥操作,比如要互斥地使用
LCD,可以使用如下代码:
        但是在 RTOS 里,使用上述代码实现互斥操作时,大概率是没问题的,但是无法确保万无一失。 假设如下场景:有两个任务 A、B 都想调用 LCD_PrintString,任务 A 执行到第 4 行代码时发现 bCanUse 为 1,可以进入 if 语句块,它还没执行第 6 句指令就被切换出去了;然后任务 B 也调用 LCD_PrintString,任务 B 执行到第 4 行代码时也发现 bCanUse 为 1,也可以进入 if 语句块使用 LCD。 在这种情况下,使用静态变量并不能实现互斥操作。
        上述例子中,是因为第 4、第 6 两条指令被打断了,那么如下改进:在函数入口处先让bCanUse 减一。这能否实现万无一失的互斥操作呢?

 

 把第 4 行的代码使用汇编指令表示如下:

假设如下场景:有两个任务 A、B 都想调用 LCD_PrintString,任务 A 执行到第 04.1 行代码时读到的 bCanUse 为 1,存入寄存器 R0 就被切换出去了;然后任务B也调用LCD_PrintString,任务 B 执行到第 4 行时发现 bCanUse 为 1 并把它减为 0,执行到第 5 行代码时发现条件成立可以进入 if 语句块使用 LCD,然后任务 B 也被切换出去了;现在任务A 继续运行第 04.2 行代码时 R0 为 1,运行到第 04.3 行代码时把 bCanUse 设置为 0,后续也能成功进入 if 的语句块。在这种情况下,任务 A、B 都能使用 LCD。
上述方法不能保证万无一失的原因在于:在判断过程中,被打断了。如果能保证这个过程不被打断,就可以了: 通过关闭中断来实现,RTOS的核心操作。 
       
示例 1 的代码改进如下:在第 5~7 行前关闭中断。

 示例 2 的代码改进如下:在第 5 行前关闭中断。

各类方法的对比 

高能:

        能实现同步、互斥的内核方法有:任务通知(task notification)、队列(queue)、事件组 (event group)、信号量(semaphoe)、互斥量(mutex)。理解这几个,你就能用FreeRTOS来做出你第一个项目了。
         它们都有类似的操作方法: 获取/释放、阻塞/唤醒 、超时。比如:
-- 任务 A 获取资源,用完后任务 A 释放资源
--  任务 A 获取不到资源则阻塞,任务 B 释放资源并把任务 A 唤醒
--  任务 A 获取不到资源则阻塞,并定个闹钟; A 要么超时返回,要么在这段时间内因为任务B释 放资源而被唤醒。
        这些内核对象五花八门,记不住怎么办?我也记不住,通过对比的方法来区分它们。
--  能否传信息?还是只能传递状态? 事件组
--  为众生(所有任务都可以使用)?只为你(只能指定任务使用)? 队列,事件组,信息量/任务通知,互斥量。
--  我生产,你们消费? 队列
--  我上锁,只能由我开锁, 互斥量

 

使用图形对比如下:
队列:
        -- 里面可以放任意数据,可以放多个数据
        -- 任务、ISR 都可以放入数据;任务、 ISR 都可以从中读出数据
  事件组:
        -- 一个事件用一 bit 表示, 1 表示事件发生了, 0 表示事件没发生
        -- 可以用来表示事件、事件的组合发生了,不能传递数据
        -- 有广播效果:事件或事件的组合发生了,等待它的多个任务都会被唤醒
  信号量:
        -- 核心是 " 计数值 "
        -- 任务、 ISR 释放信号量时让计数值加 1
        -- 任务、 ISR 获得信号量时,让计数值减 1
  任务通知:
        -- 核心是任务的 TCB 里的数值
        -- 会被覆盖
        -- 发通知给谁?必须指定接收任务
        -- 只能由接收任务本身获取该通知
 互斥量:
        -- 数值只有 0 1
        -- 谁获得互斥量,就必须由谁释放同一个互斥量

总结:

经过对本篇的概述,如果你以前学过的话,可以加深你对FreeRTOS的了解,如果你是初学,可以帮你对RTOS有一个大概的掌握,后续我将会对这些一个个展开讲解,并且会从内部机制来对其进行分析,让你不止会用,而且还知道为什么可以这样用。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/669337.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Transformer从0到1的学习【还有2-10,别想太多】

1.高纬度介绍Transformer 1.分为编码Encoders和解码器Decoders:“我爱你”作为编码器Encoders的输入进行编码得到序列码后,作为解码器的输入得到输出即为,“I Love you”。 2.编码器和译码器的具体拆分: 左边的编码器Encoders的…

(函数)判断一句话中最长的单词(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明函数&#xff1b; int aiphabetic(char); int longest(char[]);int main() {//初始化变量值&#xff1b;int i;char line[100] { 0 };//获取用户输入字符…

每天写两道(五)合并两个有序链表、最长回文子串

21.合并两个有序链表 . - 力扣&#xff08;LeetCode&#xff09; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] (1)迭代法…

牛客网刷题 | BC105 菱形图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

VMware Workstation中WinXP联网问题

我一直以为我的虚拟机上的XP没有联网 因为 蒙了半天&#xff0c;发现是因为这个网址打不开&#xff0c;不是没有网 太傻了 不如在cmd命令行中通过ping baidu.com来判断是否联网

Vue插槽与作用域插槽

title: Vue插槽与作用域插槽 date: 2024/6/1 下午9:07:52 updated: 2024/6/1 下午9:07:52 categories: 前端开发 tags:VueSlotScopeSlot组件通信Vue2/3插槽作用域API动态插槽插槽优化 第1章&#xff1a;插槽的概念与原理 插槽的定义 在Vue.js中&#xff0c;插槽&#xff08;…

【多目标跟踪】《FlowMOT: 3D Multi-Object Tracking by Scene Flow Association》论文阅读笔记

0.论文 论文地址链接:https://arxiv.org/pdf/2012.07541v1 通过流的方式跟踪是一个比较新颖的点,所以这里比较关注运动跟踪,是如果做到流的跟踪来预测目标的位置以及ID绑定的。 FlowMOT的框架结构如下所示,本中会主要关注下运动跟踪、数据关联、ID分配、新生/消亡…

cmd窗口输出内容乱码问题

出现这样的问题是因为编码格式和解码格式不一样导致的&#xff0c;cmd窗口的默认解码格式为GBK&#xff0c;如想修改cmd默认编码格式可以按照下面步骤操作&#xff1a;打开cmd窗口输入&#xff1a;chcp 65001 65001指的是utf-8编码如果不清楚编码对应的 页面编码是是多少&#…

基于51单片机和NRF24L01的无线温度监控设计

一、设计功能 由单片机、温度传感器、无线模块NRF24L01以及液晶显示器等构成高精度远 程无线温度监测系统。 温度显示精确到小数点后一位。 按键设定过温值&#xff0c;过温在液晶屏提示。 系统设计 三、器件选择3.1温度信号采集模块 传统的温度检测大多以热敏电阻为传感器&a…

4K高刷显示器 - 蚂蚁电竞ANT27VU

可以毫不夸张地说&#xff0c;每一局游戏最终能够取得胜利&#xff0c;实际上都与一套极为优秀的电竞 PC 有着紧密的关联&#xff0c;因为其能够提供强大的性能支持与流畅的体验。同样的道理&#xff0c;一套优秀的电竞 PC 若想发挥出最佳的效果&#xff0c;那也都离不开一台能…

14.Ollydbg的基本使用

上一个内容&#xff1a;13.优化界面化的游戏辅助 Ollydbg是一个调试工具&#xff0c;它可以一步一步的运行一个程序并且还能很直观的看到被调试程序的寄存器状态、栈状态。Ollydbg需要以管理员方式运行&#xff01; 下图附加程序是调试一个正在运行的进程&#xff1a; 点击了…

适合学生写作业的台灯有哪些?台灯怎么选详细攻略!

在数字化飞速发展的今天&#xff0c;孩子们的学习和生活越来越离不开电子屏幕。然而&#xff0c;长时间盯着屏幕&#xff0c;不仅容易让眼睛感到疲劳&#xff0c;更是近视问题日益严重的元凶之一。每一位家长都希望孩子能拥有健康的视力&#xff0c;因此会为孩子挑选一台护眼灯…

【UML用户指南】-04-从代码到UML的关键抽象

1、关键抽象 声明了一个名为paint的操作&#xff0c;它的实现调用名为drawString的另一个操作&#xff0c;drawString操作负责在指定的位置上打印“Hello,World!”。在通常的面向对象的方式下&#xff0c;drawString是一个名称为g的参数上的一个操作&#xff0c;g的类型是类Gr…

写字静不下心?不如试试这些“笨方法”

夏天悄悄热起来啦&#xff5e;有人说&#xff0c;想踏踏实实写一会儿&#xff0c;但又静不下心&#xff0c;耐不住性子&#xff0c;快收下这四个小锦囊&#xff0c;与古人一起笨拙精进吧&#xff01;    1、不论输赢      每次课前&#xff0c;暄桐林曦老师总会强调&am…

VS(visual studio)搭建QT开发环境插件安装

优先安装QT Qt6 官网QtCreator 下载与安装方法win10_qt6下载-CSDN博客 如果安装vs2019,打开installer,安装c环境 选择c 下载vsix后&#xff0c;双击安装即可。 插件下载&#xff1a; Index of /qtproject/official_releases/vsaddin/ 创建QT项目&#xff1a; 创建完成&…

教你搞一个比较简单的计时和进度条装饰器

教你搞一个比较简单的计时和进度条装饰器 什么是装饰器为啥要用装饰器呢&#xff1f;上代码&#xff01;如何使用装饰器效果 什么是装饰器 装饰器的英文是&#xff1a;Decorator。装修的英文是&#xff1a;Decoration。顾名思义就是我们要用装饰器在函数func()上搞点儿事儿&am…

「Django秘境探险:揭开Web开发的神秘面纱」

大家好&#xff0c;我是阿佑&#xff0c;今天将和大家一块学习到如何利用Django框架的高级特性&#xff0c;构建出既快速又安全的Web应用。我们将一起破解Django的内部机制&#xff0c;掌握从数据模型到模板设计的每一个环节。准备好了吗&#xff1f;Let’s go &#xff01; 文…

算法(二)二分查找

文章目录 二分查找简介实现方式循环方式递归方式 经典例子 二分查找简介 二分查找&#xff08;binary search&#xff09;算法&#xff0c;也叫折半算法。二分查找是针对有序的数据集合的查找办法&#xff0c;如果是无序的数据结合就使用遍历。二分查找之所以快速&#xff0c;…

Dijkstra求最短路篇二(全网最详细讲解两种方法,适合小白)(python,其他语言也适用)

前言&#xff1a; Dijkstra算法博客讲解分为两篇讲解&#xff0c;这两篇博客对所有有难点的问题都会讲解&#xff0c;小白也能很好理解。看完这两篇博客后保证收获满满。 第一篇博客讲解朴素Dijkstra算法Dijkstra求最短路篇一(全网最详细讲解两种方法&#xff0c;适合小白)(p…

原码一位乘法(计算机组成原理)

算法原理 每次将1位乘数所对应的部分积与原部分积的“累积和”相加&#xff0c;并移位 设置寄存器 存放部分积累积和、乘积高位存放被乘数存放乘数、乘积低位 法则 乘积的数值位俩数绝对值之积&#xff1b;符号位 位 俩数符号位进行异或&#xff0c;即 p x ⊕ y 步骤 设…