Home > Enterprise >  Passing 'this' pointer to a static method in a parent class
Passing 'this' pointer to a static method in a parent class

Time:01-30

I am writing an embedded application using freeRTOS and I'm trying to do it in a neat, object-oriented fashion.

To start a FreeRTOS task from within an object, you need to give it a static function. In order to make it possible to use non-static variables inside that function, I've been implementing it in the following way:

void ModeSwitcher::loop(){
    // Can use any member of the ModeSwitcher class here
}

void ModeSwitcher::runner(void* parameter){ // declared as static in header
    ModeSwitcher* ref = static_cast< ModeSwitcher *>(parameter);

    while(1){
        ref->loop();
    }
}

void FlightMode::start(uint8_t core_id) {
    xTaskCreatePinnedToCore(
    runner,           // Task function
    "switcher",       // String with name of task
    2000,             // Stack size in bytes
    this,             // Parameter passed as input of the task
    1,                // Priority of the task
    &this->xHandle,   // Task handle
    core_id           // The cpu core to use
    );
}

As you can see, the static runner is passed to rtos, which can on the other hand pass 'this' pointer back to runner. Thanks to that I can put all my code neatly in the loop and just call it by reference.

However, now I have two almost identical classes. The only difference is the code inside the 'loop'. So I would like to put my start and runner methods in a base class and the loop in a derived class. I imagine it can most likely be written in a similar way. However I can't get it to work. In my had it looks somewhat like that:

base_mode.cpp :

BaseMode::BaseMode(const char* name, void* ref) : task_name(name), reference(ref) {

}

void BaseMode::start(uint8_t core_id) {
    xTaskCreatePinnedToCore(
        runner,           // Task function
        task_name,        // String with name of task (by default max 16 characters long)
        2000,             // Stack size in bytes
        reference,        // Parameter passed as input of the task
        1,                // Priority of the task
        &this->xHandle,   // Task handle
        core_id 
    );
}

void BaseMode::runner(void* parameter){
    BaseMode* ref = static_cast<BaseMode *>(parameter);

    while(1){
        ref->loop();
    }
}

ground_mode.cpp :

void GroundMode::loop(){
    // Again, should be able to do whatever is desired here
}

GroundMode::GroundMode() : BaseMode("ground_mode", this){
    
}

It doesn't work, because there's no loop function declared in base class. If I declared one, it would be used instead of the one inside the derived class. So how can I fix this? Thanks in advance.

CodePudding user response:

Declaring a virtual loop function in BaseMode worked. Forgot these even existed.

  •  Tags:  
  • Related