(学习日记)2024.04.08:UCOSIII第三十六节:事件

news2025/1/19 3:41:16

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2024.04.08:UCOSIII第三十六节:事件

  • 五十、UCOSIII:事件
    • 1、事件的基本概念
    • 2、事件的应用场景
    • 3、事件运作机制
    • 4、事件控制块

五十、UCOSIII:事件

1、事件的基本概念

事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。
与信号量不同的是, 它可以实现一对多,多对多的同步。
即一个任务可以等待多个事件的发生:
可以是任意一个事件发生时唤醒任务进行事件处理; 也可以是几个事件都发生后才唤醒任务进行事件处理。
同样,也可以是多个任务同步多个事件。

每一个事件组只需要很少的RAM空间来保存事件组的状态。
事件组存储在一个OS_FLAGS类型的Flags变量中,该变量在事件结构体中定义。
而变量的宽度由我们自己定义,可以是8位、16位、32位的变量,取决于os_type.h中的OS_FLAGS的位数。
在STM32中,我们一般将其定义为32位的变量, 有32个位用来实现事件标志组。
每一位代表一个事件,任务通过“逻辑与”或“逻辑或”与一个或多个事件建立关联,形成一个事件组。
事件的“逻辑或”也被称作是独立型同步,指的是任务感兴趣的所有事件任一件发生即可被唤醒;
事件“逻辑与”则被称为是关联型同步, 指的是任务感兴趣的若干事件都发生时才被唤醒,并且事件发生的时间可以不同步。

多任务环境下,任务、中断之间往往需要同步操作,一个事件发生会告知等待中的任务,即形成一个任务与任务、 中断与任务间的同步。
事件可以提供一对多、多对多的同步操作。
一对多同步模型:一个任务等待多个事件的触发, 这种情况是比较常见的;
多对多同步模型:多个任务等待多个事件的触发。

任务可以通过设置事件位来实现事件的触发和等待操作。
μC/OS的事件仅用于同步,不提供数据传输功能。

μC/OS提供的事件具有如下特点:

  • 事件只与任务相关联,事件相互独立,一个32位(数据宽度由用户定义)的事件集合用于标识该任务发生的事件类型, 其中每一位表示一种事件类型(0表示该事件类型未发生、1表示该事件类型已经发生),一共32种事件类型。
  • 事件仅用于同步,不提供数据传输功能。
  • 事件无排队性,即多次向任务设置同一事件(如果任务还未来得及读走),等效于只设置一次。
  • 允许多个任务对同一事件进行读写操作。
  • 支持事件等待超时机制。
  • 支持显式清除事件。

在μC/OS的等待事件中,用户可以选择感兴趣的事件,并且选择等待事件的选项。
它有4个属性,分别是逻辑与、逻辑或、等待所有事件清除或者等待任意事件清除。
当任务等待事件同步时,可以通过任务感兴趣的事件位和事件选项来判断当前获取的事件是否满足要求。
如果满足则说明任务等待到对应的事件,系统将唤醒等待的任务; 否则,任务会根据用户指定的阻塞超时时间继续等待下去。

2、事件的应用场景

μC/OS的事件用于事件类型的通讯,无数据传输,也就是说,我们可以用事件来做标志位,判断某些事件是否发生了,然后根据结果做处理。
那为什么不直接用变量做标志呢,岂不是更好更有效率?
非也非也,若是在裸机编程中,用全局变量是最为有效的方法。
但是在操作系统中,使用全局变量就要考虑以下问题了:

  • 如何对全局变量进行保护呢,如何处理多任务同时对它进行访问?
  • 如何让内核对事件进行有效管理呢?使用全局变量的话,就需要在任务中轮询查看事件是否发送,这简直就是在浪费CPU资源啊, 还有等待超时机制,使用全局变量的话需要用户自己去实现。

所以,在操作系统中,还是使用操作系统给我们提供的通信机制就好了,简单方便还实用。

在某些场合,可能需要多个时间发生了才能进行下一步操作,比如一些危险机器的启动,需要检查各项指标,当指标不达标的时候, 无法启动。
但是检查各个指标的时候,不能一下检测完毕。所以需要事件来做统一的等待。
当所有的事件都完成了, 那么机器才允许启动,这只是事件的其中一个应用。

事件可使用于多种场合,它能够在一定程度上替代信号量,用于任务与任务间,中断与任务间的同步。
一个任务或中断服务例程发送一个事件给事件对象, 而后等待的任务被唤醒并对相应的事件进行处理。
但是它与信号量不同的是,事件的发送操作是不可累计的,而信号量的释放动作是可累计的。
事件另外一个特性是, 接收任务可等待多种事件,即多个事件对应一个任务或多个任务。
同时按照任务等待的参数,可选择是“逻辑或”触发还是“逻辑与”触发。
这个特性也是信号量等所不具备的,信号量只能识别单一同步动作,而不能同时等待多个事件的同步。

各个事件可分别发送或一起发送给事件对象,而任务可以等待多个事件,任务仅对感兴趣的事件进行关注。
当有它们感兴趣的事件发生时并且符合感兴趣的条件, 任务将被唤醒并进行后续的处理动作。

3、事件运作机制

等待(接收)事件时,可以根据感兴趣的参事件类型等待事件的单个或者多个事件类型。事件等待成功后, 必须使用OS_OPT_PEND_FLAG_CONSUME选项来清除已接收到的事件类型,否则不会清除已接收到的事件,这样就需要用户显式清除事件位。 用户可以自定义通过传入opt选项来选择读取模式,是等待所有感兴趣的事件还是等待感兴趣的任意一个事件。

设置事件时,对指定事件写入指定的事件类型,设置事件集合的对应事件位为1,可以一次同时写多个事件类型,设置事件成功可能会触发任务调度。

清除事件时,根据入参数事件句柄和待清除的事件类型,对事件对应位进行清零操作。

事件不与任务相关联,事件相互独立,一个32位的变量就是事件的集合,用于标识该任务发生的事件类型, 其中每一位表示一种事件类型(0表示该事件类型未发生、1表示该事件类型已经发生),一共32种事件类型具体见图
在这里插入图片描述
事件唤醒机制,当任务因为等待某个或者多个事件发生而进入阻塞态,当事件发生的时候会被唤醒,其过程具体见图
在这里插入图片描述
任务1对事件3或事件5感兴趣(逻辑或),当发生其中的某一个事件都会被唤醒,并且执行相应操作。
而任务2对事件3与事件5感兴趣(逻辑与), 当且仅当事件3与事件5都发生的时候,任务2才会被唤醒,如果只有一个其中一个事件发生,那么任务还是会继续等待事件发生。
如果在接收事件函数中设置了清除事件位选项OS_OPT_PEND_FLAG_CONSUME,那么当任务唤醒后将把事件3和事件5的事件标志清零,否则事件标志将依然存在。

4、事件控制块

理论上用户可以创建任意个事件(仅限制于处理器的 RAM大小)。
通过设置os_cfg.h中的宏定义 OS_CFG_FLAG_EN为 1即可开启事件功能。
事件是一个内核对象,由数据类型OS_FLAG_GRP定义,该数据类型由 os_flag_grp定义(在os.h文件)。

μC/OS的事件由多个元素组成,在事件被创建时,需要由我们自己定义事件(也可以称之为事件句柄)。
因为它是用于保存事件的一些信息的, 其数据结构OS_FLAG_GRP除了事件必须的一些基本信息外,还有PendList链表与一个32位的事件组变量Flags等,为的是方便系统来管理事件。

示意图具体见图
在这里插入图片描述
数据结构具体如下:

struct  os_flag_grp

{
/* ------------------ GENERIC  MEMBERS ------------------ */
    OS_OBJ_TYPE          Type;                      (1)

    CPU_CHAR            *NamePtr;                   (2)

    OS_PEND_LIST         PendList;                  (3)

#if OS_CFG_DBG_EN > 0u
    OS_FLAG_GRP         *DbgPrevPtr;
    OS_FLAG_GRP         *DbgNextPtr;
    CPU_CHAR            *DbgNamePtr;
#endif
/* ------------------ SPECIFIC MEMBERS ------------------ */
    OS_FLAGS             Flags;              (4)

    CPU_TS               TS;                 (5)

};
  • (1):事件的类型,用户无需理会,μC/OS用于识别它是一个事件。
  • (2):事件的名字,每个内核对象都会被分配一个名,采用字符串形式记录下来。
  • (3):因为可以有多个任务同时等待系统中的事件, 所以事件中包含了一个用于控制挂起任务列表的结构体,用于记录阻塞在此事件上的任务。
  • (4):事件中包含了很多标志位, Flags这个变量中保存了当前这些标志位的状态。这个变量可以为8位,16位或32位。
  • (5):事件中的变量TS用于保存该事件最后一次被释放的时间戳。当事件被释放时,读取时基计数值并存放到该变量中。

注意:
用户代码不能直接访问这个结构体,必须通过μC/OS提供的API访问。

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

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

相关文章

【JavaSE】接口 详解(上)

前言 本篇会讲到Java中接口内容,概念和注意点可能比较多,需要耐心多看几遍,我尽可能的使用经典的例子帮助大家理解~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 接口 语法…

YoloV8改进策略:BiFPN+小目标分支实现小目标检测精度的大幅度上升

摘要 这几天有粉丝提到了BiFPN解决小目标问题,我结合我的经验,将BiFPN和小目标分支结合实现小目标任务检测精度的上升。 BiFPN 论文:https://arxiv.org/pdf/1911.09070v2.pdf BiFPN,全称Bi-directional Feature Pyramid Netwo…

leetcode.24. 两两交换链表中的节点

题目 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 思路 创建虚拟头节点,画图,确认步骤。 实现 /*** Definition for singly-li…

阿德勒、荣格、埃里克森、霍妮、弗洛姆、沙利文的新精神分析理论

新精神分析理论,强调自我的自主性及其整合与调节功能,强调文化和社会因素对人格的重大影响。 一、阿德勒的个体心理学 阿德勒,是一个男人努力克服自卑感的优秀样板。阿德勒写了《超越与自卑》。 阿德勒,向意识层面扩展精神分析…

SpringBoot快速入门笔记(4)

文章目录 一、Vue框架1、前端环境准备2、简介3、快速开始4、事件绑定 二、Vue组件化开发1、NPM2、Vue Cli3、组件化开发4、SayHello自定义组件5、Movie自定义组件 一、Vue框架 1、前端环境准备 编码工具:VSCode 依赖管理:NPM 项目构建:VueCl…

【Mathematical Model】基于Python实现随机森林回归算法特征重要性评估线性拟合

前段时间在做遥感的定量反演,所以研究了一下回归算法,由于之前发的几篇博文都是定义好基础方程进行拟合的,不太满足我的需求。所以研究了一下随机森林回归的算法,之前使用随机森林都是做分类,这次做了回归算法也算是补…

Elasticsearch:我们如何演化处理二进制文档格式

作者:来自 Elastic Sean Story 从二进制文件中提取内容是一个常见的用例。一些 PDF 文件可能非常庞大 — 考虑到几 GB 甚至更多。Elastic 在处理此类文档方面已经取得了长足的进步,今天,我们很高兴地介绍我们的新工具 —— 数据提取服务&…

java-权限修饰符、代码块

一、权限修饰符概念 权限修饰符是用来控制一个成员被访问的范围,可以用来修饰成员变量、方法、构造方法、内部类 二、权限修饰符的分类 举例: 1、private 2、空着不写 3、protected 4、public 三、权限修饰符的使用规则 实际开发中,一般使…

SSM框架学习——了解MyBatis

了解MyBatis 什么是MyBatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff…

Linux第4课 Linux的基本操作

文章目录 Linux第4课 Linux的基本操作一、图形界面介绍二、终端界面介绍 Linux第4课 Linux的基本操作 一、图形界面介绍 本节以Ubuntu系统的GUI为例进行说明,Linux其他版本可自行网搜。 图形系统进入后,左侧黄框内为菜单栏,右侧为桌面&…

LeetCode-131. 分割回文串【字符串 动态规划 回溯】

LeetCode-131. 分割回文串【字符串 动态规划 回溯】 题目描述:解题思路一:回溯, 回溯三部曲解题思路二:0解题思路三:0 题目描述: 给你一个字符串 s,请你将 s 分割成一些子串,使每个…

【JSON2WEB】 12基于Amis-admin的动态导航菜单树

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…

Visual Studio安装下载进度为零已解决

因为在安装pytorch3d0.3.0时遇到问题,提示没有cl.exe,VS的C编译组件,可以添加组件也可以重装VS。查了下2019版比2022问题少,选择了安装2019版,下面是下载安装时遇到的问题记录,关于下载进度为零网上有三类解…

Redis-底层数据结构

Redis-底层数据结构 redisObject对象机制对象共享引用计数以及对象的消毁 动态字符串SDS链表链表的优缺点: 压缩链表ziplist的缺点 字典-Dictrehash渐进式rehash 整数集-intSet内存分布图整数集合的升级 跳表 - ZSkipList快表-quicklistlistpack redisObject对象机制 typedef s…

HFSS仿真环形耦合器学习笔记

HFSS仿真环形耦合器学习笔记 文章目录 HFSS仿真环形耦合器学习笔记1、 理论基础2、 设计分析3、 仿真验证1、 求解器设置2、 建模3、 激励方式设置4、 边界条件设置5、 扫频设置6、 设计检查,仿真分析7、 数据后处理 1、 理论基础 环形定向耦合器的结构示意图如图所…

Android 关于apk反编译d2j-dex2jar classes.dex失败的几种方法

目录 确认路径正确直接定位到指定目录确定目录正确,按如下路径修改下面是未找到相关文件正确操作 确认路径正确 ,即d2j-dex2jar和classes.dex是否都在一个文件夹里(大部分的情况都是路径不正确) 直接定位到指定目录 路径正确的…

Linux 安装系统可视化监控工具 Netdata

目录 About 监控工具 NetdataLinux 系统安装 Netdata关于 openEuler1、查看内核信息2、查看主机信息3、查看 dnf 包管理器的版本 Netdata 安装1、更新系统环境相关 rpm 包2、查看 netdata 包信息3、安装 netdata 包4、编辑 netdata.conf 配置5、启动 netdata 服务6、查看 netda…

深入浅出 -- 系统架构之微服务架构常见的六种设计模式

面向服务的架构(SOA) 面向服务的架构(SOA)是一种设计方法,也是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的…

JAVA毕业设计132—基于Java+Springboot+Vue的自习室座位预约小程序管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的自习室座位预约小程序管理系统(源代码数据库)132 一、系统介绍 本项目前后端分离带小程序,分为管理员、用户两种角色 1、用户: 注…

数学与人工智能:共舞于数字时代的奥秘

数学,这一源远流长的学科,长久以来一直为人类社会的发展与进步提供了坚实的基础。与此同时,随着科技的迅猛发展,人工智能这一新兴领域正逐渐改变着我们的生活方式。这两者之间,似乎存在着一种难以言喻的紧密联系。本文…