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.