Calling xTaskCreate on C++ member function?

dspau1
Posts: 13
Joined: Sat Jan 14, 2017 9:25 am

Calling xTaskCreate on C++ member function?

Postby dspau1 » Thu Jun 08, 2017 4:36 am

Hi all, just wondering how to call xTaskCreate on a member function in a c++ class? The intent is as per the code below, which does not compile with the error "reference to a non-static member function must be called".

Also open to suggestions if there is a better way to achieve the same result whilst still keeping everything encapsulated within the class.

Code: Select all

class HttpServer {
	
public: void Start(void)
	{		
		xTaskCreate(this->ListenerThread, "HttpListenerThread", 2048, NULL, 5, NULL);
	}
	

	void ListenerThread(void *pvParameters)
	{	
		// Handle the request here
	}
	
};

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

Re: Calling xTaskCreate on C++ member function?

Postby kolban » Thu Jun 08, 2017 4:42 am

Howdy there,
Ive been really keen on C++ and ESP32 for a period and have been cranking out tests on encapsulating ESP-IDF in C++. Here is a GitHub of my tests so far ...

https://github.com/nkolban/esp32-snippe ... /cpp_utils

In there you will find Task.cpp and Task.h which provide FreeRTOS task encapsulation as well as WebServer.cpp and WebServer.h which may also be useful to you.

I am using Doxygen for documentation generation.


Neil
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

dspau1
Posts: 13
Joined: Sat Jan 14, 2017 9:25 am

Re: Calling xTaskCreate on C++ member function?

Postby dspau1 » Thu Jun 08, 2017 5:29 am

Thanks for the super quick reply! Taking a look at your c++ abstractions now. Sounds like an excellent asset for the ESP32 platform. I also sent you a private message.

enitalp
Posts: 60
Joined: Thu Jan 12, 2017 10:03 pm

Re: Calling xTaskCreate on C++ member function?

Postby enitalp » Thu Jun 08, 2017 1:57 pm

Code: Select all

class HttpServer {
   
public: void Start(void)
   {      
      xTaskCreate(this->ListenerThread, "HttpListenerThread", 2048, [b]this[/b], 5, NULL);
   }
   

   [b]static [/b]void ListenerThread(void *pvParameters)
   {   
   HttpServer *l_pThis = (HttpServer *) pvParameters;   
      // Handle the request here
   }
   
};

dkaufmann
Posts: 24
Joined: Wed May 17, 2017 9:06 am

Re: Calling xTaskCreate on C++ member function?

Postby dkaufmann » Fri Nov 10, 2017 4:36 pm

Hi Neil,

thank you for your code snippets, very appreciated!

I use ESP-IDF and I included the Arduino IDE as component. There I included the Modbus Library which also supports Modbus TCP which is written in C++. The library contains a modbus class, which contains a member function which is used as a task.
library: https://github.com/emelianov/modbus-esp8266

I changed my main file into a cpp file and added the main function as:

#include "Arduino.h"
#include <WiFi.h>
#include <ModbusIP_ESP8266.h>

extern "C" void app_main() {
initArduino();
...
}

Now I want convert the member function of the library as a task with xtaskcreate(...). How do I need to do it? Can I use your task snippets to do this?

thanks for your help.

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

Re: Calling xTaskCreate on C++ member function?

Postby kolban » Sat Nov 11, 2017 5:52 am

Howdy,
Unfortunately I am not familiar with the Modbus Library or Modbus TCP.

Not sure what you mean by a "member function which is used as a task". In the ESP32, the concept of task is a separate thread of control within the application. Think of it loosely as "two programs" executing simultaneously within your ESP32 environment. In C++, a class is a declaration of an object and has properties/fields and methods. Within a task (any task) if you have addressability to an object (i.e. you create one) then you can invoke its methods. If you have a class (X) which has a method (m) and you want to call that method in a task, they you would create the task, create an instance of X and then call method m within the control of the Task.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

dkaufmann
Posts: 24
Joined: Wed May 17, 2017 9:06 am

Re: Calling xTaskCreate on C++ member function?

Postby dkaufmann » Mon Nov 13, 2017 9:59 am

Hi Neil, thanks for your time. I wanted to use a method m and call this method directly as a task using freertos xTaskCreate. But now I did it the way you recommended, I just created a new task which calls this method inside the while(1) loop.
At the beginning I had problems that the task watchdog triggered. Now I added a taskDelay inside this task to avoid it. Is this the best way to do it or should I feed the task watchdog?

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

Re: Calling xTaskCreate on C++ member function?

Postby kolban » Mon Nov 13, 2017 1:47 pm

If we think of a class "X" which has member "m" ... we might declare it as:

Code: Select all

class X {
public:
   void m() {
      // code here
   }
}
we might declare an instance of X and call m using:

Code: Select all

X x = X();
x.m();
In C++ m is **not** just a reference to a function ... it also exists in the **context** of the instance of X. Where we have a C language function that expects a pointer to a function ... for example:

Code: Select all

void startTask((void *func)());
we can't call:

Code: Select all

X x = X();
startTask(x.m);
because the function "m" doesn't exist outside the context of an instance of X.

In C++, it is trivial to call C, but remember, C++ is a superset of C ... meaning you can do anything in C++ that you can do in C but in C you can't do anything you can do in C++. The ESP-IDF is a C environment and doesn't "know" C++.

In a C++ program, you can declare a function that is exposed as C ... for example:

Code: Select all

extern "C" {
   void myFunc();
}

void myFunc() {
   X *x = new X();
   x->m();
}
and then pass "myFunc" as a C function pointer.

Now, back to your watchdog issue ...

ANY code that is passed as the start routine of a Task should relinquish control back to FreeRTOS periodically ... if not, then it is effectively in a tight loop and it is only by CPU preemption that other tasks get to run. A task delay will release control back from the task.

At a high level, what is it you are doing in your task that requires a tight CPU loop? Are you polling something?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

dkaufmann
Posts: 24
Joined: Wed May 17, 2017 9:06 am

Re: Calling xTaskCreate on C++ member function?

Postby dkaufmann » Mon Nov 13, 2017 2:59 pm

Hi Neil, thanks for your detailed explanation. I think I manage the C++ to C stuff correctly now. My other questions belong to the topic task management in general:
I have different tasks which fulfill the following functionalities:
1) I2C polling 1/s (low priority), using taskDelay function to suspend task for 1000 ms -> no problem
2) Modbus_task which is in a tight loop (while 1) to serve modbus requests
3) webserver_task (see open ssl example) to serve http requests

So when I give modbus_task and webserver_task the same priority, the scheduler will switch between these two tasks. So I think I do not need to feed any watchdog because the scheduler switches between these 2 tasks. The low prio task will suspend anyway due to the taskDelay function.

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

Re: Calling xTaskCreate on C++ member function?

Postby kolban » Tue Nov 14, 2017 5:18 am

I don't know anything about ModBus .... however a good WebServer implementation will consume no task CPU cycles. A task can either be "ready to run" or "blocked". The ESP32 task scheduler should only context switch across tasks that are ready to run. So what constitutes blocked?

That would be anything waiting on an event to occur. Examples include:

o Blocked on queues
o Blocked on semaphores
o Blocked on Mutices

and ...

o Blocked on network sockets.

A good WebServer should block waiting for incoming network traffic and consume no CPU cycles until and unless a network request arrives.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

Who is online

Users browsing this forum: No registered users and 83 guests