【小黑嵌入式系统第十四课】μC/OS-III程序设计基础(三)——信号量(任务同步资源同步)、事件标记组(与或多个任务)

本文主要是介绍【小黑嵌入式系统第十四课】μC/OS-III程序设计基础(三)——信号量(任务同步资源同步)、事件标记组(与或多个任务),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一课:
【小黑嵌入式系统第十三课】PSoC 5LP第二个实验——中断控制实验



前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能



文章目录

    • 1 信号量
      • 1.1 简介
      • 1.2 任务间同步
      • 1.3 ISR与任务同步
      • 1.4 资源同步
        • 例:银行柜台
      • 1.5 任务信号量
    • 2 事件标志组
      • 2.1 简介
      • 2.2 标志“与”
      • 2.3 标志“或”
      • 2.4 同步多个任务


1 信号量

1.1 简介

在实时多任务系统中,信号量(semaphore)被广泛用于:任务间对共享资源的互斥,但更多地是用于任务和中断服务程序之间的同步、任务之间的同步。

在这里插入图片描述
N为信号量值,表示发布信号量的次数累计值。
信号量用于任务-任务(或任务-ISR)间同步时,N表示事件已发生了多少次。
信号量用于资源共享时,N表示资源还可被多少个任务同时使用。


当任务(或ISR)调用OSSemPost()函数发送信号量时:
在这里插入图片描述
任务(或ISR)可以多次调用OSSemPost()函数发送信号量。


当信号量值大于0,任务调用OSSemPend()函数接收信号量时:

在这里插入图片描述


当信号量值等于0,任务调用OSSemPend()函数接收信号量时:

在这里插入图片描述

注意:μC/OS-III不允许在中断服务程序中等待信号量。


前面章节我们学习了互斥信号量,下面对计数型信号量与互斥信号量做一个对比。

在这里插入图片描述


1.2 任务间同步

在实际的应用中,常用信号量实现任务间的同步,OSSemPend()OSSemPost()会出现在不同任务中,但不一定成对出现。

在这里插入图片描述

注意:在实际的应用中,还有多对多、一对多信号量操作的情况,但很不常见,建议不要设计出这样的操作方式,这样会带来很多的麻烦。


用来实现任务间同步的信号量在创建时赋给初始值,一般为0,表示事件还未发生,初始值在OSSemCreate()函数中指定。

在这里插入图片描述


让一个LED以0.5Hz的频率闪烁,每按键一次,LED闪烁一次。

我们通过此例来说明如何使用信号量实现任务间同步,两个任务处理流程如下。

在这里插入图片描述


TaskKEY任务主要代码如下。

在这里插入图片描述


TaskLED任务主要代码如下。

在这里插入图片描述


1.3 ISR与任务同步

下面以示例来说明如何现实ISR与任务间同步。假设定时器1中断服务程序发送信号量,任务完成了信号量的创建并在接收到信号量后让蜂鸣器响一声。处理流程如下。

在这里插入图片描述


中断服务程序ISR示例代码如下。

在这里插入图片描述


蜂鸣器报警任务示例代码如下。

在这里插入图片描述


1.4 资源同步

在嵌入式系统中,可以使用信号量访问共享资源来实现资源同步。在使用时,注意发送信号量函数OSSemPost()与等待信号量函数OSSemPend()必须成对出现在同一个任务调用的函数中,才能实现资源同步(这与互斥信号量使用方式一致)。

在使用信号量做资源共享时,只有任务才能使用信号量,而中断服务程序则不可以。(注意对照前面所述,在使用信号量做ISR与任务间同步时,ISR可以给任务发送信号量,但不能做其它的信号量操作)

计数型信号量用于某共享资源可以同时为几个任务所用时,这是互斥型信号量不能处理的(互斥信号量是二值的)。


例:银行柜台

某银行有N个柜台可以为客户服务,设置信号量值为N(或者银行同时可以为N个用户服务)

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


为了说明使用信号量访问共享资源实现资源同步,设计两个任务,它们以不同的频率让LED点亮30个时钟节拍,然后熄灭60个时钟节拍,要求这两个任务不会互相干扰。下面是两个任务的处理流程。

在这里插入图片描述

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

在这里插入图片描述


下面给出两个LED任务的主要处理代码。

在这里插入图片描述


1.5 任务信号量

在μC/OS-III中,每个任务都有它自己的内嵌信号量,称为任务信号量。任务信号量是在任务创建OSTaskCreate()时创建的,因此任务创建之后便可以直接使用。

任务信号量使用起来更方便,且速度比一般信号量要快。

当事件发生时,用户若明确知道该给哪个任务发信号,此时就可以使用任务信号量。

在这里插入图片描述

μC/OS-III中的任务信号量服务函数以OSTaskSem???()命名。

在这里插入图片描述

  • OSTaskSemPend(),它在任务信号量所属任务中调用。(无任务控制块参数需传递)

在这里插入图片描述

  • 如OSTaskSemPost(),它在另一任务或ISR中调用。(需指定任务信号量所属任务的任务控制块参数,即发送(给)哪个任务的任务信号量)

在这里插入图片描述


2 事件标志组

2.1 简介

当任务要与多个事件的发生同步时,可以使用事件标志组。一个事件标志就是一个二值信号,事件标志组是若干二值信号的组合。

用事件标志组来做任务同步分为独立型同步(“或”同步)和关联型同步(“与”同步)。设一个任务与3个事件标志有关,如下图。

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

可以用多个事件的组合,发信号给多个任务,典型的有8个、16个或32个事件可以组合在一起(由os_type.h中的OS_FLAGS数据类型定义事件标志位数)。

在这里插入图片描述

注意:系统在一组新事件发生后判断是否有任务接收到需求的标志,在收到标志后进行任务状态切换。


2.2 标志“与”

为了说明如何使用标志事件组实现任务与若干个事件同步,我们设计一个系统,当时间到且独立按健被按下后,让LED1闪烁一下。三个任务的处理流程如图。

在这里插入图片描述


TaskKEY任务主要代码如下。

在这里插入图片描述


TaskDly任务主要代码如下。

在这里插入图片描述


TaskLED任务主要代码如下。

在这里插入图片描述


2.3 标志“或”

为了说明如何使用标志事件组实现任务与任何事件之一同步,我们设计一个系统,当时间到或独立按健被按下后,让LED1闪烁一下。三个任务的处理流程如图。

在这里插入图片描述

注意:标志“或”和标志“与”操作只在等待标志的LED任务有所不同,其余都相同。

由于发送标志的两个任务代码和标志“与”操作的相同,这里不做重复。标志“或”中的 TaskLED任务主要代码如下。

在这里插入图片描述


2.4 同步多个任务

有些时候需要使多个任务“同时”开始执行(将它们执行的起点同步到同一时刻),通过广播信号量来同步多个任务是一种常用的技术。

但当进行广播操作时,一些要同步的任务可能没有在等待信号量,解决该问题的方法是将信号量和事件标志组联合起来使用。

在这里插入图片描述
(1) 每个待同步的任务都需要先将一个事件标志位置位;
(2) 然后等待信号量的发布。
(3) 进行信号量广播的任务必须在所有事件标志位都被置位后,
(4) 才能发布信号量。

该方法要求左边任务优先级比右边任务优先级都低。否则对于右边的最后一个执行OSFlagPost()的任务,在它尚未执行OSSemPend()之前,左边任务就将发送信号量。

这篇关于【小黑嵌入式系统第十四课】μC/OS-III程序设计基础(三)——信号量(任务同步资源同步)、事件标记组(与或多个任务)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595067

相关文章

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We