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

本文介绍了如何在ESP32嵌入式系统中利用FreeRTOS进行实时任务调度,区分了相对延迟和绝对延迟的概念,并详细讲解了vTaskDelayUntil函数的应用,以实现精确的任务执行时间控制。
摘要由CSDN通过智能技术生成

在 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:任务下一次唤醒的时间间隔。

🚨需要注意此函数会对pxPreviousWakeTime的值自动更新,延迟执行之后不需要我们手动在去更新。

示例

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁子希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值