Problem with xTaskCreate in C++...

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Problem with xTaskCreate in C++...

Postby stefanoxjx » Thu Mar 15, 2018 8:56 pm

Hi, I'm trying to write a class, but I've a compilation error.
Anyone can tell me why?
This is the interested code...

led.h

Code: Select all

#ifndef LED_H
#define LED_H

#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

class LED
{
   public:
   LED();

   private:
   void blinkLedTask(void *pvParameter);

   ...
};

#endif //LED_H
led.cpp

Code: Select all

#include "led.h"

LED::LED()
{
    ...

    xTaskCreate(&LED::blinkLedTask, "blinkLedTask", 2048, NULL, 5, NULL);
}

void LED::blinkLedTask(void *pvParameter)
{
     ...
}
During compilation, I've this error:

Code: Select all

 error: invalid use of non-static member function xTaskCreate(blinkLedTask, "blinkLedTask", 2048, NULL, 5, NULL);
If I try to declare blinkLedTask to static, I've this error:

Code: Select all

error: cannot declare member function 'static void LED::blinkLedTask(void*)' to have static linkage [-fpermissive]
 static void LED::blinkLedTask(void *pvParameter)
I'm not very good C++ developer, I'm trying to learn it.

Thanks.
Regards.

Stefano

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Problem with xTaskCreate in C++...

Postby kolban » Thu Mar 15, 2018 10:34 pm

In your code, the function blinkLedTask is not a static function. Putting this another way, the function can't be called directly outside of the context in which the "class" in which it exists is passed. Think of a C++ class as being a container that hides iplementation details. An instance of the class holds state and provides methods you can invoke to set/get the state and perform actions. For example, if I had a C++ class that models "Salary" then I might have a method called void increase(double percent). I can use it like:

Code: Select all

Salary mySalary(1000);
mySalary.increase(10.0);
to give myself a 10% increase.

Now imagine a function (X) which takes a function pointer (Y) as a parameter. When we call X, I can then invoke Y. For example:

Code: Select all

void X((void *Y)()) {
   Y();
}
but I can't call:

Code: Select all

X(Salary::increase)
Why not? ... because a C++ method outside of the class context in which it exists doesn't mean anything.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Problem with xTaskCreate in C++...

Postby WiFive » Fri Mar 16, 2018 1:05 am

You should put the static keyword in led.h not led.cpp

jeanleflambeur
Posts: 10
Joined: Sun Oct 08, 2017 4:26 pm

Re: Problem with xTaskCreate in C++...

Postby jeanleflambeur » Fri Mar 16, 2018 7:43 am

Do this:

led.h

Code: Select all

#ifndef LED_H
#define LED_H

#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

class LED
{
   public:
   LED();

   private:
   static void staticBlinkLedTask(void *pvParameter);
   void blinkLedTask();

   ...
};

#endif //LED_H
led.cpp

Code: Select all

#include "led.h"

LED::LED()
{
    ...

    xTaskCreate(&LED::blinkLedTask, "blinkLedTask", 2048, this, 5, NULL); //note that I'm passing the instance pointer ('this') to the function
}

void LED::staticBlinkLedTask(void *pvParameter)
{
	LED* led = reintrepret_cast<LED*>(pvParameter); //obtain the instance pointer
	led->blinkLedTask(); //dispatch to the member function, now that we have an instance pointer
}

void LED::blinkLedTask() //this method has a hidden argument - the 'this' pointer
{
     ...
}
The idea is that in order to call a class member function you need an instance pointer.
xTaskCreate gives you the ability to do this using the pvParameter. So we're passing the 'this' ptr to it and we're binding it to a static function.
In the static function we interpret the pvParameter to the instance ptr (a LED*) and call the corret member function.

This indirection is needed when you want to pass a member function as a callback to a C system.

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Re: Problem with xTaskCreate in C++...

Postby stefanoxjx » Fri Mar 16, 2018 9:37 am

Hi, thanks at all for answers.
I'm was wrong because I was putting "static" in header and cpp files.
With "static" only to header file I can compile, but I've a "panic" messages.

Code: Select all

Guru Meditation Error: Core  0 panic'ed (IllegalInstruction)
. Exception was unhandled.
Core 0 register dump:
PC      : 0x400d234c  PS      : 0x00060530  A0      : 0x00000000  A1      : 0x3ffb6900  
0x400d234c: LED::blinkLedTask(void*) at /home/stefano/ESP32/ld/main/./led.cpp:88

A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x800d234c  A9      : 0x3ffb68e0  
A10     : 0x000000c8  A11     : 0x00000001  A12     : 0x3ffb106c  A13     : 0x3ffb33c4  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000000  EXCCAUSE: 0x00000000  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

Backtrace: 0x400d234c:0x3ffb6900 0x7ffffffd:0x3ffb6920
0x400d234c: LED::blinkLedTask(void*) at /home/stefano/ESP32/ld/main/./led.cpp:88


Rebooting...
ets Jun  8 2016 00:22:57
If I try to use jeanleflambeur's solutions, I've compilation errors :(
I don't know reintrepret_cast.

Code: Select all

/home/stefano:~/ESP32/ld$ make
CXX build/main/led.o
/home/stefano/ESP32/ld/main/./led.cpp: In static member function 'static void LED::staticBlinkLedTask(void*)':
/home/stefano/ESP32/ld/main/./led.cpp:93:15: error: 'reintrepret_cast' was not declared in this scope
    LED* led = reintrepret_cast<LED*>(pvParameter); //obtain the instance pointer
               ^
/home/stefano/ESP32/ld/main/./led.cpp:93:35: error: expected primary-expression before '*' token
    LED* led = reintrepret_cast<LED*>(pvParameter); //obtain the instance pointer
                                   ^
/home/stefano/ESP32/ld/main/./led.cpp:93:36: error: expected primary-expression before '>' token
    LED* led = reintrepret_cast<LED*>(pvParameter); //obtain the instance pointer
                                  ^
[code]

Stefano

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Problem with xTaskCreate in C++...

Postby WiFive » Fri Mar 16, 2018 9:57 am

Probably you didn't call vtaskdelete at the end of your task

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Re: Problem with xTaskCreate in C++...

Postby stefanoxjx » Sat Mar 17, 2018 9:05 am

No, I don't call vTaskDelete, because I don't need to delete this task.

Stefano

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Problem with xTaskCreate in C++...

Postby kolban » Sat Mar 17, 2018 4:07 pm

In your post, we see that the exception was caught at led.cpp line 88. However, I couldn't tell what source statement line 88 was at. It might be beneficial to post a copy of the source to pastebin to allow us to see the offending statement.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

cpersoz
Posts: 3
Joined: Fri Feb 07, 2020 2:55 pm

Re: Problem with xTaskCreate in C++...

Postby cpersoz » Fri Feb 07, 2020 3:00 pm

@stefanoxjx, did you end up with a solution to have a running wrapper for xTaskCreate inside a C++ class?
I'm getting the same error as you and I didn't find a way to use xTaskCreate inside a C++ class yet.

Code: Select all

libs/Channel/src/Channel.cpp:279:25: error: 'reintrepret_cast' was not declared in this scope
libs/Channel/src/Channel.cpp:279:49: error: expected primary-expression before '*' token
libs/Channel/src/Channel.cpp:279:50: error: expected primary-expression before '>' token
Thanks

markkuk
Posts: 38
Joined: Wed Mar 27, 2019 11:50 am

Re: Problem with xTaskCreate in C++...

Postby markkuk » Sat Feb 08, 2020 10:34 am

cpersoz wrote:
Fri Feb 07, 2020 3:00 pm

Code: Select all

libs/Channel/src/Channel.cpp:279:25: error: 'reintrepret_cast' was not declared in this scope
That's simply a typing error, it's reinterpret_cast, not reintrepret_cast

Who is online

Users browsing this forum: davidItaly and 229 guests