FreeRTOS(7)----事件组

1.事件位

·当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置1,当队列中没有消息需要处理的时候就可以将这个位(标志)置0

·当把队列中的消息通过网络发送输出以后就可以将某个位(标志)置1,当没有数据需要从网络发送出去的话就将这个位(标志)置0

·现在需要向网络中心发送一个心跳信息,将某个位(标志)置1。现在不需要向网络中发送心跳信息,这个位(标志)置0

2.事件组

一个事件组就是一组事件位,事件组中的事件位通过位编号来访问

·事件标志组的bit0表示队列中的消息是否处理掉

·事件标志组的bit1表示是否有消息需要从网络中发送出去

3.事件组的作用

在stm32里面freertos的事件组一般为16位,这样也就是可以同时存储16个事件的状态,事件其实和前面的信号量很像,可以类似看作成多个现在专门有一个东西"事件组"来管理多个信号量,之前的二值,互斥信号量都是只有一位的"事件组",当你任务或者中断存在多个标志位需要传递的时候,这个时候选择事件组会更加方便,你选择多个信号量也可以,但是你要挨个配置真的麻烦,这里可能会想到为啥不用全局变量,因为全局变量当被多个任务同时调用的时候,就会存在风险。这样我们还要自己去写任务调度的机制大大增加了成本。

事件的获取有两个方法:1.逻辑或:只要期望中的任何一个事件发生就可以唤醒任务,   2.逻辑与:任务所期望的事件必须全部获取,任务才可以被唤醒。

4.代码分析:

为事件结构体分配内存

初始化事件组

初始化等待链表【初始化等待链表是指在创建事件组时,将等待链表初始化为空。这样,在一开始没有任何进程或线程等待事件组信号时,事件组的等待链表为空,当一个或多个任务开始等待事件组信号时,其会加入等待链表中,等待该事件组信号被置位并被唤醒。】

	EventGroupHandle_t xEventGroupCreate( void )
	{
	EventGroup_t *pxEventBits;

		/* Allocate the event group. */
        分配内存
		pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );

		if( pxEventBits != NULL )
		{
            事件组初始化为0
			pxEventBits->uxEventBits = 0;
            初始化等待链表
			vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );

			#if( configSUPPORT_STATIC_ALLOCATION == 1 )
			{
				/* Both static and dynamic allocation can be used, so note this
				event group was allocated statically in case the event group is
				later deleted. */
				pxEventBits->ucStaticallyAllocated = pdFALSE;
			}
			#endif /* configSUPPORT_STATIC_ALLOCATION */

			traceEVENT_GROUP_CREATE( pxEventBits );
		}
		else
		{
			traceEVENT_GROUP_CREATE_FAILED();
		}

		return ( EventGroupHandle_t ) pxEventBits;
	}

等待事件函数

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

xEventGroup: 事件组的句柄

uxBitsToWaitFor:等待的事件位,可以用逻辑或等待多个标志位

xClearOnExit:   pdTRUE--->当任务唤醒后自动清楚对应的事件标志位,也就是将1变为0   pdFALSE---> 任务唤醒后不会自动清除事件位。

xWaitForAllBits: pdTRUE--->当uxBitsToWaitFor指定的事件位都为1的时候,才可以满足任务唤醒的条件   pdFALSE--->当uxBitsToWaitFor指定事件位任何一位为1就可以唤醒任务。

xTicksToWait:等待的阻塞时间

//事件标志组处理任务
void eventgroup_task(void *pvParameters)
{
	u8 num;
	EventBits_t EventValue;
	while(1)
	{

		if(EventGroupHandler!=NULL)
		{
			//等待事件组中的相应事件位
			EventValue=xEventGroupWaitBits((EventGroupHandle_t	)EventGroupHandler,		
										   (EventBits_t			)EVENTBIT_ALL,
										   (BaseType_t			)pdTRUE,				
										   (BaseType_t			)pdTRUE,
								       (TickType_t			)portMAX_DELAY);	
			printf("事件标志组的值:%d\r\n",EventValue);
			LCD_ShowxNum(174,110,EventValue,1,16,0);
			
			num++;
			LED1=!LED1;	
			LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
		}
		else
		{
			vTaskDelay(10); //延时10ms,也就是10个时钟节拍
		}
	}
}

事件组置位函数

xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )

xEventGroup:事件句柄

uxBitsToSet:将对应的事件设置为1。

void eventsetbit_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		if(EventGroupHandler!=NULL)
		{
			key=KEY_Scan(0);
			switch(key)
			{
				case KEY1_PRES:
					xEventGroupSetBits(EventGroupHandler,EVENTBIT_1);
					break;
				case WKUP_PRES:
					xEventGroupSetBits(EventGroupHandler,EVENTBIT_2);
					break;
			}
		}
        vTaskDelay(10); //延时10ms,也就是10个时钟节拍
	}
}

任务同步函数xEventGroupSync 

xEventGroupSync() 函数会等待多个事件位都置1后才会唤醒任务。它的功能是同步等待多个事件在不同任务中发生后再继续执行。

该函数需要指定一个事件组和一组要等待的辅助事件位(sync bits),当这些辅助事件位都为1时,该函数会返回并唤醒等待该事件组的任务。如果指定的辅助事件位没有全部置1,那么该任务将会被阻塞,并等待其他任务或事件处理程序将相应的位设置为1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夜路难行々

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

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

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

打赏作者

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

抵扣说明:

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

余额充值