FreeRTOS事件


事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,没有数据传输。与信号量不同的是,他可以实现一对多,多对多的同步。用事件做标志位判断某些事件是否发生了,然后根据结果进行处理。
一对多同步模型:一个任务等待多个事件的触发。
多对多同步模型:多个任务等待多个事件的触发。
使用全局变量做标志位可能引起的问题。
1.如何对全局变量进行保护,当多个任务同时尝试访问和修改全局标志变量时,可能会导致数据竞争或死锁。
2.如何让内核对事件进行有效的管理,使用全局变量需要在任务之间轮询的进行查看这个事件是否发生,这种非常浪费 CPU的资源。以及超时机制。

事件组

事件组是一组事件标志的集合。(事件标志是一个用来指示事件是否发生的布尔值,0或1)一个事件组的数据类型为EventBits_t。
当configUSE_16_BIT_TICKS 配置为 0 时,EventBits_t是一个32位无符号的数据类型。
当configUSE_16_BIT_TICKS 配置为 1 时,EventBits_t 是一个 16 位无符号的数据类型。
当配置为0时,并不意味着一个EventBits_t数据类型可以存储32个事件。其中高8位用于存储控制信息。低24位用于表示事件标志,某一位被置为一时,表示这一位对应的事件发生了。
在这里插入图片描述

API 函数

在这里插入图片描述

创建

EventGroupHandle_t xEventGroupCreate(void);

创建成功返回句柄,失败NULL

删除

void vEventGroupDelete(EventGroupHandle_t xEventGroup);

参数要删除的事件标志组句柄。

设置

任务中:

EventBits_t xEventGroupSetBits( 
EventGroupHandle_t xEventGroup,
constEventBits_t uxBitsToSet)

参数一:句柄,待操作的事件标志组。
参数二:待设置的事件标志位。
返回值:事件组中的事件标志位值。
中断中:

BaseType_t xEventGroupSetBitsFromISR(
 EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToSet,
 BaseType_t * pxHigherPriorityTaskWoken)

参数一:句柄,待操作的事件标志组。
参数二:待设置的事件标志位。
参数三:用于标记函数退出后是否需要进行任务切换。
返回值:设置成功返回pdPASS。失败返回pdFALL;

清零

任务中:

EventBits_t xEventGroupClearBits(
 EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToClear)

参数一:待操作的事件标志组。
参数二:待清零的事件标志位。
返回值:清零事件标志位之前事件组中事件标志位的值。
中断中:

BaseType_t xEventGroupClearBitsFromISR(
 EventGroupHandle_t EventGroup,
 const EventBits_t uxBitsToClear)

参数一:待操作的事件标志组。
参数二:待清零的事件标志位。
返回值:清除成功pdPASS,失败pdFAIL 。

等待

EventBits_t xEventGroupWaitBits(
 EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToWaitFor,
 const BaseType_t xClearOnExit,
 const BaseType_t xWaitForAllBits,
 TickType_t xTicksToWait)

参数一:等待的事件标志组句柄。
参数二:等待的事件标志位,可以用逻辑或等待多个事件标志位。
参数三:为pdTRUE:成功等待到事件标志位后,清除事件组中对应的事件标志位。
为pdFALSE:不清除事件组中所对应的事件标志位。
参数四:为 pdTRUE,任务会等待所有指定的位都设置为 TRUE。
为 pdFALSE,则任务会在任何一个指定的位被设置为 TRUE 时立即返回。
参数五:任务等待的最大时间(以滴答为单位)。如果设置为 0,任务将不会等待,函数将立即返回。

获取

任务中:

EventBits_t xEventGroupGetBits(xEventGroup);

参数:待获取事件标志位值的事件组句柄。
返回值:事件组的事件标志位的值。
中断中:

EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup);

参数:待获取事件标志位值的事件组句柄。
返回值:事件组的事件标志位的值。

实验

定义各任务的标志位

#define key1_event (0x01<<0)
#define key2_event (0x01<<1)
#define key3_event (0x01<<2)

创建事件句柄(创建)

EventGroupHandle_t  Event_Handle =NULL; 
Event_Handle=xEventGroupCreate(); 
if(Event_Handle == NULL)
{
	OLED_ShowString(1,5,"fail");
}
else
{
	OLED_ShowString(1,5,"succeed");
}

实验现象:
一:屏幕第4行第一列显示当前事件标志值。(获取)

void OLED2_task(void *pvParameters)
{
	EventBits_t event_val = 0;
  while(1)
  {
		/* 获取事件组的所有事件标志值 */
		event_val = xEventGroupGetBits(Event_Handle);
		OLED_ShowNum(4,1,event_val,2);
		
		vTaskDelay(20);
  }
}

若第1位和第2位为1,0000 0011 结果显示3。若1到3位都为1,显示0000 0111结果显示7。

二:按键1和按键2都有按下时执行任务oled,oled屏幕上显示k加一。(等待)

void OLED_task(void *pvParameters)
{
	static u8 k=0;
	EventBits_t event_val = 0;
  while(1)
  {
		//句柄,位,是否清零,是否同时满足,等待时间
		xEventGroupWaitBits(Event_Handle,key1_event|key2_event,pdTRUE,pdTRUE,portMAX_DELAY);
		OLED_ShowNum(2,1,++k,3);			
		vTaskDelay(20);
  }
}

三:按键3按下执行任务oled3,oled屏幕显示k加一,并清除按键1和按键2的标志位。(清除)

void OLED3_task(void *pvParameters)
{
	static u8 k=0;
  while(1)
  {
		xEventGroupWaitBits(Event_Handle,key3_event,pdTRUE,pdTRUE,portMAX_DELAY);
		xEventGroupClearBits(Event_Handle,key1_event|key2_event);
		OLED_ShowNum(2,10,++k,2);
		vTaskDelay(20);
  }
}
  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值