Page 2 of 2

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

Posted: Sat Feb 08, 2020 12:39 pm
by cpersoz
Oh indeed, thanks @markkuk, I haven't noticed it! That solve a part of the problem. It remains one issue on the wrapper on my class.
I'm getting the following error on my xTaskCreatePinnedToCore, and it seems related to the trick described on this thread.

Code: Select all

Cannot convert 'void (Channel::*)()' to 'TaskFunction_t {aka void (*)(void*)}' for argument '1' to 'BaseType_t xTaskCreatePinnedToCore(TaskFunction_t, const char*, uint32_t, void*, UBaseType_t, void**, BaseType_t)'
Here the code of my header file,

Code: Select all

#ifndef Channel_h
  #define Channel_h

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


// Channel parameters for pulses
typedef struct {
  uint16_t tClose ;
  uint16_t tOpen ;
  bool     loop ;
} _chParam ;


class Channel
{
  public:
    Channel( uint8_t _id, uint8_t _gpio, uint8_t _gpioRegBit ) ;
    ~Channel()  {}

    uint8_t     id ;
    uint8_t     gpio ;
    uint8_t     gpioBit ;
    _chParam    Ch ;
    bool        state = false ;
    void	  runOnceTask() ;
    static void runOnceTaskW( void *pvParameter );	// Wrapper

  private:
    void        on() ;
    void        off() ;
    void 	runOnce() ;

  protected:
  
#endif /* Channel_h */
};
And this is the code of the class,

Code: Select all

#include "Arduino.h"
#include "Channel.h"

/* Constructor */
Channel::Channel( uint8_t _id, uint8_t _gpio, uint8_t _gpioRegBit ) :
id( _id ), gpio( _gpio ), gpioBit( _gpioRegBit), Ch( {100,1000,false} ), state( LOW )
{
    pinMode( gpio, OUTPUT ) ;
    gpio = _gpio ;
    gpioBit = _gpioRegBit ;
}


void Channel::on()
{
    if ( state == LOW )
    	Serial.print("On") ;
    state = HIGH ;
}

void Channel::off()
{
    if ( state == HIGH )
    	Serial.print("Off") ;
    state = LOW ;
}

//::::: Task Handling
void Channel::runOnceTask()
{
    xTaskCreatePinnedToCore(
                &Channel::runOnce,	// Function that should be called
                "Channel Run once",	// Name of the task (for debugging)
                1000,			// Stack size (bytes)
                NULL,			// Parameter to pass
                1,			// Task priority, the lowest is the lowest, 24 is the max
                this,				// Task handle - instead of NULL
                CORE_TASKS		// Core you want to run the task on (0 or 1)
                    		) ;
}

void Channel::runOnceTaskW( void *pvParameter )
{
    Channel* _channel = reinterpret_cast<Channel*>(pvParameter) ; //obtain the instance pointer
    _channel->runOnce() ; //dispatch to the member function, now that we have an instance pointer
}
void Channel::runOnce()
{
    on() ;
    // Pause the task
    vTaskDelay(Ch.tClose / portTICK_PERIOD_MS) ;
    off() ;
    // Pause the task 
    vTaskDelay(Ch.tOpen / portTICK_PERIOD_MS) ;
    // When you're done, call vTaskDelete. Don't forget this!
    vTaskDelete(NULL) ;
}
Do you have any idea of what I made wrong?
Many thanks.

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

Posted: Sun Feb 09, 2020 2:00 pm
by markkuk
You're defining a static wrapper function, but you aren't actually using it. The "this" pointer must be passed as a parameter to the wrapper function.

Code: Select all

void Channel::runOnceTask()
{
    xTaskCreatePinnedToCore(
                &Channel::runOnceTaskW,	// Function that should be called
                "Channel Run once",	// Name of the task (for debugging)
                1000,			// Stack size (bytes)
                this,			// Parameter to pass
                1,			// Task priority, the lowest is the lowest, 24 is the max
                NULL,			// Task handle 
                CORE_TASKS		// Core you want to run the task on (0 or 1)
                    		) ;
}
I didn't actually test this code, but I have used this kind of construct before.

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

Posted: Sun Feb 09, 2020 3:35 pm
by cpersoz
Thanks again markkuk, I messed up on that point, now it build correctly, but I haven't test it to see if that is working.

Do I also need to make a wrapper for the taskHandle to kill the xTaskCreate?

Thanks

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

Posted: Sun Feb 09, 2020 7:43 pm
by markkuk
Task handle is a variable, not a function so it doesn't need any wrappers.