ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FreeRTOS-事件标志组

2021-09-09 19:32:51  阅读:234  来源: 互联网

标签:标志 FreeRTOS EventBits 0x01 任务 Handler 事件


FreeRTOS-事件标志组

  • 在前面我们已经学习了信号量,我们知道信号量可以用来做任务同步,但是这种任务同步有一个缺点,就是只能在两个任务之间进行同步,所以为了解决这个问题,FreeRTOS提供了事件标志组,使得多任务之间进行同步。

事件标志组表示方法

  • 事件标志组由若干个事件标志位组成,每个事件标志位表示某个事件是否发生。事件标志组的数据类型为EventBits_t,具体定义如下
typedef TickType_t EventBits_t;
#if( configUSE_16_BIT_TICKS == 1 )
	typedef uint16_t TickType_t;
	#define portMAX_DELAY ( TickType_t ) 0xffff
#else
	typedef uint32_t TickType_t;
	#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
	#define portTICK_TYPE_IS_ATOMIC 1
#endif
  • 从上面可以看出,当configUSE_16_BIT_TICKS =0时,EventBits_t为32位,否则EventBits_t为16位。但是,EventBits_t中的高8位有其他作用,不能用来表示事件,所以当EventBits_t为32位时,最多能用来表示24个事件。

事件标志组相关API

  • 本章不会深入分析这些API的源码,只是在使用上做一个介绍

xEventGroupCreate()

  • 函数作用:创建时间标志组
  • 函数声明:EventGroupHandle_t xEventGroupCreate( void )
  • 输入参数:无
  • 返回参数:事件标志组句柄

xEventGroupSetBits()

  • 函数作用:设置事件标志位
  • 函数声明:EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
  • 输入参数 xEventGroup:事件标志组句柄
  • 输入参数 uxBitsToSet :事件标志组所要置1的位,比如要使bit2置1,那么uxBitsToSet=0x04=0000 0100
  • 返回参数:事件标志组句柄

xEventGroupClearBits()

  • 函数作用:清除事件标志位
  • 函数声明:EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
  • 输入参数 xEventGroup:事件标志组句柄
  • 输入参数 uxBitsToClear :事件标志组所要清零的位,比如要使bit2置0,那么uxBitsToClear=0x04=0000 0100
  • 返回参数:事件标志组句柄

xEventGroupWaitBits()

  • 函数作用:等待事件标志位
  • 函数声明:EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
  • 输入参数 xEventGroup:事件标志组句柄
  • 输入参数 uxBitsToWaitFor:所要等待的事件标志位,比如要等待bit2,则uxBitsToWaitFor = 0x04,如果既要等待bit2也要等待bit4,则uxBitsToWaitFor = 0x04|0x10
  • 输入参数 xClearOnExit:事件等待完毕后是否清除标志位,如果输入参数为pdTRUE是表示清除,否则不清除。
  • xWaitForAllBits:是否要等待所有标志位,设置为pdTRUE时,需要等待所设置的所有标志位此时相当于与运算,否则只需要等待一个,此时相当于或运算
  • xTicksToWait:设置阻塞时间
  • 返回参数:事件标志组的值

用法示例

实验目的:创建3个事件,分别等待bit0置位,等待bit1置位,等待bit0和bit1均置位,通过按键将bit0和bit1置位
  • 按键处理函数
u8 keyFlag=0;
void key_task(void* pvParameters)
{
	EventBits_t Ebit;
	while(1)
	{
		
		if (Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON)
		{
			if ( (keyFlag&0x01) == 0x01)
				keyFlag &= ~(0x01<<0);
			else
			  keyFlag |= (0x01<<0);
			
			if ( (keyFlag&0x01) == 0x01)
			{
				Ebit = xEventGroupSetBits(Event_Handler,(0x01<<0));
				
				printf("current Ebit = %#x\r\n",Ebit);
			}
			else
			{
				Ebit = xEventGroupClearBits(Event_Handler,(0x01<<0));
				printf("current Ebit = %#x\r\n",Ebit);
			}
		
		}
		
		if (Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON)
		{
			if ( (keyFlag&0x02) == 0x02)
				keyFlag &= ~(0x01<<1);
			else
				keyFlag |= (0x01<<1);
			
			if ( (keyFlag&0x02) == 0x02)
			{
				Ebit = xEventGroupSetBits(Event_Handler,(0x01<<1));
				printf("current Ebit = %#x\r\n",Ebit);
			}
			else
			{
				Ebit = xEventGroupClearBits(Event_Handler,(0x01<<1));
				printf("current Ebit = %#x\r\n",Ebit);
			}
			
		}
		vTaskDelay(10);
	}
}
  • 等待事件任务

void event1_task(void* pvParameters)
{
	while(1)
	{
		if ( (keyFlag&0x01) == 0x01)
			LED0 = 0;
		else
			LED0 = 1;
		xEventGroupWaitBits(Event_Handler,(0x01<<0),pdFALSE,pdTRUE,portMAX_DELAY);
		printf("event1 task running!!\r\n");
		vTaskDelay(1000);
	}
}


void event2_task(void* pvParameters)
{
	while(1)
	{
		if ( (keyFlag&0x02) == 0x02)
			LED1 = 0;
		else
			LED1 = 1;
		xEventGroupWaitBits(Event_Handler,(0x01<<1),pdFALSE,pdTRUE,portMAX_DELAY);
		printf("event2 task running!!\r\n");
		vTaskDelay(1000);
	}
}


void event3_task(void* pvParameters)
{
	while(1)
	{
		if ( (keyFlag&0x03) == 0x03)
			LED2 = 0;
		else
			LED2 = 1;
		xEventGroupWaitBits(Event_Handler,(0x01<<1)|(0x01<<0),pdFALSE,pdTRUE,portMAX_DELAY);
		printf("event3 task running!!\r\n");
		vTaskDelay(1000);
	}
}
  • 创建事件标志组和任务

void start_task(void *pvParameters)
{				
	 Event_Handler = xEventGroupCreate();
	
		xTaskCreate((TaskFunction_t )key_task,            //任务函数
                (const char*    )"key_task",          //任务名称
                (uint16_t       )KEY_STACK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )KEY_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&KeyTask_Handler);   //任务句柄  	
								
	 xTaskCreate((TaskFunction_t )event1_task,            //任务函数
                (const char*    )"event1_task",          //任务名称
                (uint16_t       )EVENT1_STACK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )EVENT1_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&Event1Task_Handler);   //任务句柄  
								
	 xTaskCreate((TaskFunction_t )event2_task,            //任务函数
                (const char*    )"event2_task",          //任务名称
                (uint16_t       )EVENT2_STACK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )EVENT2_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&Event2Task_Handler);   //任务句柄 

		 xTaskCreate((TaskFunction_t )event3_task,            //任务函数
                (const char*    )"event3_task",          //任务名称
                (uint16_t       )EVENT3_STACK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )EVENT3_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&Event3Task_Handler);   //任务句柄 
								
	 vTaskDelete(StartTask_Handler);
}

标签:标志,FreeRTOS,EventBits,0x01,任务,Handler,事件
来源: https://blog.csdn.net/dhejsb/article/details/120207514

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有