首页 > 解决方案 > 为什么我的 FreeRTOS 任务看不到班级成员?

问题描述

我试图了解 FreeRTOS 构建一个包含 LED 闪烁任务的 C++ 类。但是在任务主体(也是一个类成员)中,其他类成员,即 LED1_delay 是空的/未初始化的。似乎任务主体已链接到另一个实例。

设置闪烁频率并启动任务的类函数:(gpio.cpp)

void c_gpio::LED_blink_on(float frequency){

    LED1_delay=(uint32_t)(1000/frequency);

    if(LEDTaskcreated!=true){
        //Create task
        LEDTaskHandle = osThreadNew(startTask_LED1_blinker, LEDTask_args, &LEDTask_attributes);
        LEDTaskcreated=true;
    }

}

避免静态声明的包装函数:(gpio.cpp)

void c_gpio::startTask_LED1_blinker(void* _this){
    static_cast<c_gpio*>(_this)->taskbody_LED1_blinker((void*)0);
}

任务主体:(gpio.cpp)

void c_gpio::taskbody_LED1_blinker(void* arguments){
    //All class members are uninitialized here..
      while(1)
      {
          HAL_GPIO_TogglePin(GP_LED_1_GPIO_Port,GP_LED_1_Pin);
          osDelay(this->LED1_delay);    //LED1_delay is not set.
      }
}

类声明 (gpio.hpp)

class c_gpio{

public:
    void LED_blink_on(uint8_t LED_id, float frequency);
private:

    static void startTask_LED1_blinker(void* _this);
    void taskbody_LED1_blinker(void *arguments);
    uint32_t LED1_delay;

    //Task handles & attributes
    osThreadId_t LEDTaskHandle;
    osThreadAttr_t LEDTask_attributes;
    uint16_t LEDTask_args[2];
};

实例化 (main.cpp)

#include "gpio.hpp"
c_gpio gpio;

int main(void)
{
    gpio.LED_blink_on(1,10);

    /* Init scheduler */
    osKernelInitialize();
    /* Start scheduler */
    osKernelStart();
}

我想,成员taskbody_LED1_blinker()LED1_delay属于同一个实例。但这似乎并非如此。为什么?如何正确构建这样的任务?

标签: c++multithreadingoopfreertosrtos

解决方案


问题:

您已使用类对象“gpio”来设置闪烁频率。意味着闪烁频率在 gpio 对象内更新。而“startTask_LED1_blinker”是一个未绑定到任何对象的类的静态方法

解决方案:

利用任务主体函数 startTask_LED1_blinker 的“参数”。您可以将“this”指针发送到 osThreadNew 而不是 LEDTask_args,然后使用该指针调用任务主体“taskbody_LED1_blinker”。更正您的代码以供参考

    void c_gpio::taskbody_LED1_blinker(void* arguments){
        //All class members are uninitialized here..
        while(1)
        {
            HAL_GPIO_TogglePin(GP_LED_1_GPIO_Port,GP_LED_1_Pin);
            osDelay(LED1_delay);    //LED1_delay is not set.
        }
    }

    void c_gpio::LED_blink_on(float frequency){

        LED1_delay=(uint32_t)(1000/frequency);
        

        if(LEDTaskcreated!=true){
            //Create task
            LEDTaskHandle = osThreadNew(startTask_LED1_blinker, this, &LEDTask_attributes);
            LEDTaskcreated=true;
        }
    }

推荐阅读