I had posted this on Stack Overflow here: c - Stop and restart a FreeRTOS task on another core? - Stack Overflow - but it seems this forum might be more appropriate, so I’ll repost here - hope that’s OK.
I’ll mention that in the meantime, I’ve seen Is there a way to reset = restart a task?
You can delete a task and re-create it which would essentially restart it. Why do you want to do it though?
… so I could rephrase my question as: is the task deletion and recreation still the right approach for what I describe in the post? And, I’ll mention that I want to do this, because I want to synchronize the processing done on core 1 to an external signal (an interrupt on core 0); and I also work with statically allocated tasks. Here is the the rest of the SO post:
Let’s say I work on a FreeRTOS application on an MCU with two cores. There are tasks running on core 1 of the format:
void mytask_01( void* pvParameters ) {
while (1) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sleep and wait for notification to wake
do_something_first_01();
do_something_else_02();
do_something_different_03();
// all done, go back to sleeping
}
}
So, at any given time, core 1 might be running some of these tasks - or it might be idle.
Anyways - what I want to do is: if I receive a certain interrupt on core 0, I want to stop whatever task is running; and run another initialization task, and then let the core 1 processes run as if started anew.
First problem is, I cannot tell how to find the currently running FreeRTOS task hanlde on core 1 from an interrupt on core 0: the only thing I’ve found in the API so far is RTOS task (thread) utilities: xTaskGetCurrentTaskHandle(); however it has a signature:
TaskHandle_t xTaskGetCurrentTaskHandle( void ); // The handle of the currently running (calling) task.
… but I assume this would return currently running task on “this”/“current” core - and I’d want to get the currently running task on another core.
But let’s say I obtain that task handle somehow - how can I then “stop” the currently running task? Let’s say, when the interrupt hits on core 0, it is the mytask_01()
above running on core 1, and it is executing the do_something_else_02();
function at that moment. Let’s say I get the mytask_01
task handle in this interrupt on core 0. If I just call vTaskSuspend():
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
… I assume FreeRTOS will “freeze” mytask_01
at the point of execution, that is somewhere in the do_something_else_02()
function - so if I afterwards call vTaskResume():
void vTaskResume( TaskHandle_t xTaskToResume );
… the mytask_01
would continue from the point in the do_something_else_02()
function where it was suspended. But I do NOT want that - what I want is: once the mytask_01
has been stopped/suspended, next time it is woken, I want it to start from the beginning: i.e. enter the while(1)
loop, then end up on the ulTaskNotifyTake()
and sleep - and then when woken by a notification signal the next time, the mytask_01
should start with executing do_something_first_01()
.
How can I achieve something like this?