在 ESP32 上使用 FreeRTOS 进行绝对任务调度

发布时间:2024年01月24日

在 ESP32 上使用 FreeRTOS 进行绝对任务调度

嵌入式系统通常需要满足实时性的要求,因此使用实时操作系统(RTOS)是一种常见的解决方案。ESP32是一款强大的WiFi和蓝牙模块,它支持使用FreeRTOS进行实时任务调度。在本文中,我们将介绍如何在ESP32上使用FreeRTOS,以及如何创建和调度实时任务。

什么是FreeRTOS?

FreeRTOS是一个开源的实时操作系统内核,专为嵌入式系统设计。它提供了任务调度、时间管理、任务通信和同步等功能,使得开发者能够更轻松地开发实时应用程序。FreeRTOS的内核代码高度可移植,因此可以在不同的硬件平台上运行。

相对延迟,绝对延迟是任务在 FreeRTOS 中进行时间控制时使用的两种不同方式。

相对延迟和绝对延迟区别

  1. 相对延迟:

    • 使用 vTaskDelay 函数。
    • 任务在当前时间的基础上延迟一定的时间量。
    • 时间的单位是时钟节拍(Tick)。
    • 任务等待的时间是相对于当前的时钟节拍计数而言的,不考虑任务的启动时间或上一次唤醒时间。
    • 在实时性要求相对较低的情况下,相对延迟是一个简单而方便的选择。
  2. 绝对延迟:

    • 使用 vTaskDelayUntil 函数。
    • 任务在指定的绝对时间点运行。
    • 时间的单位是时钟节拍(Tick)。
    • 任务等待的时间是相对于一个基准时间的,任务在此基准时间的基础上延迟指定的时间量。
    • 考虑了任务的启动时间和上一次唤醒时间,更精准地控制任务的执行时间。
    • 在实时性要求较高、需要更精确的时间控制的场景中,绝对延迟是更合适的选择。

进行绝对任务调度

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上使用FreeRTOSvTaskDelayUntil函数,可以轻松实现绝对延迟的任务调度。这种方式非常适用于实时应用程序,其中任务的执行时序对系统的正确性和性能有严格要求。

文章来源:https://blog.csdn.net/m0_60134435/article/details/135827961
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。