FreeRTOS在C++类中创建任务

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

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

  1. #include "stdint.h"
  2. #include "stdio.h"
  3. #include "params.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/task.h"
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. class Controller
  10. {
  11. private://only accesible for class
  12. int test1;
  13. public:
  14. //accesible outside class
  15. Controller(); // INIT OBJECT
  16. void begin(); // DECLARE DEFAULT
  17. e_thermostat_state Get_state();
  18. void normal_operation_task(void *argument); // FREERTOS TASK FUNCTION PROTOTYPE
  19. };
  20. #ifdef __cplusplus
  21. }
  22. #endif
  23. #endif

在我的控制器里。c:

  1. #include "Controller.h"
  2. Controller controller_obj;
  3. uint8_t app_temp = 10;
  4. Controller::Controller(){
  5. printf("Controller object created \n");
  6. }
  7. void Controller::begin(){
  8. printf("Initialise the object with the default values \n");
  9. xTaskCreate(this->normal_operation_task,"controller normal operation task",10000,NULL,1,NULL);
  10. }
  11. void Controller::normal_operation_task(void *argument){
  12. for(;;)
  13. {
  14. printf("normal_operation_task\n");
  15. vTaskDelay(1000/portTICK_RATE_MS);
  16. }
  17. }

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

  1. ../components/Controller/Controller.cpp: In member function 'void Controller::begin()':
  2. ../components/Controller/Controller.cpp:20:98: error: invalid use of non-static member function 'void Controller::normal_operation_task(void*)'
  3. 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中,我声明:

  1. static void Thermostat::normal_operation_task2(Thermostat* thermostat_obj){
  2. for(;;)
  3. {
  4. printf("normal_operation_task\n");
  5. vTaskDelay(1000/portTICK_RATE_MS);
  6. }
  7. }

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

问题

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

  1. void Controller::begin(){
  2. printf("Initialise the object with the default values \n");
  3. xTaskCreate(this->normal_operation_task3,"thermostat normal operation task",10000,&controller_obj,1,NULL); //receiving commands from main uart
  4. }
  5. void Controller::normal_operation_task3(void* parameters)
  6. {
  7. Controller controller_obj = *((Controller*)parameters);
  8. for(;;)
  9. {
  10. printf("normal_operation_task\n");
  11. vTaskDelay(1000/portTICK_RATE_MS);
  12. }
  13. }
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的参数来保存示例指针。

相关问题