Posted by Jerry Durand
on May 23, 2012
I'm in the process of moving all my projects from another RTOS to FreeRTOS and have a question on deleting
In the old RTOS if I tried to delete a task that had already been deleted, then it would just return a FAIL. Looking at the code here, I can't really tell what will happen if I delete the same task more than once (ie: if the handle is no longer valid).
I have a work-around but want to know if there's a clean way of handling this.
Posted by Richard Damon
on May 24, 2012
In FreeRTOS a task handle is really a pointer to the TCB for the task. When you delete the task, that TCB is freed, and any subsequent access invokes "undefined behavior". If you delete it again, it will be freed again, which for many libraries will corrupt the free store, so not a good idea.
I would suggest that you store the handle in a variable that you can zero after you delete the task, and that way you can check if the task has already been deleted.
Posted by Ken Pettit
on May 24, 2012
Richard is of course the expert on FreeRTOS, but I can say that deleting a task more than once with vTaskDelete would be a bad thing for the following reasons:
1. The vTaskDelete routine performs linked list manipulation that would cause corruption during the 2nd (or 3rd, etc.) call to vTaskDelete, even if the task were still valid.
2. You don't know when the task is actually deleted as this occurs in the idle task as a "clean-up operation". This means the task handle may be invalid the 2nd time you call it.
3. When the task is deleted, the TCB and stack are both freed, thus putting their memory regions back into the heap. That memory could have been reallocated and over-written before the 2nd vTaskDelete is called, so it isn't possible to track valid / invalid task status in the TCB.
The way I usually handle deletion of tasks is probably a bit different that usual. In my port layer, I always initialize my task's initial stack frames with a valid return address to a "catch function" that performs a "vTaskDelete" followed by a for (;;) loop. Then when I want my task to end, I send it via a mutex or global variable, and the task simply 'returns'. Note that is ONLY works because I modify the port layer for my applications (I use mostly ARM processors, so this mean setting the LR (Link Register) in the initial stack frame).
If you *absolutely* had to have a way of support multiple deletes from within the OS, it probably wouldn't be too hard to extend task.c to add a new xList to track valid xTaskHandles and modify vTaskDelete to first search that new list before attempting to delete the task. You would also need to add a new xListItem to the TCB and be sure to remove the xTaskHandle from the list from the prvDeleteTCB function.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.