μC/OS-II---事件标志组管理1(os_flag.c)

目录

    • 事件标志组创建
    • 事件标志组删除
    • 事件标志组获取/等待

在这里插入图片描述

  • 当任务要与多个事件同步时,就要使用事件标志组。
  • 一个事件标志就是一个二值信号,事件标志组是若干二值信号的组合。
  • 使用事件标志组同步任务分为独立性同步和关联性同步。

事件标志组创建

  • flags:事件标志组的初始值。
OS_FLAG_GRP  *OSFlagCreate (OS_FLAGS  flags,
														INT8U    *perr)
{
	OS_FLAG_GRP *pgrp;
#if OS_CRITICAL_METHOD == 3u                        /* Allocate storage for CPU status register        */
	OS_CPU_SR    cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
	
	if (perr == (INT8U *)0)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return ((OS_FLAG_GRP *)0);
	}
	
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
	
	if (OSSafetyCriticalStartFlag == OS_TRUE)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return ((OS_FLAG_GRP *)0);
	}
	
#endif
	
	if (OSIntNesting > 0u)                          /* See if called from ISR ...                      */
	{
		*perr = OS_ERR_CREATE_ISR;                  /* ... can't CREATE from an ISR                    */
		return ((OS_FLAG_GRP *)0);
	}
	
	OS_ENTER_CRITICAL();
	pgrp = OSFlagFreeList;                          /* Get next free event flag                        */
	
	if (pgrp != (OS_FLAG_GRP *)0)                   /* See if we have event flag groups available      */
	{
		/* Adjust free list                                */
		OSFlagFreeList       = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;
		pgrp->OSFlagType     = OS_EVENT_TYPE_FLAG;  /* Set to event flag group type                    */
		pgrp->OSFlagFlags    = flags;               /* Set to desired initial value                    */
		pgrp->OSFlagWaitList = (void *)0;           /* Clear list of tasks waiting on flags            */
#if OS_FLAG_NAME_EN > 0u
		pgrp->OSFlagName     = (INT8U *) (void *)"?";
#endif
		OS_EXIT_CRITICAL();
		*perr                = OS_ERR_NONE;
	}
	
	else
	{
		OS_EXIT_CRITICAL();
		*perr                = OS_ERR_FLAG_GRP_DEPLETED;
	}
	
	return (pgrp);                                  /* Return pointer to event flag group              */
}

事件标志组删除

#if OS_FLAG_DEL_EN > 0u
OS_FLAG_GRP  *OSFlagDel (OS_FLAG_GRP  *pgrp,
												 INT8U         opt,
												 INT8U        *perr)
{
	BOOLEAN       tasks_waiting;
	OS_FLAG_NODE *pnode;
	OS_FLAG_GRP  *pgrp_return;
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
	OS_CPU_SR     cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
	
	if (perr == (INT8U *)0)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return ((OS_FLAG_GRP *)0);
	}
	
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (pgrp == (OS_FLAG_GRP *)0)                          /* Validate 'pgrp'                          */
	{
		*perr = OS_ERR_FLAG_INVALID_PGRP;
		return (pgrp);
	}
	
#endif
	
	if (OSIntNesting > 0u)                                 /* See if called from ISR ...               */
	{
		*perr = OS_ERR_DEL_ISR;                            /* ... can't DELETE from an ISR             */
		return (pgrp);
	}
	
	if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)            /* Validate event group type                */
	{
		*perr = OS_ERR_EVENT_TYPE;
		return (pgrp);
	}
	
	OS_ENTER_CRITICAL();
	
	if (pgrp->OSFlagWaitList != (void *)0)                 /* See if any tasks waiting on event flags  */
	{
		tasks_waiting = OS_TRUE;                           /* Yes                                      */
	}
	
	else
	{
		tasks_waiting = OS_FALSE;                          /* No                                       */
	}
	
	switch (opt)
	{
		case OS_DEL_NO_PEND:                               /* Delete group if no task waiting          */
			if (tasks_waiting == OS_FALSE)
			{
#if OS_FLAG_NAME_EN > 0u
				pgrp->OSFlagName     = (INT8U *) (void *)"?";
#endif
				pgrp->OSFlagType     = OS_EVENT_TYPE_UNUSED;
				pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list           */
				pgrp->OSFlagFlags    = (OS_FLAGS)0;
				OSFlagFreeList       = pgrp;
				OS_EXIT_CRITICAL();
				*perr                = OS_ERR_NONE;
				pgrp_return          = (OS_FLAG_GRP *)0;  /* Event Flag Group has been deleted        */
			}
			
			else
			{
				OS_EXIT_CRITICAL();
				*perr                = OS_ERR_TASK_WAITING;
				pgrp_return          = pgrp;
			}
			
			break;
			
		case OS_DEL_ALWAYS:                                /* Always delete the event flag group       */
			pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
			
			while (pnode != (OS_FLAG_NODE *)0)            /* Ready ALL tasks waiting for flags        */
			{
				(void)OS_FlagTaskRdy (pnode, (OS_FLAGS)0, OS_STAT_PEND_ABORT);
				pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
			}
			
#if OS_FLAG_NAME_EN > 0u
			pgrp->OSFlagName     = (INT8U *) (void *)"?";
#endif
			pgrp->OSFlagType     = OS_EVENT_TYPE_UNUSED;
			pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list                */
			pgrp->OSFlagFlags    = (OS_FLAGS)0;
			OSFlagFreeList       = pgrp;
			OS_EXIT_CRITICAL();
			
			if (tasks_waiting == OS_TRUE)                 /* Reschedule only if task(s) were waiting  */
			{
				OS_Sched();                               /* Find highest priority task ready to run  */
			}
			
			*perr = OS_ERR_NONE;
			pgrp_return          = (OS_FLAG_GRP *)0;      /* Event Flag Group has been deleted        */
			break;
			
		default:
			OS_EXIT_CRITICAL();
			*perr                = OS_ERR_INVALID_OPT;
			pgrp_return          = pgrp;
			break;
	}
	
	return (pgrp_return);
}
#endif

事件标志组获取/等待

OS_FLAGS  OSFlagPend (OS_FLAG_GRP  *pgrp,
											OS_FLAGS      flags,
											INT8U         wait_type,
											INT32U        timeout,
											INT8U        *perr)
{
	OS_FLAG_NODE  node;
	OS_FLAGS      flags_rdy;
	INT8U         result;
	INT8U         pend_stat;
	BOOLEAN       consume;
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
	OS_CPU_SR     cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
	
	if (perr == (INT8U *)0)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return ((OS_FLAGS)0);
	}
	
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (pgrp == (OS_FLAG_GRP *)0)                          /* Validate 'pgrp'                          */
	{
		*perr = OS_ERR_FLAG_INVALID_PGRP;
		return ((OS_FLAGS)0);
	}
	
#endif
	
	if (OSIntNesting > 0u)                                 /* See if called from ISR ...               */
	{
		*perr = OS_ERR_PEND_ISR;                           /* ... can't PEND from an ISR               */
		return ((OS_FLAGS)0);
	}
	
	if (OSLockNesting > 0u)                                /* See if called with scheduler locked ...  */
	{
		*perr = OS_ERR_PEND_LOCKED;                        /* ... can't PEND when locked               */
		return ((OS_FLAGS)0);
	}
	
	if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)            /* Validate event block type                */
	{
		*perr = OS_ERR_EVENT_TYPE;
		return ((OS_FLAGS)0);
	}
	
	result = (INT8U) (wait_type & OS_FLAG_CONSUME);
	
	if (result != (INT8U)0)                                /* See if we need to consume the flags      */
	{
		wait_type &= (INT8U)~ (INT8U)OS_FLAG_CONSUME;
		consume    = OS_TRUE;
	}
	
	else
	{
		consume    = OS_FALSE;
	}
	
	/*$PAGE*/
	OS_ENTER_CRITICAL();
	
	switch (wait_type)
	{
		case OS_FLAG_WAIT_SET_ALL:                         /* See if all required flags are set        */
			flags_rdy = (OS_FLAGS) (pgrp->OSFlagFlags & flags);  /* Extract only the bits we want     */
			
			if (flags_rdy == flags)                       /* Must match ALL the bits that we want     */
			{
				if (consume == OS_TRUE)                   /* See if we need to consume the flags      */
				{
					pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;   /* Clear ONLY the flags we wanted    */
				}
				
				OSTCBCur->OSTCBFlagsRdy = flags_rdy;      /* Save flags that were ready               */
				OS_EXIT_CRITICAL();                       /* Yes, condition met, return to caller     */
				*perr                   = OS_ERR_NONE;
				return (flags_rdy);
			}
			
			else                                          /* Block task until events occur or timeout */
			{
				OS_FlagBlock (pgrp, &node, flags, wait_type, timeout);
				OS_EXIT_CRITICAL();
			}
			
			break;
			
		case OS_FLAG_WAIT_SET_ANY:
			flags_rdy = (OS_FLAGS) (pgrp->OSFlagFlags & flags);   /* Extract only the bits we want    */
			
			if (flags_rdy != (OS_FLAGS)0)                 /* See if any flag set                      */
			{
				if (consume == OS_TRUE)                   /* See if we need to consume the flags      */
				{
					pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;    /* Clear ONLY the flags that we got */
				}
				
				OSTCBCur->OSTCBFlagsRdy = flags_rdy;      /* Save flags that were ready               */
				OS_EXIT_CRITICAL();                       /* Yes, condition met, return to caller     */
				*perr                   = OS_ERR_NONE;
				return (flags_rdy);
			}
			
			else                                          /* Block task until events occur or timeout */
			{
				OS_FlagBlock (pgrp, &node, flags, wait_type, timeout);
				OS_EXIT_CRITICAL();
			}
			
			break;
#if OS_FLAG_WAIT_CLR_EN > 0u
			
		case OS_FLAG_WAIT_CLR_ALL:                         /* See if all required flags are cleared    */
			flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;    /* Extract only the bits we want     */
			
			if (flags_rdy == flags)                       /* Must match ALL the bits that we want     */
			{
				if (consume == OS_TRUE)                   /* See if we need to consume the flags      */
				{
					pgrp->OSFlagFlags |= flags_rdy;       /* Set ONLY the flags that we wanted        */
				}
				
				OSTCBCur->OSTCBFlagsRdy = flags_rdy;      /* Save flags that were ready               */
				OS_EXIT_CRITICAL();                       /* Yes, condition met, return to caller     */
				*perr                   = OS_ERR_NONE;
				return (flags_rdy);
			}
			
			else                                          /* Block task until events occur or timeout */
			{
				OS_FlagBlock (pgrp, &node, flags, wait_type, timeout);
				OS_EXIT_CRITICAL();
			}
			
			break;
			
		case OS_FLAG_WAIT_CLR_ANY:
			flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;   /* Extract only the bits we want      */
			
			if (flags_rdy != (OS_FLAGS)0)                 /* See if any flag cleared                  */
			{
				if (consume == OS_TRUE)                   /* See if we need to consume the flags      */
				{
					pgrp->OSFlagFlags |= flags_rdy;       /* Set ONLY the flags that we got           */
				}
				
				OSTCBCur->OSTCBFlagsRdy = flags_rdy;      /* Save flags that were ready               */
				OS_EXIT_CRITICAL();                       /* Yes, condition met, return to caller     */
				*perr                   = OS_ERR_NONE;
				return (flags_rdy);
			}
			
			else                                          /* Block task until events occur or timeout */
			{
				OS_FlagBlock (pgrp, &node, flags, wait_type, timeout);
				OS_EXIT_CRITICAL();
			}
			
			break;
#endif
			
		default:
			OS_EXIT_CRITICAL();
			flags_rdy = (OS_FLAGS)0;
			*perr      = OS_ERR_FLAG_WAIT_TYPE;
			return (flags_rdy);
	}
	
	/*$PAGE*/
	OS_Sched();                                            /* Find next HPT ready to run               */
	OS_ENTER_CRITICAL();
	
	if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK)        /* Have we timed-out or aborted?            */
	{
		pend_stat                = OSTCBCur->OSTCBStatPend;
		OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
		OS_FlagUnlink (&node);
		OSTCBCur->OSTCBStat      = OS_STAT_RDY;            /* Yes, make task ready-to-run              */
		OS_EXIT_CRITICAL();
		flags_rdy                = (OS_FLAGS)0;
		
		switch (pend_stat)
		{
			case OS_STAT_PEND_ABORT:
				*perr = OS_ERR_PEND_ABORT;                /* Indicate that we aborted   waiting       */
				break;
				
			case OS_STAT_PEND_TO:
			default:
				*perr = OS_ERR_TIMEOUT;                   /* Indicate that we timed-out waiting       */
				break;
		}
		
		return (flags_rdy);
	}
	
	flags_rdy = OSTCBCur->OSTCBFlagsRdy;
	
	if (consume == OS_TRUE)                                /* See if we need to consume the flags      */
	{
		switch (wait_type)
		{
			case OS_FLAG_WAIT_SET_ALL:
			case OS_FLAG_WAIT_SET_ANY:                     /* Clear ONLY the flags we got              */
				pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
				break;
#if OS_FLAG_WAIT_CLR_EN > 0u
				
			case OS_FLAG_WAIT_CLR_ALL:
			case OS_FLAG_WAIT_CLR_ANY:                     /* Set   ONLY the flags we got              */
				pgrp->OSFlagFlags |=  flags_rdy;
				break;
#endif
				
			default:
				OS_EXIT_CRITICAL();
				*perr = OS_ERR_FLAG_WAIT_TYPE;
				return ((OS_FLAGS)0);
		}
	}
	
	OS_EXIT_CRITICAL();
	*perr = OS_ERR_NONE;                                   /* Event(s) must have occurred              */
	return (flags_rdy);
}

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

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

相关文章

振南技术干货集:比萨斜塔要倒了,倾斜传感器快来!(6)

注解目录 1、倾斜传感器的那些基础干货 1.1 典型应用场景 (危楼、边坡、古建筑都是对倾斜敏感的。) 1.2 倾斜传感器的原理 1.2.1 滚珠式倾斜开关 1.2.2 加速度式倾斜传感器 1)直接输出倾角 2)加速度计算倾角 3)倾角精度的提高 (如果…

MySQL的执行器是怎么工作的

作为优化器后的真正执行语句的层,执行器有三种方式和存储引擎(一般是innoDB)交互 主键索引查询 查询的条件用到了主键,这个是全表唯一的,优化器会选择const类型来查询,然后while循环去根据主键索引的B树结…

Struts2 数据校验之四兄弟

现在是科技的时代,大多数人都在网上购物了, 我们都碰到过相同的问题,各大网站弄的那些各种各样的注册页面,相信大家都深有体会。 有了这验证就很好的保证了我们的信息的准确性和安全性。 接下来我给大家讲解一下用struts2怎么实…

【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解

文章目录 1. 前言2. JoinPoint简介3. 获取被增强方法的相关信息4. ProceedingJoinPoint简介5. 获取环绕通知方法的相关信息6. 总结 1. 前言 在Spring AOP中,JoinPoint和ProceedingJoinPoint都是关键的接口,用于在切面中获取方法的相关信息以及控制方法的…

ai的潜力和中短期的未来预测

内容来源:rickawsb ​对于描述ai的潜力和中短期的未来预测,我认为到目前为止可能没有比这篇推文总结得更好的了。 我读了三次。 文章起源于一个用户感叹openai升级chatgpt后,支持pdf上传功能,直接让不少的靠这个功能吃饭的创业公…

实力进阶,教你使用thinkphp6开发一款商城系统

0.开篇 你好!很高兴你能点开这个教程,相信你对这个教程有了那么一点点兴趣,接下来占用你一点点时间,邀你浏览一下本章内容,希望能够让你更加有兴趣去学完这个教程。 作者我是一名九零后程序员,搬砖了好几…

【Linux网络】从原理到实操,感受PXE无人值守自动化高效批量网络安装系统

一、PXE网络批量装机的介绍 1、常见的三种系统安装方式 2、回顾系统安装的过程,了解系统安装的必要条件 3、什么是pxe 4、搭建pxe的原理 5、Linux的光盘镜像中的isolinux中的相关文件学习 二、关于实现PXE无人值守装机的四大文件与五个软件的对应关系详解 5个…

OpenCV图像处理、计算机视觉实战应用

OpenCV图像处理、计算机视觉实战应用 专栏简介一、基于差异模型模板匹配缺陷检测二、基于NCC多角度多目标匹配三、基于zxing多二维码识别四、基于tesseract OCR字符识别 专栏简介 基于OpenCV C分享一些图像处理、计算机视觉实战项目。不定期持续更新,干货满满&…

vulnhub靶机Momentum

下载地址:https://download.vulnhub.com/momentum/Momentum.ova 主机发现 目标192.168.21.129 端口扫描 端口版本扫描 漏洞扫描 扫出来点目录简单看看 发现js里面有一点东西 这里面告诉了我们了web文件有id传值,而且有aes加密还有密钥 跟二没有啥区别&…

庖丁解牛:NIO核心概念与机制详解

文章目录 Pre输入/输出Why NIO流与块的比较通道和缓冲区概述什么是缓冲区?缓冲区类型什么是通道?通道类型 NIO 中的读和写概述Demo : 从文件中读取1. 从FileInputStream中获取Channel2. 创建ByteBuffer缓冲区3. 将数据从Channle读取到Buffer中 Demo : 写…

Redis维护缓存的方案选择

Redis中间件常常被用作缓存,而当使用了缓存的时候,缓存中数据的维护,往往是需要重点关注的,尤其是重点考虑的是数据一致性问题。以下是维护数据库缓存的一些常用方案。 1、先删除缓存,再更新数据库 导致数据不一致的…

LLM大模型4位量化实战【GPTQ】

权重量化方面的最新进展使我们能够在消费类硬件上运行大量大型语言模型,例如 RTX 3090 GPU 上的 LLaMA-30B 模型。 这要归功于性能下降最小的新型 4 位量化技术,例如 GPTQ、GGML 和 NF4。 在上一篇文章中,我们介绍了简单的 8 位量化技术和出…

算法通关村第十关-青铜挑战快速排序

大家好我是苏麟,今天带来快速排序 . 快速排序 单边快速排序(lomuto 洛穆托分区方案) 单边循环 (lomuto分区) 要点 : 选择最右侧元素作为基准点j 找比基准点小的,i 找比基准点大的,一旦找到,二者进行交换。 交换时机: 找到小的&#xff0c…

魔术《4 Kings 折纸》的三重境界(四)——魔术效果的突破

‍ ‍早点关注我,精彩不错过! 在前三篇文章里,我们解释清楚了分别基于奇偶性,集合和群论来解释《4 Kings 折纸》这个魔术的过程,详情请戳: 魔术《4 Kings 折纸》的三重境界(三)——群…

【限时免费】20天拿下华为OD笔试之 【前缀和】2023B-最大子矩阵和【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录 题目描述与示例题目描述输入描述输出描述示例输入输出说明 解题思路如何表示一个子矩阵暴力解法二维前缀和优化二维前缀和矩阵的构建 代码解法一:二维前缀和PythonJavaC时空复杂度 解法二:暴力解法(不推荐)PythonJavaC时…

Springboot 项目启动类放置位置

文章目录 Springboot 项目启动类放置位置springboot 默认包扫描机制启动类放在特定位置springboot 启动注解理解配置启动类扫描特定的包1、 ComponentScan2、利用 SpringBootApplication 注解的 scanBasePackages 属性 Springboot 项目启动类放置位置 如果我们使用 IDEA 或者 …

常见面试题-MySQL的Explain执行计划

了解 Explain 执行计划吗? 答: explain 语句可以帮助我们查看查询语句的具体执行计划。 explain 查出来的各列含义如下: id:在一个大的查询语句中,每个 select 关键字都对应一个唯一的 id select_type:…

jdk1.8配置tomcat9教程

文章目录 前言报错&尝试解决运行 前言 最近在学习SpringMVC框架,但是里面需要用到Tocmat服务器。作为0基础Java选手,直接找了个视频里面的tomcat包下载。 里面的版本是apache-tomcat-8.5.68-windows-x64.zip的,然后就开始疯狂的各种博客…

巧用SqlServer数据库实现邮件自动发送功能

使用数据库发送邮件需要三个步骤,配置数据库的邮件服务、编写存储过程、设置SQL作业,接下来开始逐步分享: 配置数据库邮件: 在SqlServer左侧菜单栏中,找到管理页签中数据库邮件选项: 接下来开始配置数据库…

wpf devexpress自定义编辑器

打开前一个例子 步骤1-自定义FirstName和LastName编辑器字段 如果运行程序,会通知编辑器是空。对于例子,这两个未命名编辑器在第一个LayoutItem(Name)。和最终用户有一个访客左右编辑器查阅到First Name和Last Name字段,分别。如果你看到Go…