uCOSIII实时操作系统 二 同步与通信

news2024/11/21 0:21:38

目录

同步概念:

互斥概念:

临界区概念:

任务时间概念:

信号量概念: 

互斥信号量概念:

事件标志组概念:

消息邮箱和消息梯队概念:

内存管理概念:

如何从裸机开发转跳到OS编程:

轮询系统:

前后台系统:

多任务系统:


同步概念:

任务是独立的。有时候一个任务完成的前提是需要另一个任务给出一个结果,任务之间的这种制约性的合作运行机制叫做任务间的同步

怎么来同步呢?
首先,信号量初始化成0(用来实现同步机制),接着,B任务开始就请求信号量,但是此时信号量的值为0,只能等待。然后A任务在完成任务后在输出信号量,B接受到信号量开始执任务。
如果内核支持计数式信号量,信号量的值表示尚未得到处理的事件数。请注意,可能会有一个以上的任务在等待同一事件的发生,则这种情况下内核会根据以下原则之一发信号给相应的任务:

  1. 发信号给等待事件发生的任务中优先级最高的任务,或者
  2. 发信号给最先开始等待事件发生的那个任务

根据不同的应用,发信号以标识事件发生的中断服务或任务也可以是多个

互斥概念:

互斥条件:实现任务之间通讯最简单的办法就是使用任务共享数据结构(类似于裸机的全局变量)。特别是当所有的任务都在一个单一的地址空间下,使用全局变量、指针、缓冲区、链表、循环缓冲区等,使用共享数据结构就容易理解。虽然共享数据区法简化了任务之间的信息交换,但是必须保证每一个任务在处理共享数据时候的排他性,以避免竞争和数据破坏。

与共享资源打交道时,使用满足互斥条件的一般方法有:

  • 关中断
  • 禁止任务切换
  • 利用信号量

临界区概念:

代码的临界段也成为临界区,指处理时不可分割的代码。例如:每个任务中访问共享资源部分代码。这一部分一旦执行,则不允许任何中断打断,因为共享资源的访问是互斥的。在临界区不允许任务切换,这是最基本的原则。

为确保临界代码的执行,在进入临界区访问共享资源之前,采用关中断给调度器上锁,使用信号量等方式,达到互斥的目的。而在代码执行后要立即开启,中断,解锁以及释放信号量。

任务时间概念:

事件(Event)就是在操作系统运行过程中发生的事情。例如任务被挂起、唤醒、创建等。 μC/OS操作系统在处理任务的同步和通信等环节,大量的使用了事件这一概念,创建了事件控制块这样的数据结构以进行事件的管理。

信号量概念: 

在一个时刻有些共享资源只可以被一个任务所占用,而有些可以被N多个任务所占用,前一种共享资源就好比有一把钥匙,钥匙发出去了,得到钥匙的任务可以访问共享资源,其他请求该资源的任务必须等得到钥匙的任务把钥匙归还。后者则可以有N把钥匙,如果N把钥匙都发完了,第N+1个请求访问共享资源的任务就必须等待。这些钥匙就可以用信号量(semaphore)来表示。

信号量标志了共享资源的有效可被访问数量,于是要获得共享资源的访问权,就首先要得到信号量这把钥匙。

信号量的三种操作:

1、建立(create)

建立并初始化信号量,执行的是给资源配置钥匙的操作。

2、请求(pand):

请求信号,如果还有钥匙(信号量大于0)就去领一把钥匙(信号量)执行下去,如果没有就把自己堵塞。

3、释放(post):

访问资源的操作完成之后就要把钥匙(信号量)交回,这时,如果有等待该钥匙的任务就绪,并比当前任务有更高的优先级,就执行任务调度。否则原任务在释放信号量后继续执行。

见图:

要与同一共享数据打交道的任务调用等待信号量函数OSSemPend()。处理完共享数据以后再调用释放信号量函数OSSemPost()。

在使用信号量之前,一定要对该信号量做初始化。作为互斥条件,信号量初始化为1。使用信号量处理共享数据不增加中断延迟时间,如果中断服务程序或当前任务激活了一个高优先级的任务,高优先级的任务立即开始执行。

伪代码:

sem = 1;// 信号量初始化(建立)
任务函数(void)
{
    while(1)
    {
        OSSemPend();//请求
        /*
        对共享数据进行处理
        */
        OSSemPost();//释放
    }
}

我的理解是可以把信号量比作一个标志位,有它在其他任何中断不不能打断当前任务的执行。

互斥信号量概念:

互斥信号量是一种特殊的信号量,这不仅在于该信号量只用于互斥资源的访问,还在于使用互斥信号量管理需要解决的“优先级反转”问题。(优先级反转:CPU不去执行那些优先级高的任务反而去执行那些低优先级的任务。

假设有三个任务,优先级从高到底分别是任务H(high)M(middle)L(low)。

任务H和任务L使用互斥信号量访问同一临界资源,任务M不使用临界资源。

  1. L任务正在使用临界资源,(信号量加锁),H任务被唤醒,执行H任务,但此时L任务还没有执行完,此时的临界资源还没有被释放,(互斥信号量还处于加锁状态,即使优先级更高的任务也无法访问这个临界资源)。
  2. 这个时刻H任务也要对该临界资源进行访问,但L任务还未释放资源,由于保护机制,H任务进入阻塞态,L任务得以继续运行,此时已经发生了优先级翻转现象。
  3. 某个时刻M任务被唤醒,由于M任务的优先级高于工任务,M任务抢占了CPU的使用权,M任务开始运行,此时L任务尚未执行完,临界资源还没被释放。
  4. M任务运行结束,归还CPU使用权,L任务继续运行。
  5. L任务运行结東,释放临界资源(信号量解锁),H任务得以对资源进行访问,H任务开始运行。

那到底什么是优先级反转呢?

我的理解是在低优先级中还有高优先级需要运行的条件,所以就从高优先级退到低优先级中(个人理解)。

事件标志组概念:

在信号量和互斥信号量的管理中,任务请求资源,如果资源未被占用就可继续运行,否则只能阻塞,等待资源释放的事件发生。
这种事件是单一的事件。如果任务要等待多个事件的发生,或多个事件中的某一个事件的发生就可以继续运行,那么就应该采用事件标志组管理。 事件标志组管理的条件组合可以是多个事件都发生,也可以是多个事件中有任何一个事件发生。尤其特别的是,还可以是多个事件都没有发生或多个事件中有任何一个事件没有发生。

消息邮箱和消息梯队概念:

uCOSIII中已经没有了消息邮箱这个说法;

有时很需要任务间的或中断服务与任务间的通讯。这种信息传递称为任务间的通讯。任务间信息的传递有两个途径:通过全程变量或发消息给另一个任务。
用全程变量时,必须保证每个任务或中断服务程序独享该变量。如果两个任务共享某变量,各任务实现独享该变量的办法可以是关中断再开中断,或使用信号量(如前面提到的那样)。请注意,任务通过全程变量与中断服务程序通讯,而任务并不知道什么时候全程变量被中断服务程序修改了,除非中断程序以信号量方式向任务发信号或者是该任务以查询方式不断周期性地查询变量的值 。要避免这种情况,用户可以考虑使用邮箱或消息队列。

邮箱(MailBox)很明显是用于通信的,邮箱中的内容一般是信件。操作系统也通过邮箱来管理任务间的通信与同步,**发送和接收消息的任务约定,传递的消息实际上是传递的指针指向的内容**。意思就是邮箱中的内容却不是信件本身,而是指向消息内容的地址!这个指针是void类型的(指针占4个字节),可以指向任何的数据结构。因而这样的设计更经济,所发送的信息范围也就更宽,邮箱中可以容纳下任何长度的数据了。

消息队列(message queue)也用于给任务发消息,但是它是由多个消息邮箱组合形成的,是消息邮箱的集合实质上是消息邮箱的队列一个消息邮箱只能容纳一条消息。采用消息队列,一是可以容纳多条消息,二是消息是有序的 。通常,先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,**即先进先出原则(FIFO)。然而μC/OS-Ⅱ也允许使
用后进先出方式(LIFO)。**像使用邮箱那样,当一个以上的任务要从消息队列接收消息时,每个消息队列有一张等待消息任务的等待列表(Waiting List)。如果消息队列中没有消息,即消息队列是空,等待消息的任务就被挂起并放入等待消息任务列表中,直到有消息到来。通常,内核允许等待消息的任务定义等待超时的时间。如果限定时间内任务没有收到消息,该任务就进入就绪态并开始运行,同时返回出错代码,指出出现等待超时错误。一旦一则消息放入消息队列,该消息将传给等待消息的任务中优先级最高的那个任务,或是最先进入等待消息任务列表的任务。

内存管理概念:

μC/OS-II中,采用分区的方式管理内存,即将连续的大块内存按照分区来管理,每个系统中有数个这样的分区, 每个分区又包含数个内存块,每个内存块的大小相同。这样,再分配内存的时候,根据需要从不同的分区中得到数个内存块,而在释放时,这些内存块重新释放回他们原来所在的分区。这样就不回产生内存越分越乱,没有整块连续分区的问题了。

如何从裸机开发转跳到OS编程:

裸机系统通常分成轮询系统和前后台系统

轮询系统:

轮询系统即是在裸机编程的时候,先初始化好相关的硬件,然后让主程序在一个死循环里面不断循环,顺序地做各种事情。最常用的应该就是while(1){};。轮询系统是一种非常简单的软件结构,通常只适用于那些只需要顺序执行代码且不需要外部事件来驱动的就能完成的事情。在代码清单 中,如果只是实现 LED 翻转,串口输出,液晶显示等这些操作,那么使用轮询系统将会非常完
美。但是,如果加入了按键操作等需要检测外部信号的事件,用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。

//伪代码
int main ()
{
    //硬件相关初始化
    HardwareInit();
    while(1)
    {
        Dosomething1();

        Dosomething2();

        Dosomething3();
    }
    
}

假设DoSomething3 是按键扫描,当外部按键被按下,相当于一个警报,这个时候,需要立马响应,并做紧急处理,而这个时候程序刚好执行DoSomething1,要命的是 DoSomething1需要执行的时间比较久,久到按键释放之后都没有执行完毕,那么当执行到 DoSomething3的时候就会丢失掉一次事件。足见,轮询系统只适合顺序执行的功能代码,当有外部事件驱动时,实时性就会低。

前后台系统:

相比轮询系统,前后台系统是在轮询系统的基础上加入了中断。外部事件响应在中断里面完成,事件的处理还是回到轮询系统中完成,其中中断在这里我们称之为前台,main函数里边的无限循环我们称之为后台。并且把外部的紧急事件放到中断里处理。

多任务系统:

相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的(裸机是在中断中完成,操作系统在任务中完成由CPU去任务调度)。在多任务系统中,任务跟中断一样,也具有优先级,优先级高的任务回被优先的执行,当一个紧急的事件在中断被标记之后,如果事件对应的优先级足够高,就会立马响应。相比前后台系统,多任务系统的实时性又被提高了。

//伪代码(基本代码框架)
int flag  = 0;//全局变量
int main(void)//主函数
{
    init();//硬件初始化
    osinit();//操作系统OS初始化
    osstart();//开启操作系统OS
}

void ISR1()//中断处理函数
{
    flag = 1;
}


void task1(void)//任务函数
{
    Dosmoesting1();//任务实体
}

void task2(void)//负责中断的任务
{
    while(1)
    {
        if(flag=1)
             Dosmoesting2();//任务实体
    }
}

相比较前后台系统中后台顺序执行程序主体,在多系统中,根据程序的功能我们把程序主体分割成一个个独立的,无限循环并且不能返回的任务,每个任务都是独立的互不干扰的,且具备优先级,由操作系统调度管理。加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流不用担心每个功能模块之间是否存在干扰。整个系统随之带来的额外开销就是操作系统占据的那一丁点的 FLASH 和RAM。现如今,单片机的 FLASH 和 RAM 是越来越大,完全足以抵挡 RTOS 那点开销。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络编程1-简单的CS通信程序

Linux网络编程1-简单的CS通信程序 1.Socket相关API说明1.1字节序转换函数:用于ip和port转换1.2sockaddr结构1.3socket函数 以及两个队列1.4bind listen connect accept1.5收发数据 2.服务器和客户端程序代码流程3.服务器端4.客户端5.测试accept不是建立连接而是从已…

1803_ChibiOS网络书籍阅读_嵌入式RTOS介绍

全部学习汇总: GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 1. RTOS指的是实时性操作系统,但是并不是只有嵌入式领域使用RTOS。然而,嵌入式是RTOS的主要使用领域。 2. 一般的RTOS有一组…

国庆中秋宅家自省:偷偷尝鲜

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 Python3数据科学包系列(三):数据分析实战 国庆中秋宅家自省: Pytho…

【visual studio 小技巧】项目属性->生成->事件

需求 我们有时会用到一些dll,需要把这些dll和我们生成的exe放到一起,一般我们是手动自己copy, 这样发布的时候,有时会忘记拷贝这个dll,导致程序运行出错。学会这个小技巧,就能实现自动copy,非…

Ubuntu1804 安装后无法使用root登录解决方法

1. 给root用户设置密码 sudo passwd root2. 确认是否安装ssh服务 (在安装Ubuntu 的时候可以勾选安装ssh 远程服务),没有安装的话执行以下命令(Ubuntu可以连接互联网) sudo apt-get instll openssh-server3. 设置允许root 用户进行远程连接 sudo vim /etc/ssh/sshd_config 在…

10.3 调试事件转存进程内存

我们继续延申调试事件的话题,实现进程转存功能,进程转储功能是指通过调试API使获得了目标进程控制权的进程,将目标进程的内存中的数据完整地转存到本地磁盘上,对于加壳软件,通常会通过加密、压缩等手段来保护其代码和数…

【Ubuntu】基于C++实现人脸识别

人脸识别考勤机 文章目录 人脸识别考勤机概述第一章 搭建Ubuntu环境1.1 什么是物联网1.2 物联网应该怎么学1.3 Linux开发环境搭建1.4 Linux基本使用1.5 Ubuntu网络配置 第二章 “hello,world!”程序2.1 什么是程序2.2 “hello,world!”程序2.3 C语法扩展2.4 常见错误调试 第三章…

Numpy科学计算基础库--numpy基础知识

对数组执行数学运算和逻辑运算时,Numpy 是非常有用的。在用 Python 对 n 维数组和矩阵进行运算时,Numpy 库提供了大量有用特征。Numpy 库数组有两种形式:向量和矩阵。严格地讲,向量是一维数组,矩阵是多维数组。在某些情…

Redis-数据过期策略

数据过期策略 惰性删除策略优点:对cpu比较友好,在用到该key的时候才去进行判断,对于很多用不到key不用浪费时间去检查是否过期缺点:对内存不友好,如果一个key过期了,但是我们又一直没有用到该key&#xff0…

基于YOLOv8的安全帽检测系统(4):EMA基于跨空间学习的高效多尺度注意力、效果优于ECA、CBAM、CA,助力行为检测 | ICASSP2023

目录 1.Yolov8介绍 2.安全帽数据集介绍 3.EMA介绍 4.训练结果分析 5.系列篇 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的(SOTA)模型,它建立在先前YOLO…

Win11 安装 Vim

安装包: 链接:https://pan.baidu.com/s/1Ru7HhTSotz9mteHug-Yhpw?pwd6666 提取码:6666 双击安装包,一直下一步。 配置环境变量: 先配置系统变量中的path: 接着配置用户变量: 在 cmd 中输入…

MySQL 事务隔离级别与锁机制详解

目录 一、前言二、事务及其ACID属性三、并发事务处理带来的问题四、事务隔离级别4.1、隔离级别分类4.2、查看当前数据库的事务隔离级别:4.3、临时修改数据库隔离级别(重启MySQL后恢复到配置中的级别) 五、表数据准备六、MySQL常见锁介绍5.1、锁分类5.2、…

【网络安全 --- XSS漏洞利用实战】你知道如何利用XSS漏洞进行cookie获取,钓鱼以及键盘监听吗?--- XSS实战篇

一,XSS 实战 以pikachu靶场为例 1-1 盗取cookie 过程:想要盗取别人的cookie信息的话有一个前提条件,就是你应该在别人触发你的xss攻击时,你的代码应该将收集的cookie信息发送给你的平台来接收,这样才获取到了数据 …

图的广度遍历-邻接矩阵实现

description 本题要求实现邻接矩阵存储图的广度优先遍历。 函数接口定义: void BFS(MGraph G,Vertex i); 其中MGraph是邻接矩阵存储的图,定义如下: #define MaxVertexNum 10 /定义最大顶点数/ typedef int Vertex;/* 用顶点下标表示顶点,…

1799_GNU pdf阅读器evince_windows系统下编译尝试

全部学习汇总: GreyZhang/g_GNU: After some years I found that I do need some free air, so dive into GNU again! (github.com) 从网上下载下来了evince的代码,尝试做一个windows下的编译。 这应该是autotools的构建系统,先尝试运行confi…

java做个qq机器人

前置的条件 机器人是基于mirai框架实现的。根据官方的文档&#xff0c;建议使用openjdk11。 我这里使用的编辑工具是idea2023 在idea中新建一个maven项目&#xff0c;虽然可以使用gradle进行构建&#xff0c;不过我这里由于网络问题没有跑通。 pom.xml <dependency>&l…

提示msvcp140.dll丢失的5个解决方法,msvcp140.dll丢失问题全面分析

在我们的日常生活和工作中&#xff0c;电脑已经成为不可或缺的工具。然而&#xff0c;在使用电脑的过程中&#xff0c;我们经常会遇到各种问题&#xff0c;其中就包括提示 msvcp140.dll 丢失的问题。msvcp140.dll 是 Visual C Redistributable for Visual Studio 2015 的运行时…

堆--数组中第K大元素

如果对于堆不是太认识&#xff0c;请点击&#xff1a;堆的初步认识-CSDN博客 解题思路&#xff1a; /*** <h3>求数组中第 K 大的元素</h3>* <p>* 解体思路* <ol>* 1.向小顶堆放入前k个元素* 2.剩余元素* 若 < 堆顶元素, 则略过* …

SM5308 2.1A 充电 2.4 A 放电高集成度移动电源 SOC 可替代IP5306

SM5308 是一款集成升压转换器、锂电池充电管理、电池电量指示的多功能电源管理 SOC&#xff0c;为移动电源 提供完整的电源解决方案。 SM5308 的高集成度与丰富功能,使其在应用时仅需极少的外围器件,并有效减小整体方案的尺寸&#xff0c; 降低 BOM 成本。 SM5308 只需一个电…

竞赛选题 深度学习 opencv python 实现中国交通标志识别

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…