UCOSIII事件标志组详解

UCOSIII中的事件标志组是一种用于任务同步和事件管理的机制,它允许任务和中断服务例程(ISR)发布事件标志,并允许任务等待这些事件标志的发生。以下是对UCOSIII事件标志组的详细介绍:

1. 定义与创建

  • 定义:在UCOSIII中,事件标志组是OS_FLAG_GRP类型的内核对象,用于管理一串事件标志位。
  • 创建:在使用事件标志组之前,需要调用OSFlagCreate()函数来创建一个事件标志组。这个函数需要指定事件标志组的名称、初始值以及一个用于保存错误码的参数。
void  OSFlagCreate (OS_FLAG_GRP  *p_grp,
                    CPU_CHAR     *p_name,
                    OS_FLAGS      flags,
                    OS_ERR       *p_err)

p_grp:事件标志组对象

p_name:事件标志组的名字

flags:事件标志组里所有标志位的初值,默认写0

p_err:返回错误码,没有错误的就返回OS_ERR_NONE

2. 同步机制

事件标志组与任务之间有两种同步机制:

  • “或”同步:当等待多个事件时,只要任何一个事件发生,任务就会被同步。
  • “与”同步:当所有的事件都发生时,任务才会被同步。

3. 等待事件标志组

  • 等待函数OSFlagPend()函数用于等待一个或多个事件标志位的发生。这个函数可以指定要等待的标志位、超时时间以及等待条件等参数。
  • 等待条件:可以通过OS_OPT参数指定等待条件,如等待任意一个标志位、等待所有标志位、非阻塞等待等。
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:要等待哪些标志位;0x01,则等待bit0;0x05,则等待bit0和bit2;0x83,则等待bit0、bit1、bit7。

timeout:超时时间,默认写0,一直等待

opt:默认是以下格式

OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME+OS_OPT_PEND_BLOCKING

OS_OPT_PEND_FLAG_CLR_ALL:等待事件标志组所有的位清零;

OS_OPT_PEND_FLAG_CLR_ANY:等待事件标志组中任意一个标志清零;

OS_OPT_PEND_FLAG_SET_ALL:等待事件标志组中所有的位置位;

OS_OPT_PEND_FLAG_SET_ANY:等待事件标志组中任意一个标志置位。

调用上面四个选项的时候还可以搭配下面三个选项:

OS_OPT_PEND_FLAG_CONSUME:用来设置是否继续保留该事件标志的状态;

OS_OPT_PEND_NON_BLOCKING:标志组不满足条件时不挂起任务;

OS_OPT_PEND_BLOCKING:标志组不满足条件时挂起任务。

p_ts: 用于记录等待事件花了多长时间,默认写NULL,不记录。

p_err: 返回错误码,没有错误的就返回OS_ERR_NONE。

4. 发布事件标志

  • 发布函数OSFlagPost()函数用于发布事件标志,可以指定要置位或清零的标志位。
  • 发布者:任务和ISR都可以发布事件标志,但只有任务可以创建事件标志组、删除事件标志组以及取消其他任务对事件标志组的等待。
OS_FLAGS  OSFlagPost (OS_FLAG_GRP  *p_grp,
                      OS_FLAGS      flags,
                      OS_OPT        opt,
                      OS_ERR       *p_err)

p_grp:事件标志组对象

flags: 结合opt参数一起使用。设置/清零哪些标志位,0x01,则对应bit0;0x05,则对应bit0和bit2;0x83,则对应bit0、bit1、bit7。

opt: OS_OPT_POST_FLAG_SET,对应的bit置位   ,OS_OPT_POST_FLAG_CLR,对应的bit清零.

p_err: 返回错误码,没有错误的就返回OS_ERR_NONE。

5.注意事项

  • 在使用事件标志组时,需要确保已经通过OS_CFG_FLAG_EN宏启用了事件标志组功能。
  • 在设计任务同步逻辑时,应仔细考虑选择“或”同步还是“与”同步机制。
  • 在发布事件标志时,应注意避免不必要的重复发布和潜在的竞争条件。
  • 在使用事件标志组进行任务同步时,应确保任务间的依赖关系和同步逻辑清晰明确,以避免死锁或竞态条件等问题。

6. 使用场景

事件标志组常用于需要同步多个任务或等待多个事件发生的场景。例如,在一个嵌入式系统中,可能需要等待多个按键被按下才能执行某个任务,这时就可以使用事件标志组来实现。我们在前后台系统中一般都是自己定义全局变量标志,然后循环判断,浪费CPU资源,不能合理的调度,UCOSIII的事件标志组很好的解决了这个问题

7.代码实现

7.1创建标志组

#define KEYFLAGS_VALUE	0X00						
OS_FLAG_GRP	EventFlags;		//定义一个事件标志组
    //创建一个事件标志组
	OSFlagCreate((OS_FLAG_GRP*)&EventFlags,		//指向事件标志组
                 (CPU_CHAR*	  )"Event Flags",	//名字
                 (OS_FLAGS	  )KEYFLAGS_VALUE,	//事件标志组初始值
                 (OS_ERR*  	  )&err);			//错误码

7.2发送标志组

#define KEY0_FLAG		0x01
#define KEY1_FLAG		0x02
flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
								 (OS_FLAGS	  )KEY0_FLAG,
								 (OS_OPT	  )OS_OPT_POST_FLAG_SET,
					             (OS_ERR*	  )&err);

flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
								 (OS_FLAGS	  )KEY1_FLAG,
								 (OS_OPT	  )OS_OPT_POST_FLAG_SET,
								 (OS_ERR*     )&err);

7.3等待标志组 

	//等待事件标志组
		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);

注意:有的朋友可能对flags和opt这两个参数不太理解,比如在flags等于0x03的时候,相当于使用了标志组的bit0和bit1,但是此时如果opt设置了 OS_OPT_PEND_FLAG_SET_ANY,等待任意一个标志位置位,会不会两个参数存在冲突,就是只等待任意一个标志位,加起来到不了0x03。其实falgs的这个参数只是定义了任务对哪些事件标志位感兴趣,并不是所有置1的标志位相加是0x03才会同步,刚接触这里可能会被例子里面写的赋值KEY0_FLAG+KEY1_FLAG搞蒙掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千千道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值