一、前言
事件标志组是实现多任务同步的有效机制之一。使用全局变量相比事件标志组主要有如下三个问题:
a. 使用事件标志组可以让 RTOS 内核有效地管理任务, 而全局变量是无法做到的,任务的超时等机制需要用户自己去实现。 b.使用了全局变量就要防止多任务的访问冲突,而使用事件标志组则处理好了这个问题,用户无需担心。 c.使用事件标志组可以有效地解决中断服务程序和任务之间的同步问题。
二、任务间事件组标志组的实现
1、配置说明
任务间事件标志组的实现是指各个任务之间使用事件标志组实现任务的通信或者同步机制。
configUSE_16_BIT_TICKS 设置为 1,则事件组内实现的位数(或标志数)为 8; 如果 configUSE_16_BIT_TICKS 设置为 0,则为 24。
2、需要使用到的API
1)函数 xEventGroupCreate用于创建事件标志组
EventGroupHandle_t xEventGroupCreate( void );
返回值,如果创建成功,此函数返回事件标志组的句柄。
2)函数 xEventGroupSetBits 用于函数内设置指定的事件标志位为 1
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */
const EventBits_t uxBitsToSet ); /* 事件标志位设置 */
参数:1:事件标志组句柄 。 2:表示24个可设置的事件标志位,变量 uxBitsToSet 的低 24 位的某个位设置为 1,那么被设置的事件标志组的相应位就设置为 1。 变量 uxBitsToSet 设置为 0 的位对事件标志相应位没有影响。
返回值:返回当前的事件标志组数值
3)函数 xEventGroupSetBitsFromISR用于中断设置指定的事件标志位为 1
BaseType_t xEventGroupSetBitsFromISR(
EventGroupHandle_t xEventGroup, //事件标志组句柄
const EventBits_t uxBitsToSet, //事件标志位设置
BaseType_t * pxHigherPriorityTaskWoken )//高优先级任务是否被唤醒的状态保存
返回值:如果消息成功发送给 daemon 任务( 就是 FreeRTOS 的定时器任务) 返回 pdPASS, 否则返回 pdFAIL,另外 daemon 任务中的消息队列满了也会返回 pdFAIL。
使用需要在FreeRTOSConfig.h 配置如下:
4)函数xEventGroupWaitBits 等待事件标志被设置
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, //事件标志组句柄
const EventBits_t uxBitsToWaitFor, //等待被设置的事件标志位
const BaseType_t xClearOnExit, //选择是否清零被置位的事件标志位
const BaseType_t xWaitForAllBits, //选择是否等待所有标志位都被设置
TickType_t xTicksToWait ) //设置等待时间
参数:
xEventGroup | 正在测试位的事件组。 此前 必须已通过 xEventGroupCreate() 创建好事件组。 |
uxBitsToWaitFor | 指定事件组中要测试的一个或多个事件位 的按位值。 例如,要等待第 0 位和/或第 2 位, 请将 uxBitsToWaitFor 设置为 0x05。 要等待第 0 位和/或第 1 位和/或第 2 位, 请设置 uxBitsToWaitFor 为 0x07, 以此类推。 uxBitsToWaitFor 不得设置为 0。 |
xClearOnExit | 如果 xClearOnExit 设置为 pdTRUE, 那么在作为 uxBitsToWaitFor 参数传递的值中设置的任何位 会在 xEventGroupWaitBits() 返回某个值之前在事件组中清除掉, 前提是 xEventGroupWaitBits() 因超时以外的原因而返回值 。 超时值由 xTicksToWait 参数设置。 如果 xClearOnExit 设置为 pdFALSE, 那么当调用 xEventGroupWaitBits() 返回时,事件组中设置的位不会改变。 |
xWaitForAllBits | xWaitForAllBits 用于创建逻辑与测试 (必须设置所有位)或逻辑或测试(必须设置一个 或多个位),如下所示: 如果 xWaitForAllBits 设置为 pdTRUE, 那么当在作为 uxBitsToWaitFor 参数传递的值中设置的所有位 均已在事件组中设置好,或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。 如果 xWaitForAllBits 设置为 pdFALSE,那么当在作为 uxBitsToWaitFor 参数传递的值中设置的任何位已在事件组中设置好, 或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。 |
xTicksToWait | 等待 uxBitsToWaitFor 指定的一个/所有(取决于 xWaitForAllBits 的值)位完成设置的最大时间 (单位:tick)。 |
返回:
事件位等待完成设置或阻塞时间过期时的事件组值。如果 高优先级任务或中断在调用任务解除“已阻塞”状态和退出 xEventGroupWaitBits() 函数之间更改了事件位的值,则事件组中事件位的当前值将与返回值不同 。
测试返回值以确定哪些位已完成设置。 如果 xEventGroupWaitBits() 因为超时值过期而返回,则并非在等待的所有位都会进行设置。 如果 xEventGroupWaitBits() 因为它所等待的位均已完成设置而返回相应值, 则返回值是自动清除 (原因是 xClearOnExit 参数设置为 pdTRUE)任何位之前的事件组值。
三、测试例程(STM32F103c8t6)
1.使用xEventGroupSetBits 函数内设置BIT
测试步骤:1.创建事件标志组,主函数调用该函数
2.使用串口接收到相应指令,使用xEventGroupSetBits 设置相应的BIT
3.创建信息处理任务,使用xEventGroupWaitBits 等待步骤2中修改的bit
4.观察串口打印的调试信息
2.使用 xEventGroupSetBitsFromISR 中断内设置 BIT
测试步骤:1.初始化TIM2,定时器计数一个1us即可,开启中断,并开启两个通道CC1,CC2
2. 使用串口接收到相应指令,开启TIM2的CC1或者CC2
3.在CC1或者CC2 的 TIM_CallBack 中使用xEventGroupSetBitsFromISR设置相应的BIT
4.观察串口打印的调试信息
例程:https://gitee.com/hutaooooooo/git_keil/tree/master/freetos_xEventGroup