嵌入式系统通常需要满足实时性的要求,因此使用实时操作系统(RTOS)是一种常见的解决方案。ESP32是一款强大的WiFi和蓝牙模块,它支持使用FreeRTOS进行实时任务调度。在本文中,我们将介绍如何在ESP32上使用FreeRTOS,以及如何创建和调度实时任务。
FreeRTOS是一个开源的实时操作系统内核,专为嵌入式系统设计。它提供了任务调度、时间管理、任务通信和同步等功能,使得开发者能够更轻松地开发实时应用程序。FreeRTOS的内核代码高度可移植,因此可以在不同的硬件平台上运行。
相对延迟,绝对延迟是任务在 FreeRTOS 中进行时间控制时使用的两种不同方式。
相对延迟:
vTaskDelay
函数。绝对延迟:
vTaskDelayUntil
函数。ESP32内置了对FreeRTOS的支持,因此可以轻松地在ESP32上使用FreeRTOS进行任务调度。
FreeRTOS 中的任务延迟可以通过两种方式实现:相对延迟和绝对延迟。绝对任务延迟是指任务在一个特定的绝对时间点运行,而不是相对于当前时间的相对延迟。FreeRTOS 提供了 vTaskDelayUntil
函数来实现绝对任务延迟。
vTaskDelayUntil
函数vTaskDelayUntil
函数用于设置任务的绝对延迟,让任务在指定的绝对时间点运行。其原型如下:
void vTaskDelayUntil(TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement);
pxPreviousWakeTime
:指向 TickType_t
类型的变量的指针,用于保存任务上一次唤醒的时间。xTimeIncrement
:任务下一次唤醒的时间间隔。以下是一个使用 vTaskDelayUntil
的简单示例,其中任务每隔 1000 个时钟节拍(Tick)运行一次:
#include <FreeRTOS.h>
#include <task.h>
void vTaskExample(void *pvParameters) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = 1000; // 延迟的时间间隔,单位是时钟节拍
// 获取当前系统时间
xLastWakeTime = xTaskGetTickCount();
for (;;) {
// 任务逻辑
// ...
// 延迟到下一个绝对时间点
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
void setup() {
// 创建任务
xTaskCreate(vTaskExample, "Task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
}
void loop() {
// 空的 loop 函数
}
在这个例子中,vTaskExample
任务会每隔 1000 个时钟节拍运行一次。通过使用 vTaskDelayUntil
函数,任务能够在绝对的时间点进行延迟,而不是相对于当前时间。这样可以更精准地控制任务的执行频率。
在任务循环中添加串口打印功能,打印此时系统时间
for (;;) {
// 任务逻辑
// ...
Serial.println(xTaskGetTickCount());
// 延迟到下一个绝对时间点
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
和预想的一样每次打印任务的时间完美延迟1000节拍
在ESP32上使用FreeRTOS的vTaskDelayUntil
函数,可以轻松实现绝对延迟的任务调度。这种方式非常适用于实时应用程序,其中任务的执行时序对系统的正确性和性能有严格要求。