FreeRTOS在C++类中创建任务

0h4hbjxa  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(235)

我正在写一个C代码来处理我的温度控制器。我决定学习更多的面向对象编程,学习更多的类,因此这次我选择了C(我通常用C编写代码)。我创建了一个简单的Controller类,其中有我的公共和私有函数。在我的controller.h文件中:

#include "stdint.h"
#include "stdio.h"
#include "params.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#ifdef __cplusplus
extern "C" {
#endif

class Controller
{
    private://only accesible for class
        int test1;
   

    public: 
    //accesible outside class
    
        Controller();                                                   // INIT OBJECT
        void begin();                                                   // DECLARE DEFAULT 
        e_thermostat_state Get_state();    
        void normal_operation_task(void *argument);    // FREERTOS TASK FUNCTION PROTOTYPE     
};

#ifdef __cplusplus
}
#endif

#endif

在我的控制器里。c:

#include "Controller.h"

Controller controller_obj;
uint8_t app_temp = 10;

Controller::Controller(){
    printf("Controller object created \n");
}

void Controller::begin(){
    printf("Initialise the object with the default values \n");
    xTaskCreate(this->normal_operation_task,"controller normal operation task",10000,NULL,1,NULL);
    
        
}

void Controller::normal_operation_task(void *argument){
    for(;;)
    {   
        printf("normal_operation_task\n");
        vTaskDelay(1000/portTICK_RATE_MS);
    }
}

正如您所看到的,当我调用开始方法时,我只想简单地启动任务。我希望freertos任务成为控制器类的一部分的原因是,在这个任务中,我需要访问控制器类的变量和函数。
我得到的错误:

../components/Controller/Controller.cpp: In member function 'void Controller::begin()':
../components/Controller/Controller.cpp:20:98: error: invalid use of non-static member function 'void Controller::normal_operation_task(void*)'
     xTaskCreate(this->normal_operation_task,"thermostat normal operation task",10000,NULL,1,NULL); // receiving commands from main uart

有人能给予我一些关于这个的建议吗?我有两个选择:
1.在我的类中,将所有变量和方法声明为public,这样即使freertos任务不是类的一部分,我也可以访问它们。
1.创建task作为Controller类的一部分,以便它可以使用私有方法和变量。

更新

我已经设法这样做时声明静态函数normal_operation_task,我建议我。在controller.h中,我声明:

static void Thermostat::normal_operation_task2(Thermostat* thermostat_obj){
    for(;;)
    {   
        printf("normal_operation_task\n");
        vTaskDelay(1000/portTICK_RATE_MS);
    }
}

我现在试图理解以下几点:
1.为什么这个函数必须声明为static
1.为什么我需要将指针传递给控制器对象?因为它被声明为类方法,所以它可以自动访问类函数和变量

问题

下面的问题是什么,为什么这是错误的?

void Controller::begin(){

    printf("Initialise the object with the default values \n");
    xTaskCreate(this->normal_operation_task3,"thermostat normal operation task",10000,&controller_obj,1,NULL); //receiving commands from main uart
}

 void Controller::normal_operation_task3(void* parameters)
 {
            Controller controller_obj = *((Controller*)parameters);
            for(;;)
            {   
                printf("normal_operation_task\n");
                vTaskDelay(1000/portTICK_RATE_MS);
            }
}
nzk0hqpo

nzk0hqpo1#

关于“为什么我需要将指针传递给我的控制器对象?因为它被声明为类方法,所以它会自动访问类函数和变量,静态方法只能访问类的静态成员。换句话说,静态方法和成员属于类,而不是类的示例。你需要给你的静态方法传递一个指向你的示例的指针,这样才能访问示例及其成员。
至于为什么它一定是一个静态方法,我自己也想知道。

7gs2gvoe

7gs2gvoe2#

FreeRTOS头部有必要的代码(条件extern“C”),使它们与C代码接口-但FreeRTOS通过名称调用的任何回调也需要声明为extern“C”。因此,从C调用xTaskCreate可以工作,但FreeRTOS无法调用您的类方法,因为它没有使用extern“C”声明。您将类声明为extern“C”,但未声明方法(不能将方法声明为extern“C”)。编译器通过名称修改来“检测”这种不匹配(google this以获取更多细节)。
你可以在类的外部创建一个桥接函数(例如作为C-struct的一部分),它持有指向您的控制器类的指针,并且每当FreeRTOS调用此桥接函数时,它都会在指针的帮助下调用您的成员方法。您还可以使用传递给xTaskCreate的参数来保存示例指针。

相关问题