个人笔记--FreeRTOS事件标志组

FreeRTOS事件标志组

简介
事件的基本概念

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

事件组的优点:多个事件的集合叫做事件组

通常编程时如果要定义一个标志位,最长用的类型是char类型,在STM32中,char类型要占用8位bit,可能我们用标志位只是用来1表示事件发生,0表示事件没有发生。使用8位比较浪费RAM空间,事件组可以很好的节省RAM空间。在FreeRTOS中事件组存储在一个EventBits_tl类型的变量中,这个变量还有一个宏来控制。

configUSE_16_BIT_TICKS 定义为 1 时变量uxEventBits为16位的,但是只能存储8个位来存储事件。

configUSE_16_BIT_TICKS 定义为 0 时变量uxEventBits为32位的,但是只能存储24个位来存储事件。

每一位代表一个事件,任务通过逻辑与或者逻辑或与一个或多个事件建立关联。

事件组特点
  • 事件只与任务相关联,事件之间相互独立。
  • 事件仅用于同步,不提供数据传输功能。
  • 事件无排队性,多次设置一个事件(任务还没有读取走),等效于只设置一次
  • 允许多个任务对同一事件进行读写操作
  • 支持等待超时
事件应用场景
  1. 做标志位

    用事件做标志位,用来标志某些情况是否发生。多个事件标志位可以组成事件组统一管理。

    比如设备启动,有些需要进行一些列自检,当全部自检成功,设备才能启动正常,这时可以用事件作为自检成功或失败的标志位

事件运作机制
  1. 接收事件时,可以根据需要关注单个或多个事件类型,事件接收成功后可以选择是否清空事件标志位。

  2. 设置事件时,通过移位操作,对事件集合的对应事件位置1,可以同时写多个事件类型,设置事件成功后可能会出发任务调度。

  3. 清除事件时,根据传入参数事件句柄和待清除的事件类型,对事件对应为进行清0操作。

  4. 事件唤醒机制,当任务等待某个或者多个事件发生而进入阻塞态,当事件发生后任务进入就绪态,用户可以指定阻塞时间。
    在这里插入图片描述

事件不与任务关联,事件之间相互独立,每一位表示一种事件类型,只有0或1两种情况。

事件函数接口讲解

事件控制块

/*------------------------------------------------------------------------------
	如果宏 configUSE_16_BIT_TICKS 定义为 1,那么变量uxEventBits 就 是 16 位 的 , 
	其 中 有 8 个 位 用来存储 事 件 组 , 如 果 宏configUSE_16_BIT_TICKS 定义为 0,
	那么变量 uxEventBits 就是 32 位的,其中有 24 个位用来存储事件组
----------------------------------------------------------------------------------*/
EventGroupHandle_t Event_Handle =NULL;//定义事件组控制句柄

事件创建函数 xEventGroupCreate( )

/*-------------------------------------------------------------------------------
	事件创建函数(动态),函数参数为空,返回值是一个EventGroupHandle_t类型的句柄
-----------------------------------------------------------------------------------*/
 EventGroupHandle_t xEventGroupCreate( void );

//使用实例
static EventGroupHandle_t Event_Handle =NULL;//定义事件组句柄
Event_Handle = xEventGroupCreate(); 
if (NULL != Event_Handle)
	printf("Event_Handle 事件创建成功!\r\n");
else
	/* 创建失败,应为内存空间不足 */

事件删除函数 vEventGroupDelete( )

/*---------------------------------------------------------------------------------
	事件删除函数,只有被创建成功的事件才能被删除,该函数不能用在中断里,当事件被删除后阻塞
	在事件组上的任务或被解锁。
------------------------------------------------------------------------------------*/
使用实例:
static EventGroupHandle_t Event_Handle = NULL;
Event_Handle = xEventGroupCreate();
if(NULL!=Event_Handle)
{
    printf("Event_Handle事件创建成功\r\n");
    xEventGroupCreate(Event_Handle);//删除事件组
}
else
{
    printf("Event_Handle事件创建失败\r\n");//空间不足,创建失败
}

事件组置位函数 xEventGroupSetBits()(任务)

/*---------------------------------------------------------------------------------
	事件组置位函数,用于置位事件组中指定的位,当位被置为后,阻塞在该位上的任务将会被解锁。
	该函数不能在中断中使用。
	xEventGroup---事件句柄
	xBitsToSet----指定事件中的事件标志位(设置为0X08只置位位3,设置为0X09则置位位3和位0)
	返回值是事件组中的值
------------------------------------------------------------------------------------*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t xBitsToSet );

#define KEY1_EVENT (0x01 << 0)//设置事件掩码的位 0 
#define KEY2_EVENT (0x01 << 1)//设置事件掩码的位 1

if(key==1)//如果按键1按下
    xEventGroupSetBits(Event_Handle,KEY1_EVENT);
if(key==2)//如果按键1按下
    xEventGroupSetBits(Event_Handle,KEY2_EVENT);

事件组置位函数 xEventGroupSetBitsFromISR()(中断)

xEventGroupSetBitsFromISR()xEventGroupSetBits()的中断版本,用于置位事件组中
指定的位。置位事件组中的标志位是一个不确定的操作,因为阻塞在事件组的标志位上的
任务的个数是不确定的。FreeRTOS 是不允许不确定的操作在中断和临界段中发生的,所以
xEventGroupSetBitsFromISR()给 FreeRTOS 的守护任务发送一个消息,让置位事件组的操作
在守护任务里面完成,守护任务是基于调度锁而非临界段的机制来实现的。

等待事件函数 xEventGroupWaitBits( )

/*----------------------------------------------------------------------------------
	等待事件函数
	xEventGroup:事件句柄
	uxBitsToWaitFor:一个按位或的值,指定需要等待事件组中的那些位置1
	xClearOnExit:传入pdTURE时唤醒任务后,清除事件标志位;传入pdFALSE时,不清除事件标志位
	xWaitForAllBits:传入pdTURE时-当指定位都置位后,才满足唤醒任务的条件。(逻辑与等待事件)
	传入pdFALSE时-当指定位有一个置位后,即可满足唤醒任务的条件。(逻辑或等待事件)
	xTicksToWait:超时等待时间。
	返回值:返回事件中的哪些事件标志位被置位,返回值很可能并不是用户指定的事件位,需要对返回
	值进行判断再处理。
-----------------------------------------------------------------------------------*/
EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToWaitFor,
 const BaseType_t xClearOnExit,
 const BaseType_t xWaitForAllBits,
 TickType_t xTicksToWait );

清除事件组指定位函数 xEventGroupClearBits( )与 xEventGroupClearBitsFromISR( )

/*--------------------------------------------------------------------------------------
	如果在获取事件的时候没有将对应的标志位清除,那么就需要用这个函数来进行显式清除,
	EventGroupClearBits()函数不能在中断中使用,而是由具有中断保护功能的xEventGroupClearBitsFromISR() 
	来代替
	xEventGroup:事件句柄
	uxBitsToClear:指定事件组中的哪个位需要清除,如设置 uxBitsToSet 为0x08 则只清除位 3,如果设置
	uxBitsToSet 为 0x09 则位 3 和位 0 都需要被清除。
	返回值:事件在还没有清除指定位之前的值。
----------------------------------------------------------------------------------------*/
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );

事件标志组学习总结完毕,后续有新的笔记会重复更新。–add-by-wrs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值