<FreeRTOS入门第九节>事件标志位

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

今天又学习了FreeRTOS的事件标志位的处理。呀呼。


一、事件标志位是什么?

事件标志位能有效的解决一个任务与多个任务的同步,这是信号量不能解决的。
事件标志位就是指定一个位来存储一个任务或者事件的标志,是运行还是没有运行,运行就将这位置‘1’,没有运行就置‘0’,然后在获取这个位的标志来判断这个任务或者事件是否在运行。

二、API介绍

1.事件标志位的创建

在这里插入图片描述

/*
	动态创建事件标志位
	形参:无
	EventGroupHandle_t返回值的函数
	成功:其他值
	失败:NULL
*/
EventGroupHandle_t xEventGroupCreate( void )

2.事件标志位的设置

在这里插入图片描述

/*
	设置事件标志位的值置‘1’
	xEventGroup:事件标志位的句柄
	uxBitsToSet:设置的位(后面看案例,这里不解释)
	EventBits_t的返回函数
	成功:pdTRUE
	失败:pdFLASE
*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                const EventBits_t uxBitsToSet )

3.事件标志位清除

在这里插入图片描述

/*
	清除事件标志位
	xEventGroup:事件标志位的句柄
	uxBitsToClear:设置的位(后面看案例,这里不解释)
	EventBits_t的返回函数
	成功:pdTRUE
	失败:pdFLASE
*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
                                  const EventBits_t uxBitsToClear )

4.获取某一位的事件清除函数

在这里插入图片描述

/*
	获取某一位的事件标志位
	xEventGroup:事件标志位的句柄
	uxBitsToWaitFor:事件的标志位位置(可以使用|来定义多个位)
	xClearOnExit:退出uxBitsToWaitFor时是否清除标志位,pdTRUE开启,pdFLASE关闭
	xWaitForAllBits:pdTRUE当uxBitsToWaitFor的所以事件标志位都置‘1’才会返回。pdFALSE当uxBitsToWaitFor的某一个位的事件标志位置‘1’就会返回
	xTicksToWait:事件阻塞时间
	EventBits_t的返回函数
	成功:pdTRUE
	失败:pdFLASE
*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToWaitFor,
                                 const BaseType_t xClearOnExit,
                                 const BaseType_t xWaitForAllBits,
                                 TickType_t xTicksToWait )

三、案例

main.c

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "Timers.h"
#include "event_groups.h"
#include "stdio.h"
#include "Key.h"
#ifdef __GNUC__ //printf重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart1, (uint8_t*)&ch,1,HAL_MAX_DELAY);
    return ch;
}

TaskHandle_t HandlerTask1;
TaskHandle_t Task_Name4;


BaseType_t xReturn;
SemaphoreHandle_t Task1semaphore;

TimerHandle_t AutoTimerTask;
TimerHandle_t OneTimerTask;

EventGroupHandle_t EventGroupTask1;



void SystemClock_Config(void);
StackType_t xTask3Static[128];
StaticTask_t xTaskTCB;

StackType_t xIdle3Static[128];
StaticTask_t xIdleTCB;

StackType_t xTimerStatic[526];
StaticTask_t xTimerTCB;
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize ){
			*ppxIdleTaskTCBBuffer=&xIdleTCB;				
			*ppxIdleTaskStackBuffer=xIdle3Static;
			*pulIdleTaskStackSize=128;
}
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
                                          StackType_t ** ppxTimerTaskStackBuffer,
                                              uint32_t * pulTimerTaskStackSize ){
		 	* ppxTimerTaskTCBBuffer=&xTimerTCB;
			* ppxTimerTaskStackBuffer=xTimerStatic;
			* pulTimerTaskStackSize=526;																																															
}



void Task1Function( void * param){
		
	for(;;){
		
		
		vTaskDelay(100);
	}
}
void Task2Function(void* param){
		uint8_t num;
		EventBits_t EventFlag;
  for(;;)
  {
		num=Key_config();
		if(EventGroupTask1!=NULL){
			switch(num){
				case 1:
						xEventGroupSetBits(EventGroupTask1,(1<<0));
				break;
				case 2:
					  xEventGroupSetBits(EventGroupTask1,(1<<2));
				break;
				case 3:
					 #if 1
						EventFlag=xEventGroupWaitBits((EventGroupHandle_t) EventGroupTask1,
																(EventBits_t) (1<<0)|(1<<2),
																(BaseType_t) pdTRUE,
																(BaseType_t) pdFALSE,
																(TickType_t) 50);
					#else
						EventFlag=xEventGroupGetBits(EventGroupTask1);
					
						//xEventGroupClearBits(EventGroupTask1,(1<<0)|(1<<1));
					#endif
						printf("Event->Flag:%d\r\n",EventFlag);
				break;
			}
			
		}
		//vTaskDelay(100);
  }
}
void Task3Funtion(void* param){
	TickType_t st_time=xTaskGetTickCount(); 

	while(1){
		uint32_t num =1;
		xTaskDelayUntil(&st_time,30);
		
	}
	
}

void Task4Funtion(void* param){
	taskENTER_CRITICAL();
	//创建标志位
	  EventGroupTask1=xEventGroupCreate();
														
	//创建任务
	xReturn=xTaskCreate(Task1Function,"Task1",128,NULL,2,&HandlerTask1);
	xTaskCreate(Task2Function,"Task2",128,NULL,2,NULL);
 	xTaskCreateStatic(Task3Funtion,"Task3",128,NULL,2,xTask3Static,&xTaskTCB);
	if(xReturn == pdPASS){
			uint8_t buffS[20]="Task1 Create OK..\r\n";
			HAL_UART_Transmit(&huart1,(uint8_t*)buffS,strlen(buffS)*sizeof(char),HAL_MAX_DELAY);
	
		}
	vTaskDelete(Task_Name4);
	taskEXIT_CRITICAL();
}



int main(void)
{
  
	
	HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
	MX_USART1_UART_Init();
	
	xTaskCreate(Task4Funtion,"Task4",600,NULL,1,&Task_Name4);
	
  vTaskStartScheduler();
	
  while (1)
  {
   
  }
 
}


void SystemClock_Config(void)
{
	
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};


  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

void Error_Handler(void)
{
 
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

效果展示
在这里插入图片描述


总结

事件标志位总的说就是用来记录任务或者事件的运行状态的。

有些人心如花木,皆向阳而生 --《剑来》
何为凡人,何为仙,岂闻韶华尽何年,回首沧桑,此恨绵绵,风月如剑,看我破天。道不尽仙凡殊途,尽人间 --《凡人修仙传》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

单片有机机

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

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

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

打赏作者

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

抵扣说明:

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

余额充值