在C++类中使用FreeRTOS任务
前言
ESP32是一款强大的微控制器,具有丰富的功能和灵活性,可以用于各种物联网和嵌入式应用。FreeRTOS是一个广泛使用的实时操作系统,可以帮助我们实现多任务处理和任务调度。在ESP32开发中,结合C++类和FreeRTOS任务可以让我们更好地组织和管理代码,提高代码的可读性和可维护性。
示例
#include <Arduino.h>
#include <FreeRTOS.h>
#include <task.h>
#define LED_PIN 2
class LEDTask {
public:
LEDTask(uint8_t pin) : _pin(pin) {}
void begin() {
pinMode(_pin, OUTPUT); // 设置引脚为输出模式
xTaskCreate(taskFunction, "LED Task", 2048, this, 1, &_taskHandle);
}
static void taskFunction(void* pvParameters) {
LEDTask* taskInstance = static_cast<LEDTask*>(pvParameters);
taskInstance->run();
}
void run() {
while (1) {
digitalWrite(_pin, HIGH); // 点亮LED
vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒
digitalWrite(_pin, LOW); // 熄灭LED
vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒
}
}
private:
uint8_t _pin;
TaskHandle_t _taskHandle;
};
LEDTask ledTask(LED_PIN);
void setup() {
ledTask.begin();
}
void loop() {
// 主循环代码
}
为什么FreeRTOS任务用静态函数
在使用FreeRTOS时,任务函数通常是静态的,这是因为FreeRTOS的任务函数需要与C函数指针的形式相匹配。这种匹配要求任务函数必须是静态的或全局的,以确保它们具有固定的地址,从而可以在任务创建时传递给FreeRTOS内核。
在C++中,类的成员函数(非静态)需要一个额外的隐藏参数,该参数是指向类对象的指针(this 指针)。因此,非静态成员函数的函数指针和普通的C函数指针是不同的。
由于FreeRTOS任务创建函数 xTaskCreate()
需要一个普通的C函数指针作为任务的入口点,所以我们无法直接将非静态成员函数传递给 xTaskCreate()
函数。
解决方案是使用静态成员函数作为任务的入口点。静态成员函数不需要额外的隐藏参数,因此它们与普通的C函数指针兼容。在静态成员函数中,我们可以通过类型转换将 this 指针转换回类的对象指针,然后调用类的非静态成员函数。
因此,任务使用静态函数的主要原因是为了与FreeRTOS内核的要求相匹配,以便可以正常地将任务函数指针传递给FreeRTOS的任务创建函数。
结语
通过结合C++类和FreeRTOS任务,我们可以更好地组织和管理ESP32的代码。C++类提供了面向对象的编程模式,使代码更加模块化和可重用。FreeRTOS任务实现了多任务处理和任务调度,使我们能够更好地处理并发和异步事件。