STM32FreeRTOS-事件组1(STM32Cube高效开发教程)

文章目录

一、事件组的原理和功能

1、事件组与队列信号量特点

事件组是FreeRTOS中的一种对象,且FreeRTOS默认就可以使用事件组,无需设置相关参数,但是使用之前需要使用创建函数创建事件组对象。

事件标志组与队列信号量的区别:

2、事件组存储结构

事件组有一个内部变量存储事件标志,当configUSE_16_BIT_TICKS为0时,这个变量是32位的,否则是16位的,在STM32上处理器上是32位的。

使用了32位无符号的数据类型变量来存储事件标志,但其中的高8位用作存储事件标志组的控制信息,低24位用作存储事件标志,所以说一个事件组最多可以存储 24 个事件标志!

一个事件组中的所有事件位保存在一个EventBits_t类型的变量里,所以一个事件又称为一个"事件位"

3、事件组运行原理

(1)设置事件组中的位与某个事件对应,检测到事件发生时将相应的位置1,表示事件发生了。

(2)可以有1个或多个任务等待事件组中的事件发生,可以是各个事件都发生(事件位的与运算),或某个事件发生(事件位的或运算)。

(3)假设图中的Task1和Task2都以阻塞状态等待两个事件都发生,当Bit2和Bit0都被置为1后(不分先后顺序),两个任务都会被解除阻塞状态。所以 事件组具有广播功能。

二、事件组部分函数

函数所在文件如下图所示:

1、xEventGroupCreate()创建事件组函数

以动态分配内存方式创建事件组,无参数,返回值是创建的事件组句柄变量(一个指针变量),其他函数在操作事件组时都使用事件组句柄变量作为输入参数。

返回值类型EventGroupHandle_t的定义如下:

2、xEventGroupSetBits()事件组置位函数

c 复制代码
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;

参数1:要操作的事件组句柄
参数2:要置位的事件位掩码
返回值:置位成功后事件组当前的值

类型EventBits_t的定义如下,也就是TickType_t,在STM32处理器上,等同于类型uint32_t

被置位的事件位为1,未被置位的事件位为0,一个事件只对应事件组中的一个事件位,一个事件发生只需要置位一个事件位

需要置位事件组中的bit7,则位掩码是0x80

需要置位事件组中的bit0,则位掩码是0x01

同时置位事件组中的bit7和bit0,则位掩码是0x81

官方代码段举例:

c 复制代码
Example usage:

	//想要置位哪一个事件位通过宏定义操作即可
   #define BIT_0	( 1 << 0 ) //宏定义:置位bit0对应的事件位
   #define BIT_4	( 1 << 4 ) //宏定义:置位bit4对应的事件位


   void aFunction( EventGroupHandle_t xEventGroup )
   {
  		 EventBits_t uxBits; //存放置位函数返回值

		//使用时间位0和事件位4进行置位操作
		//对两个事件位的宏定义进行或操作,就是同时对两个位进行置位(也就是传递的参数2位掩码)
	
		// Set bit 0 and bit 4 in xEventGroup.
		//位掩码是0x11
		uxBits = xEventGroupSetBits(
							xEventGroup,	// The event group being updated.
							BIT_0 | BIT_4 );// The bits being set.
			

		//函数返回值是置位成功后事件组当前的数值
			
		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )//bit0和bit4同时被置位	
		{
			// Both bit 0 and bit 4 remained set when the function returned.
		}
		
		else if( ( uxBits & BIT_0 ) != 0 )//bit0被置位
		{
			// Bit 0 remained set when the function returned, but bit 4 was
			// cleared.  It might be that bit 4 was cleared automatically as a
			// task that was waiting for bit 4 was removed from the Blocked
			// state.
		}
		else if( ( uxBits & BIT_4 ) != 0 )//bit4被置位
		{
			// Bit 4 remained set when the function returned, but bit 0 was
			// cleared.  It might be that bit 0 was cleared automatically as a
			// task that was waiting for bit 0 was removed from the Blocked
			// state.
		}
		else//bit0和bit4均没有被置位
		{
			// Neither bit 0 nor bit 4 remained set.  It might be that a task
			// was waiting for both of the bits to be set, and the bits were
			// cleared as the task left the Blocked state.
		}
   }

3、xEventGroupSetBitsFromISR()事件组置位函数ISR版本

ISR版本相对于任务版本多了最后一个参数:是否需要进行上下文切换的申请

根据参数configUSE_TRACE_FACILITY数值为1或0分为以下两个版本

c 复制代码
#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
#endif

默认的函数原型:

pxHigherPriorityTaskWoken是指针BaseType_t*,是一个返回值(pdTRUE或pdFALSE),表示在退出ISR函数前是否需要申请进行一次任务调度。

c 复制代码
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
									const EventBits_t uxBitsToSet, 
									BaseType_t *pxHigherPriorityTaskWoken );
/*
参数1:事件组句柄
参数2:置位掩码
参数3:退出ISR时是否需要上下文切换
*/
//示意代码如下:
BaseType_t highTaskWoken =pdFALSE;
xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, &highTaskWoken);
portYIELD_FROM_ISR(highTaskWoken); //申请进行一次任务调度

Freeertos不允许中断或临界代码段进行不确定的操作,在ISR中进行事件组置位操作时FreeRTOS实际上向定时器守护任务发送了一个消息,将事件组置位操作延后到定时器守护任务里执行。

如果定时器优先值高于当前执行的任务,返回pdtrue,否则返回pdfalse

根据pdtrue手动的进行一次上下文切换,这个函数返回pdtrue表明延后处理的消息成功的发送给了定时器守护任务,当定时器守护任务的队列消息满时,函数会无法接收到新的消息,返回值为pdfalse

4、xEventGroupClearBits()事件位清零函数

函数xEventGroupClearBits()用于在任务函数中将事件组的某些事件位清零,其函数原型是

c 复制代码
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, 
								const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;


参数1:事件组句柄
参数2:要清零的事件位掩码(掩码意义与事件位置位中一样)
返回值:事件位被清零之前的事件组的值

uxBitsToClear是需要清零的事件位的掩码, 需要清零的位设置为1。

将bit0和bit4清零

5、xEventGroupClearBitsFromISR()事件位清零函数ISR版本

c 复制代码
#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
#endif

在ISR函数中的事件位清零操作会被延后到定时器守护任务(timer daemon task) 中去处理,函数的返回值为pdTRUE或pdFALSE,如果返回值为pdTRUE表示延后处理的消息成功发送给了定时器守护任务,否则就是没有成功发送。

6、xEventGroupGetBits()读取事件组当前的值

传入事件组句柄(不清空任何位)

它实际上就是执行了函数xEventGroupClearBits(),只是传递的事件位掩码是0,也就是不清除任何事件位,而返回事件组当前的值

7、xEventGroupWaitBits()等待事件组成立

函数xEventGroupWaitBits()使当前任务进入阻塞状态,以等待事件组中多个事件位表示的事件成立时再退出阻塞状态。
事件组成立的条件可以是多个事件位都被置位(逻辑与运算) ,或其中某个事件位被置位(逻辑或运算)

c 复制代码
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, 
									const EventBits_t uxBitsToWaitFor, 
									const BaseType_t xClearOnExit, 
									const BaseType_t xWaitForAllBits,
									 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

/*
参数1:事件组句柄
参数2:所等待事件位的掩码(如果需要等待某个事件位置1,掩码中相应的位就设置为1)
参数3:设定值为pdTRUE或pdFALSE,退出时是否清除掩码位(清零)
	pdTRUE则表明在事件组条件成立退出阻塞状态时,会将参数2掩码中指定的所有位全部清零
	如果函数因为超时退出阻塞状态,即使设置为pdTRUE也不会将掩码事件位清零
参数4:设定值为pdTRUE或pdFALSE,是否等待所有位置位(所有同时成立还是某一个成立即可)
	pdTRUE表示事件位全部置1条件成立(逻辑与运算),否则任意一个置1条件成立(逻辑或运算)
	当事件条件成立时,函数就会退出,任务退出阻塞态
参数5:超时阻塞时间

返回值:
*/
相关推荐
m0_748254091 小时前
STM32--超声波模块(HC—SR04)(标准库+HAL库)
stm32·单片机·嵌入式硬件
南城花随雪。1 小时前
单片机:实现FFT快速傅里叶变换算法(附带源码)
单片机·嵌入式硬件·算法
逝灮1 小时前
【蓝桥杯——物联网设计与开发】基础模块8 - RTC
stm32·单片机·嵌入式硬件·mcu·物联网·蓝桥杯·rtc
weixin_452600698 小时前
串行时钟保持芯片D1380/D1381,低功耗工作方式自带秒、分、时、日、日期、月、年的串行时钟保持芯片,每个月多少天以及闰年能自动调节
科技·单片机·嵌入式硬件·时钟·白色家电电源·微机串行时钟
森旺电子11 小时前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
不过四级不改名67713 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A15913 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion13 小时前
各种电机原理介绍
单片机·嵌入式硬件
善 .16 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件
超级码农ProMax16 小时前
STM32——“SPI Flash”
stm32·单片机·嵌入式硬件