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:超时阻塞时间

返回值:
*/
相关推荐
时光の尘21 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
嵌入式大圣2 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv
日晨难再3 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
yufengxinpian4 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件
__基本操作__5 小时前
历遍单片机下的IIC设备[ESP--0]
单片机·嵌入式硬件
网易独家音乐人Mike Zhou11 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
PegasusYu14 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
lantiandianzi18 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
文弱书生65618 小时前
输出比较简介
stm32
哔哥哔特商务网18 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件