freertos事件组
时间: 2023-08-22 16:04:15 浏览: 165
FreeRTOS事件组是一个用于多任务协调和通信的机制。它允许任务等待多个事件同时发生,并在事件发生后恢复任务的执行。事件组可以用于线程同步、互斥、事件通知等应用场景。
FreeRTOS事件组由32位的二进制位表示,每个事件标志位对应一个事件。任务可以通过等待特定的事件标志位来挂起自己的执行,并在其中一个或多个事件标志位被设置时被唤醒。任务还可以使用事件组的API函数来设置或清除特定的事件标志位。
以下是一些常用的FreeRTOS事件组API函数:
- xEventGroupCreate():创建一个新的事件组。
- vEventGroupDelete():删除已创建的事件组。
- xEventGroupSetBits():设置一个或多个事件标志位。
- xEventGroupClearBits():清除一个或多个事件标志位。
- xEventGroupWaitBits():等待一个或多个事件标志位被设置。
使用FreeRTOS事件组可以实现任务之间的同步和通信,提高系统的可靠性和效率。
相关问题
freertos 事件组
FreeRTOS事件组是FreeRTOS操作系统中的一个特性,用于实现任务间的同步和通信。事件组可以看作是一个32位的位图,每个位代表一个事件标志。任务可以等待某些特定的事件发生,或者通过设置特定的事件标志来通知其他任务。这种机制可以用于实现任务间的同步操作,例如任务等待某个事件发生后才能继续执行。
在FreeRTOS中,可以通过以下API来使用事件组:
- `xEventGroupCreate()`:创建一个事件组。- `xEventGroupSetBits()`:设置事件组中的某些位。
- `xEventGroupClearBits()`:清除事件组中的某些位。
- `xEventGroupGetBits()`:获取事件组中的当前位状态。
- `xEventGroupWaitBits()`:等待事件组中的某些位被设置。
通过使用这些API,任务可以进行事件的等待和通知,从而实现任务间的同步和通信。事件组是FreeRTOS中非常有用的一个功能,可以在多任务环境下提供可靠的同步机制。
FreeRTOS事件组
### FreeRTOS事件组的使用方法
#### 1. 创建事件组
通过 `xEventGroupCreate()` 函数来创建一个事件组。该函数会返回一个 `EventGroupHandle_t` 类型的句柄,用于后续操作[^1]。
```c
EventGroupHandle_t xEventGroup;
// 创建事件组
xEventGroup = xEventGroupCreate();
if (xEventGroup == NULL) {
// 处理错误情况
}
```
---
#### 2. 删除事件组
当不再需要某个事件组时,可以通过 `vEventGroupDelete()` 来释放其占用的资源[^4]。
```c
// 删除事件组
vEventGroupDelete(xEventGroup);
```
---
#### 3. 设置事件标志
可以使用 `xEventGroupSetBits()` 或者在中断上下文中使用 `xEventGroupSetBitsFromISR()` 来设置特定的事件标志位[^2]。
```c
// 在任务中设置事件标志
xEventGroupSetBits(xEventGroup, BIT0 | BIT1);
// 在中断中设置事件标志
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xEventGroupSetBitsFromISR(xEventGroup, BIT2, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
```
---
#### 4. 清除事件标志
如果需要清除某些事件标志位,则可以调用 `xEventGroupClearBits()` 或者在中断上下文中使用 `xEventGroupClearBitsFromISR()`。
```c
// 在任务中清除事件标志
xEventGroupClearBits(xEventGroup, BIT0);
// 在中断中清除事件标志
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xEventGroupClearBitsFromISR(xEventGroup, BIT1, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
```
---
#### 5. 等待事件标志
为了等待某些事件发生,可以使用 `xEventGroupWaitBits()` 函数。此函数允许指定超时时间以及是否需要所有或部分条件满足后再继续运行。
```c
const TickType_t xTicksToWait = pdMS_TO_TICKS(1000); // 超时时间为1秒
const EventBits_t uxBitsToWaitFor = BIT0 | BIT1; // 需要等待的比特位
EventBits_t uxReturn;
uxReturn = xEventGroupWaitBits(
xEventGroup, // 事件组句柄
uxBitsToWaitFor, // 等待哪些比特被置位
pdTRUE, // 如果为pdTRUE则自动清除匹配到的比特;如果是pdFALSE则不清除这些比特
pdFALSE, // 只有全部比特都就绪才返回(pdFALSE),或者只要有一个比特就绪即可返回(pdTRUE)
xTicksToWait // 最大阻塞时间
);
if ((uxReturn & uxBitsToWaitFor) == uxBitsToWaitFor) {
// 所需的所有比特都被设置了
} else {
// 超时或者其他原因未完成
}
```
---
#### 6. 获取当前状态
有时可能仅想读取而不改变任何现有的事件标志值,这时可利用 `xEventGroupGetBits()` 和 `xEventGroupGetBitsFromISR()` 这两个API实现。
```c
// 在任务中获取事件标志的状态
EventBits_t uxCurrentState = xEventGroupGetBits(xEventGroup);
// 在中断中获取事件标志的状态
EventBits_t uxInterruptState = xEventGroupGetBitsFromISR(xEventGroup);
```
---
### 示例代码综合应用
下面是一个完整的例子展示如何结合上述功能在一个简单的场景下工作:
```c
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#define TASK_STACK_SIZE configMINIMAL_STACK_SIZE
#define EVENT_GROUP_TASK_DELAY pdMS_TO_TICKS(100)
void vTaskOne(void *pvParameters);
void vTaskTwo(void *pvParameters);
int main(void) {
EventGroupHandle_t xCreatedEventGroup;
xCreatedEventGroup = xEventGroupCreate();
if (xCreatedEventGroup != NULL) {
xTaskCreate(vTaskOne, "Task One", TASK_STACK_SIZE, (void *)xCreatedEventGroup, tskIDLE_PRIORITY + 1, NULL);
xTaskCreate(vTaskTwo, "Task Two", TASK_STACK_SIZE, (void *)xCreatedEventGroup, tskIDLE_PRIORITY + 1, NULL);
vTaskStartScheduler();
}
for (;;);
}
void vTaskOne(void *pvParameters) {
EventGroupHandle_t xEventGroup = (EventGroupHandle_t)pvParameters;
while (true) {
// 周期性地设置BIT0
xEventGroupSetBits(xEventGroup, BIT0);
vTaskDelay(EVENT_GROUP_TASK_DELAY);
}
}
void vTaskTwo(void *pvParameters) {
EventGroupHandle_t xEventGroup = (EventGroupHandle_t)pvParameters;
const EventBits_t uxBitsToWaitFor = BIT0;
while (true) {
EventBits_t uxReturn;
uxReturn = xEventGroupWaitBits(
xEventGroup,
uxBitsToWaitFor,
pdTRUE, // 自动清除匹配到的比特
pdFALSE, // 必须等到所有的比特都准备好
portMAX_DELAY
);
if ((uxReturn & uxBitsToWaitFor) == uxBitsToWaitFor) {
// 当前已经检测到了BIT0被触发
} else {
// 错误处理逻辑
}
}
}
```
---
阅读全文
相关推荐

















