OSEK OS - Resource Management and Priority Ceiling
If you have worked with RTOS’s before, you may have stumbled upon semaphores and mutexes, synchronization resources. OSEK does not have the likes of them, although it provides a more abstract version of a resource, with the same goal of managing concurrent access to a limited resource. First, we will take a step back and look at how tasks are scheduled by the OSEK OS. Luckily for you, the same concepts can be applied to the Autosar OS, as they are quite similar!
Task Scheduling and the Scheduler as a Resource (RES_SCHEDULER)
Tasks are activated in OSEK by two different OS services: ActivateTask
and ChainTask
. Depending on the Conformance Class chosen, the task can be activated one or more times, until a maximum number of activations defined upon system generation, and a task is only scheduled if this value is not reached. If a task is activated multiple times, it runs according to the order of activation.
Tasks will be queued for execution according to priority (with some exceptions, such as the OSEK Priority Ceiling Protocol, discussed later in the section), where 0 is the lowest priority. The scheduler is activated every time a task switch is possible, according to the scheduling policy. Of course, priorities are assigned statically and cannot be changed in runtime. In case a task is pre-empted, it becomes the first on the ready list within its current priority.
Moreover, the scheduler itself is a resource, that can be taken over and released via de OS services GetResource
and ReleaseResource
. Getting the resource scheduler means the task will block context switching until the resource is released. This can be used, for example, to protect writing to RTE buffers, which is a very fast operation and data-sensitive. You would likely not want your runnable to get preempted in the middle of writing to a buffer and causing all sorts of havoc.
If full-preemptive scheduling is chosen, releasing a resource might lead to a task switch, if a higher priority task is queued for execution.
Considerations on OSEK Resources
We have already learned at the previous sections one key resource in OSEK, the scheduler (always named RES_SCHEDULER
). Now, we will build up on that.
Resource management in OSEK has the following goals:
- Only one task or CAT2 ISR can access a resource at a given time (you can check our article OSEK OS Overview - AutosarToday (opens in a new tab) to learn about CAT1 and CAT2 ISRs).
- Priority inversion must not take place.
- Deadlocks must not occur.
- Accessing a resource cannot result in the waiting state.
Resource management can be applied to:
- Preemptable tasks.
- Non-preemptable tasks in the MIXED scheduling policy.
- Sharing resources between tasks and ISR’s.
- Sharing resources between ISR’s.
Some considerations when using OSEK resources are:
- While a resource is busy, some OS services cannot be called if a possible outcome is the waiting state, namely,
TerminateTask
,ChainTask
,Schedule
andWaitEvent
. - When multiple resources are required within a task, then the code to get and release the resources should follow the LIFO principle (Last In, First Out).
- When using resources within ISR’s is to disable the interrupts, in order to not get interrupted while accessing a resource and possibly cause problematic issues.
Problems with Resources: Deadlocks and Priority Inversion
Two of the most common problems when dealing with resources are deadlocks and priority inversion. Deadlocks (illustrated on the figure below) take place when two tasks lock each other forever. A possible occasion where this issue can occur is when a task T1 accesses a resource R1, and before unlocking this resource is pre-empted by a higher priority task T2, which locks the resource R2 and runs until a point where it waits for the resource R1, that is locked by T1, before unlocking R2. The task T1 then runs until it requires the resource R2, which is locked by T2. In this situation, none of the tasks can continue:
Overview of Deadlocks in the OSEK OS
As for priority inversion (observed in the figure below), it is the result of a lower priority task delaying a higher priority task. This can occur, for example, when a very low priority task T1 locks the resource R1, before getting pre-empted by another higher priority task T2. In the meantime, a higher priority task T3 is scheduled to execute, and runs until the point where it needs the resource R1, that is in use by T1. Since T1 gets pre-empted very often, the resource takes a long time to get released, causing an insupportable delay in the very high priority task T3:
Overview of Priority Inversion in the OSEK OS
OSEK Priority Ceiling Protocol as the Solution
To counteract these two issues, OSEK comes up with the Priority Ceiling Protocol (PCP), which you may know as priority inheritance. It works as follows:
- Each resource gets statically assigned a ceiling priority, according to the highest priority task that accesses it or is linked to it.
- When a task gets a resource, its priority will temporarily increase to the ceiling priority of a resource.
- Upon releasing a resource, its priority will be restored to its own statically assigned value.
This approach solves the aforementioned problems. If we take a look again at our examples, deadlocks will not occur because the lower priority task cannot be pre-empted by the higher priority task while owning the resource, as they both have the same priority. As for priority inversion, since the low priority task gets its priority raised to the same level as the highest priority task, it will not get pre-empted as often, hence, taking less time to release the resource.
Of course, not everything is perfect: OSEK PCP will create a delay for tasks with priorities smaller than or equal to the resource priority, which, in the worst case, can be from when the resource is locked until its release.
OSEK OS Resources and ISRs
As mentioned, OSEK resource management also applies to ISR’s. Albeit this is optional. Using resources in interrupts considers all the aforementioned steps, with the nuance that interrupts have a higher priority than all tasks. This means that when a task accesses a resource, it will inherit the priority of the task or ISR that can access or is linked to it. One example of this extension in action is in the figure below, where we have a task T1 locking a resource which is linked to the ISR1. While the resource is locked, ISR2 is triggered, but will not run until the resource is unlocked, because ISR2 has a lower priority than ISR1 and T1 inherits its priority:
OSEK OS Resources Applied with ISRs
OSEK OS Internal Resources
Lastly, OSEK also defines internal resources. This is a special category of resources that are not available to the developer and cannot be accessed via the OS services GetResource
and ReleaseResource
. These resources are strictly available via a specific set of APIs. Otherwise, they behave in the same way as the other resources (hence, priority ceiling still applies). Moreover, internal resources can only be used in tasks, and only a single one is allowed per task.
Internal resources are managed as follows:
- When a task associated with the internal resource enters the running state, the resource is locked automatically. Hence, PCP only applies within this state.
- When a scheduling point occurs, the internal resource is released. Some implementations may only limit this to task switches only.
The behaviour of tasks which are associated with the same internal resource is similar to the one observed in a group of tasks, described earlier in the section. Due to the OSEK Priority Ceiling Protocol, the running task which owns the internal resource cannot be pre-empted by the other tasks that share it.
Alright, this is our overview of the OSEK resources and the OSEK Priority Ceiling Protocol. If you have enjoyed it, remember to add yourself to the waiting list for the upcoming ebooks, where this and more topics will be included, to turn you into an Autosar machine!
Author: Micael Coutinho (opens in a new tab)
References:
© AutosarToday —@LinkedIn