2021-05-24 FREERTOS任务通知—模拟事件标志组

任务通知—模拟事件标志组
描述:使用任务通知模拟事件标志组也时通过操作一个32位任务通知值的位来实现的,只不过是间接操作的,比事件标志组操作要繁琐一点,个人建议使用事件标志组替代任务通知模拟。

#include "event_groups.h" //头文件
EventGroupHandle_t  EventGroupHandler;//事件标志组句柄声明
#define EVENTBIT_0    (1<<0)//事件标志位 0
#define EVENTBIT_1    (1<<1)//事件标志位 1
#define EVENTBIT_2    (1<<2)//事件标志位 2
#define EVENTBIT_ALL	(EVENTBIT_0|EVENTBIT_1|EVENTBIT_2)  
EventGroupHandler=xEventGroupCreate();//创建一个事件标志组

以上为事件标志组的声明与创建过程。

#include "FreeRTOS.h"
#include "task.h"
#include "limits.h"
#define EVENTBIT_0	(1<<0)				//事件位0
#define EVENTBIT_1	(1<<1)
#define EVENTBIT_2	(1<<2)

以上为任务通知模拟事件标志组的声明

//设置事件位的任务

void eventsetbit_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		if(EventGroupTask_Handler!=NULL)
		{
			key=KEY_Scan(0);
			switch(key)
			{
				case KEY1_PRES:
					xTaskNotify((TaskHandle_t	)EventGroupTask_Handler,//接收任务通知的任务句柄
								(uint32_t		)EVENTBIT_1,			//要更新的bit
								(eNotifyAction	)eSetBits);				//更新指定的bit
					break;
				case KEY2_PRES:
					xTaskNotify((TaskHandle_t	)EventGroupTask_Handler,//接收任务通知的任务句柄
								(uint32_t		)EVENTBIT_2,			//要更新的bit
								(eNotifyAction	)eSetBits);				//更新指定的bit
					break;	
				case KEY3_PRES:
				xTaskNotify((TaskHandle_t	)EventGroupTask_Handler,//接收任务通知的任务句柄
								(uint32_t		)EVENTBIT_3,			//要更新的bit
								(eNotifyAction	)eSetBits);				//更新指定的bit
					break;	
			}
		}
        vTaskDelay(10); //延时10ms,也就是10个时钟节拍
	}
}

中断服务函数的事件设置如下:
//外部中断4服务程序

#define EVENTBIT_0 (1<<0)

void EXTI4_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken;
	xTaskNotifyFromISR((TaskHandle_t	)EventGroupTask_Handler, 	//任务句柄
						   (uint32_t		)EVENTBIT_0, 				//要更新的bit
						   (eNotifyAction	)eSetBits, 					//更新指定的bit
						   (BaseType_t*		)xHigherPriorityTaskWoken);
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);	 
	 EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位  
}

获取任务通知
//事件标志组处理任务

void eventgroup_task(void *pvParameters)
{
	u8 enevtvalue;
	static u8 event0flag,event1flag,event2flag;
	uint32_t NotifyValue;
	BaseType_t err;
	
	while(1)
	{
		//获取任务通知值
		err=xTaskNotifyWait((uint32_t	)0x00,				//进入函数的时候不清除任务bit
							(uint32_t	)ULONG_MAX,			//退出函数的时候清除所有的bit
							(uint32_t*	)&NotifyValue,		//保存任务通知值
							(TickType_t	)portMAX_DELAY);	//阻塞时间
		
		if(err==pdPASS)	   //任务通知获取成功
		{
			if((NotifyValue&EVENTBIT_0)!=0)			//事件0发生	
			{
				event0flag=1;	
			}				
			else if((NotifyValue&EVENTBIT_1)!=0)	//事件1发生	
			{
				event1flag=1;
			}
			else if((NotifyValue&EVENTBIT_2)!=0)	//事件2发生	
			{
				event2flag=1;	
			}
	
			enevtvalue=event0flag|(event1flag<<1)|(event2flag<<2);	//模拟事件标志组值
			if((event0flag==1)&&(event1flag==1)&&(event2flag==1))	//三个事件都同时发生
			{
				event0flag=0;								//标志清零
				event1flag=0;
				event2flag=0;
			}
		}
		else
		{
			printf("任务通知获取失败\r\n");
		}

	}
}

总结:任务通知模拟事件标志组的核心就是任务通知值的设置与读取过程,获取通知的时候需要读取该32位的值与相应事件位比较判定事件是否发生,发生则FLAG0置1,它无法判定多个事件是否发生,只能用FLAG判定。
多个FLAG置1则表示模拟事件标志组达成。
真事件标志组可以设置多个事件位同时置1才释放阻塞,也可以单个事件置1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值