【小黑嵌入式系统第十二课】μC/OS-III程序设计基础(二)——系统函数使用场合、时间管理、临界区管理、使用规则、互斥信号量

上一课:
【小黑嵌入式系统第十一课】μC/OS-III程序设计基础(一)——任务设计、任务管理(创建&基本状态&内部任务)、任务调度、系统函数

文章目录

    • 一、系统函数使用场合
      • 1.1 时间管理
        • 1.1.1 控制任务的执行周期
        • 1.1.2 控制任务的运行节奏
        • 1.1.3 状态查询
      • 1.2 资源同步
        • 1.2.1 “资源同步”图解
        • 1.2.2 “资源同步” 实现方式
      • 1.3 行为同步
        • 1.3.1 行为同步
        • 1.3.2 数据通信
    • 二、时间管理
      • 2.1 概述
      • 2.2 `OSTimeDly()`
      • 2.3 `OSTimeDlyHMSM()`
      • 2.4 `OSTimeDlyResume()`
      • 2.5 `OSTimeGet()`、`OSTimeSet()`
    • 三、临界区管理
      • 3.1 进入然后退出临界区
      • 3.2 禁止然后允许调度
    • 四、事件的一般使用规则
      • 4.1 相似性
      • 4.2 先创建后使用
      • 4.3 配对使用
      • 4.4 在ISR中使用
    • 五、互斥信号量
      • 5.1 简介
      • 5.2 资源同步


一、系统函数使用场合

1.1 时间管理

1.1.1 控制任务的执行周期

在任务函数的代码中可以通过插入延时函数来控制任务周期性运行,定时闲置CPU一段时间,供其它任务使用。

在这里插入图片描述

注意:延时函数OSTimeDly()是以系统节拍数为参数,而延时函数OSTimeDlyHMSM()是以实际时间值为参数,但在执行过程中仍然转换为系统节拍数。如果实际时间不是系统节拍的整数倍,将进行四舍五入处理。设系统节拍为50毫秒,调用OSTimeDly(20)的效果是延时1秒钟,调用OSTimeDlyHMSM(0,1,27,620)的实际时间是延时1分27秒600毫秒。


1.1.2 控制任务的运行节奏

在任务函数的代码中也可以通过插入延时函数来控制任务的运行节奏。

在这里插入图片描述


1.1.3 状态查询

查询过程是一个无限循环过程,只有当希望的状态出现以后才能退出这个无限循环,这种情况在实时操作系统管理下是不允许的,它将剥夺低优先级任务的运行机会。解决这个问题的办法是“用定时查询代替连续查询” 。

在这里插入图片描述


1.2 资源同步

1.2.1 “资源同步”图解

在这里插入图片描述


1.2.2 “资源同步” 实现方式
  1. 使用关中断:通过调用禁止中断函数OS_CRITICAL_ENTER()和允许中断函数OS_CRITICAL_EXIT()实现的。
  2. 使用关调度:通过调用禁止任务调度函数OSSchedLock()和允许任务调度函数OSSchedUnlock()实现的,因为禁止调度违背了多任务的初衷,所以不建议用户使用。
  3. 使用信号量与互斥信号量:通过等待信号量和发送信号量实现共享资源的独享。

1.3 行为同步

1.3.1 行为同步

一个任务的运行过程需要和其它任务的运行配合,才能达到预定的效果,任务之间的这种动作配合和协调关系称为“行为同步”。

在这里插入图片描述


1.3.2 数据通信

在这里插入图片描述
注意:尽管指针可能是局部变量,但只要指针指向的变量是全局变量,操作指针指向的变量时也需要当作全局变量来处理。


二、时间管理

2.1 概述

μC/OS-III提供了若干个时间管理服务函数,可以满足任务在运行过程中对时间管理的需求。在使用时间管理服务函数时,必须十分清楚一个事实:时间管理服务函数是以系统节拍为处理单位的,实际的时间与希望的时间是有误差的,最坏的情况下误差接近一个系统节拍。因此时间管理服务函数只能用在对时间精度要求不高的场合,或者时间间隔较长的场合。


2.2 OSTimeDly()

系统延时函数OSTimeDly()调用图解:

在这里插入图片描述

下面我们设计一个任务,让一个LED以50个时钟节拍为单位闪烁,说明OSTimeDly()函数的用途。由于篇幅关系,只给出任务主要处理代码。

在这里插入图片描述

注意:上面的设计是OSTimeDly() 控制任务的周期性执行,还可以用它来控制任务的运行节拍。


2.3 OSTimeDlyHMSM()

μC/OS-III提供了OSTimeDlyHMSM()系统延时函数,这个函数是以小时(H)、分(M)、秒(S)和毫秒(m)四个参数来定义延时时间的,函数在内部把这些参数转换为时钟节拍,再通过单次或多次调用OSTimeDly()进行延时和任务调度,所以延时原理和调用延时函数OSTimeDly()是一样的。

为了说明OSTimeDlyHMSM()函数的使用方法,下面我们设计一个任务,让一个LED以2Hz的频率闪烁。下面给出任务主要处理代码。

在这里插入图片描述

注意:上面的设计是**OSTimeDlyHMSM()**控制任务的周期性执行,还可以用它来控制任务的运行节拍。


2.4 OSTimeDlyResume()

µC/OS-III允许用户结束任务正处于的延时期,延时的任务可以不等待延时期满,而是通过其它任务取消其延时来使其处于就绪态,通过调用OSTimeDlyResume()和指定要恢复的任务来完成。

在这里插入图片描述

为了说明OSTimeDlyResume()函数的使用方法,我们设计一个系统。TaskLED任务让一个LED以0.5Hz的频率闪烁;按键任务处理按键事件,每按键一次,LED状态立即翻转一次。下面是两个任务的处理流程。

在这里插入图片描述
TaskLED任务代码如下:

在这里插入图片描述
TaskKEY任务的代码如下:

在这里插入图片描述


2.5 OSTimeGet()OSTimeSet()

无论时钟节拍何时发生,µC/OS-III都会将一个32位的计数器加1,这个计数器在用户调用OSStart()初始化多任务时和4,294,967,295个节拍执行完一遍的时候从0开始计数。

在这里插入图片描述

用户可以通过调用OSTimeGet()来获得该计数器的当前值, OSTimeGet()的详细信息见下表。

在这里插入图片描述
在这里插入图片描述

用户可以通过调用OSTimeSet()来改变计数器的值,OSTimeSet()的详细信息见下表。

在这里插入图片描述
在这里插入图片描述

为了说明OSTimeGet()函数的使用方法,我们设计一个任务,计算两次按键的时间间隔放在全局变量ktime中。下面是任务的处理流程。

在这里插入图片描述
TaskKEY任务代码如下:

在这里插入图片描述


三、临界区管理

3.1 进入然后退出临界区

进入然后退出临界段是“资源同步”的方法之一,能够在访问共享资源时保障信息的可靠性和完整性。

在这里插入图片描述

为了说明它在”资源同步”时的使用,我们设计一个系统,假设有两个任务,它们都对全局变量sum1和sum2操作。低优先级任务让这两个变量始终相等,并不断在计数;高优先级任务不断的判断这两个变量是否相等,不相等则点亮LED,下面是两个任务的处理流程。

在这里插入图片描述
TaskLED任务代码如下:

在这里插入图片描述

TaskAdd任务代码如下:

在这里插入图片描述


3.2 禁止然后允许调度

给调度器上锁OSSchedlock()函数用于禁止任务调度,直到任务完成后调用给调度器开锁OSSchedUnlock()函数为止。使用它有3点需要注意。

  1. OSSchedlock()OSSchedUnlock()必须成对使用,也可以嵌套使用;
  2. OSSchedlock()只是禁止了任务的调度,而没有禁止中断,此时如果允许中断,中断到来时还是会执行对应的中断服务程序;
  3. 调用OSSchedLock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用,直到配对的OSSchedUnlock()调用为止。

注意:对于用户来说,极少使用禁止然后允许调度的方法。不过,很多操作系统内部和驱动程序使用它来减少中断响应时间。


四、事件的一般使用规则

4.1 相似性

事件管理函数是μC/OS-III中最多的系统函数,而且每种事件具有的管理函数数目不同。但是所有的事件都有类似的4个函数,它们是所有事件的基本功能,其函数名类似,使用方法也类似,详细函数见下表。

在这里插入图片描述


4.2 先创建后使用

任何一个事件,必须先创建后使用。创建事件是通过调用函数OS???Create()实现的,其中???为事件的类型。创建事件可以在main()函数中,但更多的是在任务初始化部分。使用方法如下。

在这里插入图片描述

一般来说,在嵌入式系统中,事件是静态使用的,即创建后永远不删除。但有时候需要动态使用,即根据需要创建和删除事件,此时创建事件就是在任务的事件执行代码中,使用方法如下。

在这里插入图片描述


4.3 配对使用

下面给出一个示例,假设Task0为高优先级任务,Task1为低优先级任务。 Task0代码如下。

在这里插入图片描述
Task1代码如下:

在这里插入图片描述


4.4 在ISR中使用

要掌握事件函数在中断服务程序中的调用规则,我们必须清楚中断服务有哪些特点。

  • 中断与所有的任务异步
  • 中断服务程序总体是顺序结构
  • 中断服务程序需要尽快退出
  • 中断服务程序不能等待

下面给出事件在中断服务程序中使用方法,假设Task0任务接收ISR发送的消息,任务代码如下。

在这里插入图片描述
ISR中的代码如下:

在这里插入图片描述

注意:

  1. 中断服务程序一般不会调用建立和删除事件函数,否则要么没有起到事件的作用,要么程序很复杂;
  2. 中断服务程序不能调用等待事件的函数,否则可能造成程序崩溃。

五、互斥信号量

5.1 简介

在日常生活中,出租车是一种常用的共享资源,当出租车载客时,从外面可以看到标识为载客;当空闲时,标识为空车。这样等车的人就可以根据标识知道出租车的当前状态,判断是否能够座上这辆车。这个标识牌就是一个二值信号量。由于这种二值信号量可以实现对共享资源的独占式处理,所以叫做互斥信号量。

在这里插入图片描述

互斥信号量也称为mutex,专用于资源同步。互斥信号量具有一些特性:占用一个空闲优先级,以便解决优先级反转问题。

假设任务1和任务3共享一个资源,任务2为优先级介于任务1和任务3之间的一个与该共享资源无关任务,分析优先级反转问题。

在这里插入图片描述

此时,只要任务3没有释放共享资源,即使任务1比任务2优先级更高,但却在任务2之后运行,这种现象就是优先级反转。
并且在任务1等待共享资源期间,任务2就绪时可剥夺任务3的运行,导致额外增加了任务1的等待时间,这被称为无界优先级反转,因任何一个(介于任务1、3之间的)中等优先级的任务都可以延长任务1的等待时间。

假设任务1和任务3共享一个资源,使用互斥信号量进行资源同步,任务2为优先级介于任务1和任务3之间的一个与该共享资源无关任务,通过互斥信号量解决优先级反转问题。

在这里插入图片描述

此时,任务2无法在任务1之前得到运行,不发生优先级反转

综上所述,可以说能防止优先级反转现象的信号就是互斥信号量。

使用互斥信号量有以下3点需要注意:

  1. 在嵌入式系统中,经常使用互斥信号量访问共享资源来实现资源同步。而用来实现资源同步的互斥信号量在创建时初始化,这是由OSMutexCreate ()函数来实现的;

  2. OSMutexPost ()发送互斥信号量函数与OSMutexPend ()等待互斥信号量函数必须成对出现在同一个任务调用的函数中,因此我们需要编写一个公共的库函数,因为有多个任务可能调用这个函数 ;

  3. 信号量最好在系统初始化的时候创建,不要在系统运行的过程中动态地创建和删除。在确保成功地创建信号量之后,才可对信号量进行接收和发送操作。


5.2 资源同步

为了说明使用互斥信号量访问共享资源实现资源同步,设计两个任务,它们在不同的音符按键按下期间让DAC输出不同的音符声音,要求这两个任务不会互相干扰。下面是两个任务的处理流程。

在这里插入图片描述

为了实现资源同步,我们需要保证OSMutexPost()OSMutexPend()成对出现在同一个任务函数中,所以我们编写一个库函数DAC()供两个任务调用,代码如下。

在这里插入图片描述

下面给出两个DAC任务的主要处理代码:

在这里插入图片描述

使用互斥信号量做共享资源的管理,可参考示例程序:“Micrium_CY8CKIT-050B_uCOS-III-LCDMutex_GNU(PSoC Creator 4.0).rar”

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营Day7 | 344.反转字符串、541.反转字符串||、替换数字、151.反转字符串中的单词、右旋字符串

LeetCode 344 反转字符串 本题思路:反转字符串比较简单,定义两个指针,一个 i 0, 一个 j s.length-1。然后定义一个临时变量 tmp,进行交换 s[i] 和 s[j]。 class Solution {public void reverseString(char[] s) {int i 0;int …

在Excel中,如何简单快速地删除重复项,这里提供详细步骤

当你在Microsoft Excel中使用电子表格时,意外地复制了行,或者如果你正在制作其他几个电子表格的合成电子表格,你将遇到需要删除的重复行。这可能是一项非常无脑、重复、耗时的任务,但有几个技巧可以让它变得更简单。 删除重复项 …

【Linux】权限篇(二)

权限目录 1. 前言2. 权限2.1 修改权限2.2 有无权限的对比2.3 另外一个修改权限的方法2.3.1 更改用户角色2.3.2 修改文件权限属性 3. 第一个属性列4. 目录权限5. 默认权限 1. 前言 在之前的一篇博客中分享了关于权限的一些知识,这次紧接上次的进行,有需要…

《A++ 敏捷开发》-1 如何改善

1 如何改善 敏捷开发过程改进案例 5月 A公司一直专门为某电信公司提供针对客服、线上播放等业务。 张工是公司的中层管理者,管理好几个开发团队,有5位项目经理向他汇报。 他听说老同学的团队都开始用敏捷开发,很感兴趣,便参加了…

mysql SQL执行超时问题

show variables like max_execution_time 使用这个命令查看了,没有设置sql执行超时时间,那么大概率问题就出在阿里的Druid数据库连接池出了问题 尝试着socketTimeout由60000毫秒改成10000毫秒,果然执行了十几秒就超时报错了 socketTime…

【雷达原理】雷达测速原理及实现方法

一、雷达测速原理 1.1 多普勒频率 当目标和雷达之间存在相对运动时,若雷达发射信号的工作频率为,则接收信号的频率为,其中为多普勒频率。将这种由于目标相对于辐射源运动而导致回波信号的频率发生变化的现象称为多普勒效应。 如图1-1所示&a…

IDEA的facets和artifacts

在软件开发领域,IDEA 是指 JetBrains 公司的 IntelliJ IDEA,是一款流行的集成开发环境(Integrated Development Environment)。在 IntelliJ IDEA 中,"facets" 和 "artifacts" 是两个概念&#xff…

Qt通用属性工具:随心定义,随时可见(一)

一、开胃菜&#xff0c;没图我说个DIAO 先不BB&#xff0c;给大家上个效果图展示下&#xff1a; 上图我们也没干啥&#xff0c;几行代码&#xff1a; #include "widget.h" #include <QApplication> #include <QObject> #include "QtPropertyEdit…

攻防世界——game 游戏

下载下来是一个exe文件&#xff0c;可以用IDA打开 我们先运行一下 这是属于第二种类型&#xff0c;完成一个操作后给你flag 这种题我更倾向于动调直接得到flag 我们查壳 没有保护壳&#xff0c;直接32打开 进入字符串界面&#xff0c;找到显示的那部分 int __cdecl main_0(…

汽车级EEPROM 存储器 M24C64-DRMN3TP/K是电可擦除可编程只读存储器?它的功能特性有哪些?

M24C64-DRMN3TP/K是一款64 Kbit串行EEPROM汽车级设备&#xff0c;工作温度高达125C。符合汽车标准AEC-Q100 1级规定的极高可靠性。 该设备可通过一个高达1MHz的简单串行I2C兼容接口访问。 存储器阵列基于先进的真EEPROM技术&#xff08;电可擦除可编程存储器&#xff09;。M2…

【三维生成与重建】ZeroRF:Zero Pretraining的快速稀疏视图360°重建

系列文章目录 题目&#xff1a;ZeroRF: Fast Sparse View 360◦ Reconstruction with Zero Pretraining 任务&#xff1a;稀疏重建&#xff1b;拓展&#xff1a;Image to 3D、文本到3D 作者&#xff1a;Ruoxi Shi* Xinyue Wei* Cheng Wang Hao Su &#xff0c;来自UC San Dieg…

【接口测试】如何定位BUG的产生原因

我们从在日常功能测试过程中对UI的每一次操作说白了就是对一个或者多个接口的一次调用&#xff0c;接口的返回的内容(移动端一般为json)经过前端代码的处理最终展示在页面上。http接口是离我们最近的一层接口&#xff0c;web端和移动端所展示的数据就来自于这层&#xff0c;那么…

深入理解 Rust 中的容器类型及其应用

Rust 作为一种系统编程语言&#xff0c;提供了丰富的容器类型来处理各种数据结构和算法。这些容器类型不仅支持基本的数据存储和访问&#xff0c;还提供了高效的内存管理和安全性保障。本文将详细介绍 Rust 中的几种主要容器类型&#xff0c;包括它们的用法、特点和适用场景&am…

【数据结构一】初始Java集合框架(前置知识)

Java中的数据结构 Java语言在设计之初有一个非常重要的理念便是&#xff1a;write once&#xff0c;run anywhere&#xff01;所以Java中的数据结构是已经被设计者封装好的了&#xff0c;我们只需要实例化出想使用的对象&#xff0c;便可以操作相应的数据结构了&#xff0c;本篇…

【C++进阶02】多态

一、多态的概念及定义 1.1 多态的概念 多态简单来说就是多种形态 同一个行为&#xff0c;不同对象去完成时 会产生出不同的状态 多态分为静态多态和动态多态 静态多态指的是编译时 在程序编译期间确定了程序的行为 比如&#xff1a;函数重载 动态多态指的是运行时 在程序运行…

【Amazon 实验②】使用Amazon WAF做基础 Web Service 防护之自定义规则

文章目录 1. 自定义规则1.1 介绍 2. 实验步骤2.1 测试2.2 输出 上一篇章介绍了使用Amazon WAF做基础 Web Service 防护中的Web ACLs 配置 & AWS 托管规则的介绍和演示操作 【Amazon 实验①】使用Amazon WAF做基础 Web Service 防护&#xff0c;本篇章将继续介绍关于自定义…

操作系统--磁盘存储器的管理

目录 8.1 外存的组织方式 常用的外存分配方法&#xff1a; 8.1.1 连续组织方式 连续组织方式的主要优点有&#xff1a; 连续组织方式的主要缺点如下&#xff1a; 8.1.2 链接组织方式 链接组织方式的主要优点是&#xff1a; 1. 隐式链接 2. 显式链接 8.1.3 FAT和NTFS技术 文…

大创项目推荐 深度学习+python+opencv实现动物识别 - 图像识别

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 inception_v3网络5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

基于Java (spring-boot)的在线考试管理系统

一、项目介绍 系统功能说明 1、系统共有管理员、老师、学生三个角色&#xff0c;管理员拥有系统最高权限。 2、老师拥有考试管理、题库管理、成绩管理、学生管理四个模块。 3、学生可以参与考试、查看成绩、试题练习、留言等功能 二、作品包含 三、项目技术 后端语言&#xff1…

【二】【C语言\动态规划】解码方法、不同路径、不同路径II,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…