学习了事件组

任务 A 写入数据后------->仅唤醒一个等待该数据的任务

 对于信号量,互斥量也是一样

任务 A 写入数据后give -------->仅唤醒一个等待该数据的任务

而事件组是一种广播机制

一个任务A写入一个数据----------->唤醒多个数据

事件组

唤醒谁?

队列、信号量:事件发生时,只会唤醒一个任务

事件组:事件发生时,会唤醒所有符号条件的任务,简单地说它有"广播"的作用

等待一位,或者多位?

只发生一个 or

都发生 and

是否清除事件?

队列、信号量:是消耗型的资源,队列的数据被读走就没了;

信号量被获取后就减少了事件组:被唤醒的任务有两个选择,可以让事件保留不动,也可以清除事件

 高八位用来表示 或/与 

  1. 事件触发:

    • 任务 A 执行时,通过 FreeRTOS 函数(如 xEventGroupSetBits)将事件组的 bit0 置为 1
    • 任务 B 执行时,同理将 bit2 置为 1
  2. 事件等待与唤醒:

    • 任务 C:调用 xEventGroupWaitBits,设置等待条件为 bit0 | bit2(任意一个满足),一旦 bit0 或 bit2 被置 1,任务 C 会被唤醒执行;
    • 任务 D:调用 xEventGroupWaitBits,设置等待条件为 bit0 & bit2(需同时满足),只有 bit0 和 bit2 都 被置 1,任务 D 才会被唤醒。

事件组的使用:

上图为例

1,使用时先创建事件组

2,任务A/B设置任务组,设置事件组里的某一位、某些位

3,任务C/D进行等待任务组,等待什么事件?可以等待某一位、某些位中的任意一个,也可以等待多位。得到事件时,要不要清除?可选择清除、不清除。

函数:

创建

使用事件组之前,要先创建,得到一个句柄;使用事件组时,要使用句柄来表明使用哪个事件组。

有两种创建方法:动态分配内存、静态分配内存。函数原型如下:

/* 创建一个事件组,返回它的句柄。
 * 此函数内部会分配事件组结构体 
 * 返回值: 返回句柄,非NULL表示成功
 */
EventGroupHandle_t xEventGroupCreate( void );

/* 创建一个事件组,返回它的句柄。
 * 此函数无需动态分配内存,所以需要先有一个StaticEventGroup_t结构体,并传入它的指针
 * 返回值: 返回句柄,非NULL表示成功
 */
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );

设置 

可以设置事件组的某个位、某些位:

在任务中使用xEventGroupSetBits()

1>>0  bit0 置1  1>>7 bit7置

/* 设置事件组中的位
 * xEventGroup: 哪个事件组
 * uxBitsToSet: 设置哪些位? 
 *              如果uxBitsToSet的bitX, bitY为1, 那么事件组中的bitX, bitY被设置为1
 *              可以用来设置多个位,比如 0x15 就表示设置bit4, bit2, bit0
 * 返回值: 返回原来的事件值(没什么意义, 因为很可能已经被其他任务修改了)
 */
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                    const EventBits_t uxBitsToSet );

等待

使用xEventGroupWaitBits来等待事件,可以等待某一位、某些位中的任意一个,也可以等待多位;等到期望的事件后,还可以清除某些位。

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToWaitFor,
                                 const BaseType_t xClearOnExit,
                                 const BaseType_t xWaitForAllBits,
                                 TickType_t xTicksToWait );
参数 说明
xEventGroup 等待哪个事件组?
uxBitsToWaitFor 等待哪些位?哪些位要被测试?
xWaitForAllBits 怎么测试?是"AND"还是"OR"? pdTRUE: 等待的位,全部为1; pdFALSE: 等待的位,某一个为1即可
xClearOnExit 函数提出前是否要清除事件? pdTRUE: 清除uxBitsToWaitFor指定的位 pdFALSE: 不清除
xTicksToWait 如果期待的事件未发生,阻塞多久。 可以设置为0:判断后即刻返回; 可设置为portMAX_DELAY:一定等到成功才返回; 可以设置为期望的Tick Count,一般用*pdMS_TO_TICKS()*把ms转换为Tick Count
返回值 返回的是事件值, 如果期待的事件发生了,返回的是"非阻塞条件成立"时的事件值; 如果是超时退出,返回的是超时时刻的事件值。

 三个小车A B C,进车站

广播 :A先跑 ,B与C等待A跑完然后设置事件组才能动

如果B与C的优先级相同,一起跑,否则,高优先级先运行

OR:A或B到站后,只要一个到站,C再启动

AND:A与B一起到站,C才能启动

改进MPU6050姿态控制

MPU6050是读I2C操作,很耗时,所以放到任务中,通过vTaskDelay函数让任务及时得到我摇晃板子的动作。但是,如果没有摇晃板子,还是一直在While中执行,浪费CPU资源,那么就通过中断改进

如何唤醒任务呢?在中断里设置事件

等待事件,只有得到事件后才会触发读取I2C操作,得不到事件就一直处于阻塞状态

MPU6050

采用PB5作为中断,进行配置

当中断触发时,产生高电平

配置为上升沿触发

中断使能

一:系统中断 通过事件组进行触发

  1. MPU6050初始化时

动态创建事件组

  1. 创建一个函数,设置事件组,作用为: 在中断 / 任务上下文里,给事件组 g_xEventMPU6050 的第 0 位(bit0)置

  1. 等待事件组,在MPU6050任务中等待

只有事件触发时,任务才能调用

  1. 最后在中断函数中,写入MPU6050_Callback()函数

       当 GPIO_PIN_5 触发外部中断(比如接了 MPU6050 的中断输出引脚),就会调用 MPU6050_Callback 做后续处理

二:MPU6050中断设置

资料:

https://blog.csdn.net/sjf8888/article/details/97912391

0XFF全部使能

涉及函数:

动态创建

/* 创建一个事件组,返回它的句柄。
 * 此函数内部会分配事件组结构体 
 * 返回值: 返回句柄,非NULL表示成功
 */
EventGroupHandle_t xEventGroupCreate( void );

设置事件组(中断中使用)

/* 设置事件组中的位
 * xEventGroup: 哪个事件组
 * uxBitsToSet: 设置哪些位? 
 *              如果uxBitsToSet的bitX, bitY为1, 那么事件组中的bitX, bitY被设置为1
 *              可以用来设置多个位,比如 0x15 就表示设置bit4, bit2, bit0
 * pxHigherPriorityTaskWoken: 有没有导致更高优先级的任务进入就绪态? pdTRUE-有, pdFALSE-没有
 * 返回值: pdPASS-成功, pdFALSE-失败
 */
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
									  const EventBits_t uxBitsToSet,
									  BaseType_t * pxHigherPriorityTaskWoken );

等待事件组

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToWaitFor,
                                 const BaseType_t xClearOnExit,
                                 const BaseType_t xWaitForAllBits,
                                 TickType_t xTicksToWait );
xEventGroup 等待哪个事件组?
uxBitsToWaitFor 等待哪些位?哪些位要被测试?
xWaitForAllBits 怎么测试?是"AND"还是"OR"? pdTRUE: 等待的位,全部为1; pdFALSE: 等待的位,某一个为1即可
xClearOnExit 函数提出前是否要清除事件? pdTRUE: 清除uxBitsToWaitFor指定的位 pdFALSE: 不清除
xTicksToWait 如果期待的事件未发生,阻塞多久。 可以设置为0:判断后即刻返回; 可设置为portMAX_DELAY:一定等到成功才返回; 可以设置为期望的Tick Count,一般用*pdMS_TO_TICKS()*把ms转换为Tick Count
返回值 返回的是事件值, 如果期待的事件发生了,返回的是"非阻塞条件成立"时的事件值; 如果是超时退出,返回的是超时时刻的事件值。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐