UCOSIII事件标志组

事件标志组

事件标志组是进行任务同步的另外一种方法,事件标志组是为了解决一个任务与多个事件的同步。

或同步、与同步

按照“与”和“或”的逻辑,当任何一个事件发生都会进行任务同步的机制叫做“或”同步,当所有时间发生才会同步的机制叫做“与”同步

API函数

UCOSIII中的事件标志组为:OS_FLAG_GRP,定义在os.h中:

typedef  struct  os_flag_grp         OS_FLAG_GRP;

struct os_flag_grp内容如下:

struct  os_flag_grp {                                       /* Event Flag Group                                       */
                                                            /* ------------------ GENERIC  MEMBERS ------------------ */
    OS_OBJ_TYPE          Type;                              /* Should be set to OS_OBJ_TYPE_FLAG                      */
    CPU_CHAR            *NamePtr;                           /* Pointer to Event Flag Name (NUL terminated ASCII)      */
    OS_PEND_LIST         PendList;                          /* List of tasks waiting on event flag group              */
#if OS_CFG_DBG_EN > 0u
    OS_FLAG_GRP         *DbgPrevPtr;
    OS_FLAG_GRP         *DbgNextPtr;
    CPU_CHAR            *DbgNamePtr;
#endif
                                                            /* ------------------ SPECIFIC MEMBERS ------------------ */
    OS_FLAGS             Flags;                             /* 8, 16 or 32 bit flags                                  */
    CPU_TS               TS;                                /* Timestamp of when last post occurred                   */
};
OSFlagCreate()

OSFlagCreate()即为创建事件标志组函数:

void  OSFlagCreate (OS_FLAG_GRP  *p_grp,
                    CPU_CHAR     *p_name,
                    OS_FLAGS      flags,
                    OS_ERR       *p_err)

参数:
*p_grp:创建的事件标志组
*p_name:事件标志组的名字,就是字符串
flags:事件标志组的初始值
*p_err:用于保存错误

OSFlagPend()

等待事件标志组函数:

OS_FLAGS  OSFlagPend (OS_FLAG_GRP  *p_grp,
                      OS_FLAGS      flags,
                      OS_TICK       timeout,
                      OS_OPT        opt,
                      CPU_TS       *p_ts,
                      OS_ERR       *p_err)

参数:
*p_grp:等待的事件标志组
flags:等待的事件标志组序列位,类似寄存器的位。
timeout:等待超时时间,设置0表示一直等待直到发生标志置位。
opt:选项,
*p_ts:时间戳,设置NULL则不使用。
*p_err:用于保存错误

opt是这个函数的重要参数,可以选择如下选项进行搭配:

#define  OS_OPT_PEND_FLAG_MASK               (OS_OPT)(0x000Fu)
#define  OS_OPT_PEND_FLAG_CLR_ALL            (OS_OPT)(0x0001u)  /* Wait for ALL    the bits specified to be CLR       */
#define  OS_OPT_PEND_FLAG_CLR_AND            (OS_OPT)(0x0001u)

#define  OS_OPT_PEND_FLAG_CLR_ANY            (OS_OPT)(0x0002u)  /* Wait for ANY of the bits specified to be CLR       */
#define  OS_OPT_PEND_FLAG_CLR_OR             (OS_OPT)(0x0002u)

#define  OS_OPT_PEND_FLAG_SET_ALL            (OS_OPT)(0x0004u)  /* Wait for ALL    the bits specified to be SET       */
#define  OS_OPT_PEND_FLAG_SET_AND            (OS_OPT)(0x0004u)

#define  OS_OPT_PEND_FLAG_SET_ANY            (OS_OPT)(0x0008u)  /* Wait for ANY of the bits specified to be SET       */
#define  OS_OPT_PEND_FLAG_SET_OR             (OS_OPT)(0x0008u)

#define  OS_OPT_PEND_FLAG_CONSUME            (OS_OPT)(0x0100u)  /* Consume the flags if condition(s) satisfied        */

#define  OS_OPT_PEND_BLOCKING                (OS_OPT)(0x0000u)
#define  OS_OPT_PEND_NON_BLOCKING            (OS_OPT)(0x8000u)

与同步和或同步就是在这里通过选项进行设置的,opt分为:
1)等待所有的标志位清除:

#define  OS_OPT_PEND_FLAG_CLR_ALL            (OS_OPT)(0x0001u)  /* Wait for ALL    the bits specified to be CLR       */
#define  OS_OPT_PEND_FLAG_CLR_AND            (OS_OPT)(0x0001u)

2)等待任意标志位清除

#define  OS_OPT_PEND_FLAG_CLR_ANY            (OS_OPT)(0x0002u)  /* Wait for ANY of the bits specified to be CLR       */
#define  OS_OPT_PEND_FLAG_CLR_OR             (OS_OPT)(0x0002u)

3)等待所有标志位置位

#define  OS_OPT_PEND_FLAG_SET_ALL            (OS_OPT)(0x0004u)  /* Wait for ALL    the bits specified to be SET       */
#define  OS_OPT_PEND_FLAG_SET_AND            (OS_OPT)(0x0004u)

4)等待任意标志位置位

#define  OS_OPT_PEND_FLAG_SET_ANY            (OS_OPT)(0x0008u)  /* Wait for ANY of the bits specified to be SET       */
#define  OS_OPT_PEND_FLAG_SET_OR             (OS_OPT)(0x0008u)

上面提到的8个选项两两一组,每组的2个选项宏定义的值其实是一样的,使用名字含有AND和ALL的就是与同步机制,含有OR和ANY的就是或同步机制。

一般上面四种选项还会搭配下面三个选项进行使用:

#define  OS_OPT_PEND_FLAG_CONSUME            (OS_OPT)(0x0100u)  /* Consume the flags if condition(s) satisfied        */
#define  OS_OPT_PEND_BLOCKING                (OS_OPT)(0x0000u)
#define  OS_OPT_PEND_NON_BLOCKING            (OS_OPT)(0x8000u)

OS_OPT_PEND_FLAG_CONSUME的意思是请求到事件组的标志位后即清除相应标志位,这样做其实是为了下次请求时可以使用该标志位。
OS_OPT_PEND_BLOCKINGOS_OPT_PEND_NON_BLOCKING就是选择是否进行挂起当前任务等待事件标志组标志位。

OSFlagPend()使用示例:

		OSFlagPend((OS_FLAG_GRP*)&EventFlags,
				   (OS_FLAGS	)KEY0_FLAG+KEY1_FLAG,
		     	   (OS_TICK     )0,
				   (OS_OPT	    )OS_OPT_PEND_FLAG_SET_ALL+OS_OPT_PEND_FLAG_CONSUME,
				   (CPU_TS*     )0,
				   (OS_ERR*	    )&err);

其中
#define KEY0_FLAG 0x01
#define KEY1_FLAG 0x02
即请求bit0和bit1都置1,请求到标志位后会进行清除。

OSFlagPost()

此函数发布事件标志组的标志位,即对事件标志组的相应位进行操作的函数,通过opt选项进行设置,可以对标志位置1或者清0。

OS_FLAGS  OSFlagPost (OS_FLAG_GRP  *p_grp,
                      OS_FLAGS      flags,
                      OS_OPT        opt,
                      OS_ERR       *p_err)

参数:
*p_grp:要发布的事件标志组
flags:等待的事件标志组序列位,类似寄存器的位。
opt:有如下两个选择:

#define  OS_OPT_POST_FLAG_SET                (OS_OPT)(0x0000u)
#define  OS_OPT_POST_FLAG_CLR                (OS_OPT)(0x0001u)

OS_OPT_POST_FLAG_SET 为置位标志位,置1
OS_OPT_POST_FLAG_CLR 为清除标志位,置0

*p_err:用于保存错误

还有三个API没有列出:
在这里插入图片描述
上面的这些函数中,只有OSFlagPost()可以在ISR中断服务函数中使用,也就是说在中断中只能发布事件标志组,类似于消息队列。

总结:

使用事件标志组是为了解决多个事件与任务的同步问题,满足所有的标志位置位时才可以请求到事件标志组就可以很好的说明这个问题。事件标志组不像消息队列,消息队列更多的是进行一些数据的交互、任务间信息的传递。感觉更像多个信号量组成的内核对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值