ESP32 xTaskCreatePinnedToCore usage in a class

Hi there, straight to the point.

I'm trying to use wificlientsecure to make some https requests, I want these requests to run on the esp32's second core, so they're not blocking the main thread.

But I've run into some problems trying to put the following sketch into a class.

I've removed anything not directly related to my problem, so theres no http requests being done here. It will do some work on the second core, write the result in a shared variable, and set a flag indicating it's done. Main loop thread checks the indicator and reads the result variable when its complete. To hopefully make it thread safe.

ESP32CoreTaskTest.ino

//Global Variables shared between cores
bool taskFinished = false;
int count = 0;

void setup() {
    //Start Serial Output
    Serial.begin(115200); 
    Serial.println("");

    xTaskCreatePinnedToCore(
                task,       //Function to implement the task 
                "taskname", //Name of the task
                6000,       //Stack size in words 
                NULL,       //Task input parameter 
                0,          //Priority of the task 
                NULL,       //Task handle.
                1);         //Core where the task should run 
}


void loop() {
  // put your main code here, to run repeatedly:
  if(taskFinished){
    Serial.print("Task#: ");
    Serial.println(count);
  }else{
    Serial.println("Busy");
  }
  delay(100);
}

void task( void* ){
  while(1){
    taskFinished = false;
    count++;      //do some work
    delay(250);   //do some work
    taskFinished = true;
    delay(250);   //Pretend task is done, and not really looping. We should be able to read the task result after the task has finished
  }
}

This works perfectly, they share memory and wait for tasks to be finished before reading the result.
But I cannot figure out how implement it as a class. So I can use it like this.

Task task = Task();
task.startTask();

while(!task.taskFinished)
{
   //busy
}

int result = task.count;

//Dispose the task, keep the result

Obviously the code works, so it must be turned into c++ at some point, but I dont know what that would look like.

My attempt at the code looks like this:

ESP32CoreTaskTest_Class.ino

#include "Task.h"

Task task;

void setup() {
    //Start Serial Output
    Serial.begin(115200); 
    Serial.println("");

    task = Task();
    task.startTask();
}

void loop() {
  // put your main code here, to run repeatedly:
  if(task.taskFinished){
    Serial.print("Task#: ");
    Serial.println(task.count);
  }else{
    Serial.println("Busy");
  }
  delay(100);
}

Task.cpp

#include "Task.h"

//Constructor
Task::Task(){
  
}

//Member
void Task::startTask(){

  xTaskCreatePinnedToCore(
            this->worktask, //Function to implement the task 
            "taskname",     //Name of the task
            6000,           //Stack size in words 
            NULL,           //Task input parameter 
            0,              //Priority of the task 
            NULL,           //Task handle.
            1);             //Core where the task should run 
}

//Task to run
void Task::worktask(void* _this){
  while(1){
    taskFinished = false;
    count++;      //do some work
    delay(250);   //do some work
    taskFinished = true;
    delay(250);   //Pretend task is done, and not really looping. We should be able to read the task result after the task has finished
  }
}

Task.h

#ifndef Task_h
#define Task_h

#include "Arduino.h"

class Task {
  public:
    Task(void);
    void startTask(void);
    bool taskFinished = false;
    int count = 0;
  private:
    static void worktask( void* );  
    
   
};



#endif

This throws "invalid use of member 'Task::taskFinished' in static member function" as described in the link below.

As its not quite as simple as just making it a static member. :confused:

https://esp32.com/viewtopic.php?t=5027 that I cant quite decipher.

And I did try what was suggested, but I ran into some different compile errors, so I thought I'd go back to my orignal question to myself, and post it here.

What would my original sketch look like, if it was plain c++?

Well, I've figured it out it seems.

Key clue to getting it working was here Calling xTaskCreate on C++ member function? - ESP32 Forum

Here's a working example of using xTaskCreatePinnedToCore inside a class. There's still some work left to do, fx adding proper callbacks and replacing the "work" with an actual https request.

class AsyncHTTPSRequest {

  public: 
    int testVar = 0;
    char request[100] = "";
    volatile bool taskFinished = true;
  private: 
    const int taskCore = 0;
    const int taskPriority = 1;
    TaskHandle_t Task1;
  
  public:  AsyncHTTPSRequest(void){
    
  }
  
  public: void Start(void)
  {      
    taskFinished = false;
    //Start Task with input parameter set to "this" class
    xTaskCreatePinnedToCore(
      this->httpsTask,        //Function to implement the task 
      "httpsTask",            //Name of the task
      5000,                   //Stack size in words 
      this,                   //Task input parameter 
      taskPriority,           //Priority of the task 
      &Task1,                 //Task handle.
      taskCore);              //Core where the task should run 
  }
  
  
  private: static void httpsTask(void *pvParameters)
  {   
    AsyncHTTPSRequest *l_pThis = (AsyncHTTPSRequest *) pvParameters;   
    // Handle the request here

    delay(1000); //Pretend work
    
    l_pThis->testVar = 1;

    l_pThis->taskFinished = true;
    delay(50); //Wait a little before killing task
    vTaskDelete( NULL );
  }
     
};

AsyncHTTPSRequest req;

void setup() {
  // put your setup code here, to run once:
  //Start Serial Output
  Serial.begin(115200); 
  Serial.println("");
    
  req.Start();
}

void loop() {
  // put your main code here, to run repeatedly:
  if(req.taskFinished){
    Serial.print("Done :");Serial.println(req.testVar);   //Task finished, read result variable
    while(1){delay(10);}
  }
  else
  {
    Serial.println("Busy");
  }

  delay(10);
}