Don’t delete RTOS objects at Run-Time!
An RTOS provides many features to an application. The most important one being task management but offers the ability for task and ISRs to coexist by allowing those to signal other tasks using semaphores and event flags, provide resource management through mutual exclusion semaphores, send messages through message queues and so on, depending on the RTOS you are using. These services are performed by APIs that act on data structures that are known as RTOS objects as shown in Figure 1. In fact, although not immediately apparent in Figure 1, a task is also an RTOS object because it is always defined by a Task Control Block (TCB).
Figure 1, RTOS Objects.
Some RTOSs require that you allocate storage for RTOS objects and, you must initialize (a.k.a. create) these objects through RTOS APIs so that your application avoids manipulating these objects. Other RTOSs, again through an API, allocate storage and initialize the RTOS object. There are advantages and disadvantages to both methods but that discussion is beyond the scope of this article. For example, to use the uC/OS-III semaphore services you would need to write the following code:
OS_SEM MySem; // Allocate storage for a semaphore : // Somewhere in your code … : OSSemCreate(&MySem, …); // Create (i.e. initialize) the semaphore : :
All RTOS objects must be created before you can invoke any of the other RTOS services acting on those RTOS objects.
Figure 2 shows how you would use the semaphore RTOS object in your application. As shown, a task or an ISR can signal a semaphore but only tasks can wait for a semaphore to be signaled. Note that in this example, I show two separate semaphores, each having its own purpose.
Figure 2, Using semaphores.
Most RTOS provides the ability to delete RTOS objects. Deleting an object simply means de-initializing it and possibly freeing up its storage. As far as the application code is concerned, it agrees that it will no longer use or reference that RTOS object! However, even though services are provided to delete RTOS objects, it is highly recommended to avoid doing this. In fact, one of the many requirements to get a safety critical systems certified is that you are NOT allowed to delete objects after they have been created!
You might ask, “Well then, why do RTOS developers provide those APIs?”. There are a few reasons for this:
One reason is consistency. If I can create an object, I should be able to delete it! In fact, in some cases, your application might create a task for the sole purpose of bringing up your system. Once up, the task would no longer be needed and would delete itself. However, I generally recommend keeping such a task and possibly using it as a system monitor task or something else in your application. Creating and deleting RTOS objects is oftentimes expensive (CPU cycles), especially when it comes to tasks, although in the case of a startup task, the overhead might have little impact.
If your system makes use of a Memory Protection Unit (MPU) and the MPU detects either a stack overflow or an access violation then, you might have no other choice but to take some subsystems down or, possibly the whole thing. In this case, whether you can delete RTOS objects and restart them depends on what causes the fault and whether such a system can be restarted. For example, it could be possible to restart a user interface, communications, and other support functions but, if the fault occurs in a control system, then you might not have a choice but to perform a controlled shutdown where ISRs, tasks, and I/Os are placed in a safe state rather than do something as drastic as a reset. In a shutdown sequence, RTOS objects would be deleted in a carefully designed order to avoid damaging equipment and especially hurting personnel.
Like anything else, you need to understand the implications of using RTOS services including and especially those that are used to delete RTOS objects.