OS_FLAG.C(1)
本篇介绍OS_FLAG.C中的检测事件标志组的标志状态函数
OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp,OS_FLAGS flags,INT8U wait_type,INT8U *perr)检测事件标志组的标志状态函数:
- 介绍一下wait_type:
在最后的代码中也有相关介绍,为了更好理解,下面具体解释一下:
wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bitsto be set/cleared.
* You can specify the following argument:
* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0)
* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0)
* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1)
* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1)
*--wait_type:定义等待事件标志位的方式.有以下四种参数选择:
OS_FLAG_WAIT_CLR_ALL:所有指定事件标志位清 (0);
OS_FLAG_WAIT_CLR_ANY:任意指定事件标志位清 (0);
OS_FLAG_WAIT_SET_ALL:所有指定事件标志位置 (1);
OS_FLAG_WAIT_SET_ANY:任意指定事件标志位置 (1)。
*注释:如果需要在得到期望的事件标志后,清除该事件标志,则可以在调用函数时,
将该参数加上一个常量OS_FLAG_CONSUME。例如,如果等待事件标志组中任意指定事件标志位置位,
并且在任意事件标志位置位后清除该位,则把参数wait_type设置为:OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME。
所谓的消耗与否,就是事件组满足条件后(获得事件标志组后),事件标志组控制块的对应事件标志是否清除,如果清除,就称为消耗掉,如果不清除,就成为不消耗。
代码中具体体现为:
result = (INT8U)(wait_type & OS_FLAG_CONSUME); /*将wiat_type与OS_FLAG_COUNSUME进行与,结果存放在result中*/if (result != (INT8U)0) /*判断我们是否需要清除标志。*/{ wait_type &= ~OS_FLAG_CONSUME; /*不为0,消耗型,需要清除,wait_type保存其取反之后的值*/consume = OS_TRUE; /*"清除"事件标志位置1,需要对这个标志清0*/} else /*result为0,非消耗型。不需要清除*/{consume = OS_FALSE; /*"清除"事件标志位为0*/}
将wiat_type与OS_FLAG_COUNSUME进行逻辑与运算,结果存放在result中。若是rusult为0,则说明wait_type是没有加上OS_FLAG_CONSUME的,也就是非消耗类型的,否则就是消耗类型的。
- 该函数中第二个需要解释的点:
case OS_FLAG_WAIT_SET_ALL: /*等待选择的所有位都置1,即所有指定事件标志位清 (0)*/flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /*提取我们需要的位*/if (flags_rdy == flags) /*必须匹配到我们需要的所有的位*/{ if (consume == OS_TRUE) /*如果是消耗型的*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*将请求事件组中对应请求标志位的位清零,消耗了事件*/}}
以这个小片段为例,里面有一个与运算:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /*提取我们需要的位*/
解释一下我们是如何提取我们需要的位呢?这行语句为什么进行与运算?
0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |
1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
OSFlagFlags和flags都是8位。假定各自8位分别如上图设置。当我们提取位的时候,就一一对应,进行逻辑与操作,并赋给flags_rdy:
0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
然后再将flags_rdy与flags的每位进行比较(针对OS_FLAG_WAIT_SET_ALL情况):
if (flags_rdy == flags) /*必须匹配到我们需要的所有的位*/
上述例子可以看到二者是不一样的。所以这个等式不成立,就没有匹配到我们需要的所有的位,就执行相应的操作。
如果是OS_FLAG_WAIT_SET_ANY等待类型,进行完与操作之后,
if (flags_rdy != (OS_FLAGS)0) /*看是否有任何设置为1的标志*/
是将flags_rdy与0进行比较。然后执行相关操作。
- 第三个需要提醒的点:
if (consume == OS_TRUE) /*如果是消耗型的*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*将请求事件组中对应请求标志位的位清零,消耗了事件*/}
如果是消耗型的,在清除的时候,我们只清除了之前用到的位,并不是所有位都清除了。这点需要注意一下。
下面是该函数的源代码:
/*$PAGE*/
/*
*********************************************************************************************************
* CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP
* 检测事件标志组的标志状态
* Description: This function is called to check the status of a combination of bits to be set or cleared
* in an event flag group. Your application can check for ANY bit to be set/cleared or ALL
* bits to be set/cleared.This call does not block if the desired flags are not present.
*描述:这个功能用来检查位的组合状态,来确定事件标志组中的事件标志位是置位还是清0。你的应用程序可以检查任意一位是置位还是清0,也可以检查所有位是置位还是清0。
* 这个调用不会被阻塞如果需要的事件标志没有产生。这点与于OSFlagPend()不同。
* Arguments : pgrp is a pointer to the desired event flag group.
*参数: --pgrp:指向事件标志组的指针
* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
* The bits you want are specified by setting the corresponding bits in
* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
* 'flags' would contain 0x03.
* --flags:指定需要检查的事件标志位。为1则检查对应位;为0则忽若对应位。flags是事件组合的标志,是位掩码,表示事件要等待哪些位。如果应用程序等待任务组中事件标志中的0和2,掩码为0x05。
* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits
* to be set/cleared.
* You can specify the following argument:
* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0)
* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0)
* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1)
* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1)
* --wait_type:定义等待事件标志位的方式.有以下四种参数选择:OS_FLAG_WAIT_CLR_ALL:所有指定事件标志位清 (0);OS_FLAG_WAIT_CLR_ANY:任意指定事件标志位清 (0);OS_FLAG_WAIT_SET_ALL:所有指定事件标志位置 (1);OS_FLAG_WAIT_SET_ANY:任意指定事件标志位置 (1)。
* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by
* the call. Example, to wait for any flag in a group AND then clear
* the flags that are present, set 'wait_type' to:
* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME
* 注释:如果需要在得到期望的事件标志后,清除该事件标志,则可以在调用函数时,将该参数加上一个常量OS_FLAG_CONSUME。例如,如果等待事件标志组中任意指定事件标志位置位,并且在任意事件标志位置位后清除该位,则把参数wait_type设置为:OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME所谓的消耗与否,就是事件组满足条件后,获得事件标志组后。事件标志组控制块的对应事件标志清除,即消耗掉。
* perr is a pointer to an error code and can be:
* OS_ERR_NONE No error
* OS_ERR_EVENT_TYPE You are not pointing to an event flag group
* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument.
* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag
* group handle.
* OS_ERR_FLAG_NOT_RDY The desired flags you are waiting for are not
* available.
* --perr:是一个指向错误码的指针,可以是一下几种:OS_ERR_NONE:无错误OS_ERR_EVENT_TYPE:指针未指向事件标志组错OS_ERR_FLAG_WAIT_TYPE:参数wait_type不是指定的四个方式之一。OS_ERR_FLAG_INVALID_PGRP:pgrp为空指针OS_ERR_FLAG_NOT_RDY:指定的事件标志没有发生。
* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error
* occurred.
*返回值:返回事件标志组的事件标志。如果是超时或者有错误发生,返回0
* Called from: Task or ISR
*调用:从任务或者中断调用
* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The
* function NOW returns the flags that were ready INSTEAD of the current state of the
* event flags.注释:1)重点:该功能和之前版本的不同,现在版本的该功能返回的是就绪的标志,而不是当前事件的状态
*********************************************************************************************************
*/#if OS_FLAG_ACCEPT_EN > 0u
OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp,OS_FLAGS flags,INT8U wait_type,INT8U *perr)
{OS_FLAGS flags_rdy; /*定义一个"准备完毕"含量值*/INT8U result; /*结果*/BOOLEAN consume; /*定义一个"清除"事件标志位(保存值)*/#if OS_CRITICAL_METHOD == 3u /*中断被设置为类型3*/OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICAL /*如果定义了安全性中断*/if (perr == (INT8U *)0) /*如果错误码指针为空,调用安全中断异常函数*/{OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0u /*进行参数检查*//*有效化pgrp指针*/if (pgrp == (OS_FLAG_GRP *)0) /*如果pgrp指针为空*/{ *perr = OS_ERR_FLAG_INVALID_PGRP; /*将错误码指针设置为OS_ERR_FLAG_INVALID_PGRP*/return ((OS_FLAGS)0); /*返回0*/}#endifif (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) /*有效化事件控制块类型 如果不是事件类型标志*/{ *perr = OS_ERR_EVENT_TYPE; /*将错误码指针设置为OS_ERR_EVENT_TYPE*/return ((OS_FLAGS)0); /*返回0*/}result = (INT8U)(wait_type & OS_FLAG_CONSUME); /*将wiat_type与OS_FLAG_COUNSUME进行与,结果存放在result中*/if (result != (INT8U)0) /*判断我们是否需要清除标志。*/{ wait_type &= ~OS_FLAG_CONSUME; /*不为0,需要清除,wait_type保存其取反之后的值*/consume = OS_TRUE; /*"清除"事件标志位置1,需要对这个标志清0*/} else /*result为0,不需要清除*/{consume = OS_FALSE; /*"清除"事件标志位为0*/}/*$PAGE*/*perr = OS_ERR_NONE; /*先将错误码指针设置为无错误形式*/OS_ENTER_CRITICAL(); /*关中断(进入中断)*/switch (wait_type) /*判断等待类型,根据类型不同,处理相应的代码*/{case OS_FLAG_WAIT_SET_ALL: /*等待选择的所有位都置1,即所有指定事件标志位清 (1)*/flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /*提取我们需要的位*/if (flags_rdy == flags) /*必须匹配到我们需要的所有的位*/{ if (consume == OS_TRUE) /*如果是消耗型的*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*将请求事件组中对应请求标志位的位清零,消耗了事件*/}}else /*没有匹配到我们需要的所有的位,阻塞,等待事件标志组完成或者是超时*/{*perr = OS_ERR_FLAG_NOT_RDY;/*将错误码设置为标志位位准备好类型*/}OS_EXIT_CRITICAL(); /*开中断*/break;case OS_FLAG_WAIT_SET_ANY: /*如果等待类型为任意指定事件标志位清(1)*/flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); if (flags_rdy != (OS_FLAGS)0) /*看是否有任何设置为1的标志*/{ if (consume == OS_TRUE) /*如果是消耗类型*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*只清除我们需要的位*/}}else{*perr = OS_ERR_FLAG_NOT_RDY; /*将错误类型设置为OS_ERR_FLAG_NOT_RDY*/}OS_EXIT_CRITICAL(); /*开中断*/break;#if OS_FLAG_WAIT_CLR_EN > 0u /*允许生成 Wait on Clear 事件标志代码*/case OS_FLAG_WAIT_CLR_ALL: /* 等待类型为所有指定事件标志位清 (0); */flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /*只提取我们需要的位 */if (flags_rdy == flags) { if (consume == OS_TRUE) { pgrp->OSFlagFlags |= flags_rdy; }} else {*perr = OS_ERR_FLAG_NOT_RDY;}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 */}} else {*perr = OS_ERR_FLAG_NOT_RDY;}OS_EXIT_CRITICAL();break;
#endifdefault: /*默认情况下*/OS_EXIT_CRITICAL();/*开中断(退出中断)*/flags_rdy = (OS_FLAGS)0;/*将flags_rdy设置为0*/*perr = OS_ERR_FLAG_WAIT_TYPE;/*错误码设置为OS_ERR_FLAG_WAIT_TYPE*/break;}return (flags_rdy);/*返回flags_rdy*/
}
#endif
大概流程图为:
END
不足之处还望提醒,谢过~
OS_FLAG.C(1)相关推荐
- OS_FLAG.C(3)
上篇我们介绍了创建和删除事件标志组函数,后来在接着看源代码的时候,发现倒着来更有助于理解.所以后面几篇我会选择较为合适的方式来不定期更博,方便大家理解. 1.介绍删除节点函数OS_FlagUnlink ...
- OS_FLAG.C(2)
本篇介绍OS_FLAG.C文件中的创建事件标志组函数*OSFlagCreate (OS_FLAGS flags,INT8U *perr)和删除事件标志组函数 *OSFlagDel (OS_FLAG_ ...
- OpenAPI使用(swagger3),Kotlin使用swagger3,Java使用swagger3,gradle、Maven使用swagger3
OpenAPI使用(swagger3) demo见Gitte 一.背景及名词解释 OpenAPI是规范的正式名称.规范的开发工作于2015年启动,当时SmartBear(负责Swagger工具开发的公 ...
- 2022-2028年中国第五代移动通信技术(5G)市场研究及前瞻分析报告
[报告类型]产业研究 [报告价格]4500起 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了中国第五代移动通信技术(5G)行业市场行业相 ...
- 2021-2027全球与中国经颅磁刺激仪(TMS)市场现状及未来发展趋势
[报告类型]产业研究 [报告价格]¥4500起 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了全球与中国经颅磁刺激仪(TMS)行业市场行 ...
- Go 学习笔记(84)— Go 项目目录结构
1. 目录规范 一个好的目录结构至少要满足以下几个要求. 命名清晰:目录命名要清晰.简洁,不要太长,也不要太短,目录名要能清晰地表达出该目录实现的功能,并且目录名最好用单数.一方面是因为单数足以说明这 ...
- Redis 笔记(16)— info 指令和命令行工具(查看内存、状态、客户端连接数、监控服务器、扫描大key、采样服务器、执行批量命令等)
Info 命令返回关于 Redis 服务器的各种信息和统计数值.通过给定可选的参数 section ,可以让命令只返回某一部分的信息. 1. 显示模块 server : 一般 Redis 服务器信息, ...
- Redis 笔记(12)— 单线程架构(非阻塞 IO、多路复用)和多个异步线程
Redis 使用了单线程架构.非阻塞 I/O .多路复用模型来实现高性能的内存数据库服务.Redis 是单线程的.那么为什么说是单线程呢? Redis 在 Reactor 模型内开发了事件处理器,这个 ...
- Redis 笔记(10)— 发布订阅模式(发布订阅单个信道、订阅信道后的返回值分类、发布订阅多个信道)
1. 发布-订阅概念 发布-订阅 模式包含两种角色,分别为发布者和订阅者. 订阅者可以订阅一个或者若干个频道(channel): 而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都可以收到此消 ...
最新文章
- 【 全干货 】5 分钟带你看懂 Docker !
- 毕业就拿阿里offer,你和他比差在哪?
- Nginx源码分析(3)
- Big Sur:加州一号公路和比克斯比大桥
- Boost:bind绑定boost::apply的测试程序
- Qtum量子链帅初受邀火星特训营面对面授课
- CPU是如何处理指令的
- intellij idea 12 搭建maven web项目 freemarker + spring mvc
- ubuntu16.04 安装python3.6
- .NET后台如何获取前台HMTL控件的值
- 简单web服务器的实现(C++)
- 著名的十大经济学效应
- Pytorch——报错解决:匈牙利匹配
- excel表格公式出现#REF是什么意思
- 中国移动通信互联网短信网关接口协议及相关下载
- 百度之星Valley Numer
- Multisim14安装报错fatal error!Required NIPathsDir property NISHAREDDIR is undefined.
- 卷土重来的FCoin日本站,你被割了吗?
- facebooks项目aria是您一生的Google地图
- 在ORCAD原理图中怎么去指定器件的封装呢?