OSEK OS in Practice Part 2

Micael Coutinho,autosarbswos

Now that we learned how to use tasks, events and ISR's, we dive into counters, alarms, shared resources and hooks, in the backbone of the Autosar OS

In our previous articles OSEK OS Overview (opens in a new tab) and OSEK OS in Practice (opens in a new tab), we discussed all the components of the OSEK OS and dove into details regarding tasks and ISRs, by specifying the available APIs, their OIL description and peculiarities, respectively. Today, we will follow the same pattern and learn more about counters, alarms, the way OSEK OS handles shared resources and OS hooks.

Without further ado, let's start. Counters and alarms are OSEK OS's way of providing the ability to process recurring events. Recurring events are generated by counters, which will trigger alarms in return, to provide the recurring functionality to the application. Some common functionalities are task activation and event setting.

A counter is a component which abstracts you from a ticking source in the system. The ticking sources are dependent on the underlying hardware, where the counter is a standard component in the OSEK OS. There is always one counter in the OS, being the SystemCounter. You cannot modify a counter, as they are read only. But you can work with them at your own taste by using alarms. With an alarm, you can mask their value to your needs, and a hardware interrupt always has to be associated with a counter. There are 3 values that specify a counter:

A counter can be defined in OIL as such:

    Counter myCounter {
        TICKSPERBASE        = 2;
        MINCYCLE            = 10;
        MAXALLOWEDVALUE     = 100;
    };

In the former example, we have a counter named myCounter that has will increment itself after 2 ticks of its underlying ticking source, trigger an alarm every 10 counts and overflow at 100. Now, let's move on to alarms.

As we specified before, an alarm works together with a counter. The alarm performs an action, when triggered by the counter. Each alarm is associated with one counter, but a single counter can serve for multiple alarms at once. The alarm is set every time the counter reaches its cycle value, and can, out of many things, activate a task, set an event or just call an alarm handling function. The latter is declared as such:

    ALARMCALLBACK(MyAlarmFunction) {
        // alarm servicing goes here
    }

Alarms are handled in the same way as Tasks or ISRs by the OS, depending on the implementation. Now, let's look at the APIs available for alarms:

A possible description in OIL for an alarm can be as follows:

    Alarm myAlarm {
        COUNTER         = myCounter;
        ACTION          = ACTIVATETASK {
            TASK            = myTask; 
        };
        AUTOSTART       = TRUE {
            ALARMTIME       = 2;
            CYCLETIME       = 20;
            APPMODE         = myAppMode;
        }
    }; 

In the former example, we create an alarm named myAlarm based on the counter myCounter, which will activate the task myTask. We also configure it to start automatically, by setting an alarm time of 2 and a cycle time of 20.

Now, let's talk about resource sharing with operating systems and their main issues. It's a very common thing to have hardware and software resources being used across multiple tasks and ISRs (well, ISR2's in the OSEK OS). Usually, resource management systems, such as mutexes, are created to ensure the same resource is not being used by multiple tasks / ISRs at once, ensuring the resources are always in a deterministic state when we access them. The problem with shared resources such as the mutex are phenomena such as priority inversion and deadlocks. The first is due to a lower priority executable entity locking a resource and blocking execution of a higher priority executable entity, delaying the execution of the higher priority entity. The latter happens when two entities are delaying each other's execution infinitely because they want locked resources by each other.

To avoid these aforementioned problems, the OSEK OS implements a priority ceiling protocol, where each resource is statically assigned a ceiling priority. This priority shall be at least the same as the highest priority task that accesses it. When a task requires such resource and its priority is smaller than the ceiling priority of the resource, until the task releases the resource, its priority is set to the ceiling priority of the resource temporarily, until it releases the resource.

There are two API calls to deal with resources:

A resource can be described in OIL as such:

    Resource myResource {
        RESOURCEPROPERTY    = STANDARD;
    };

Lastly, let's talk about hooks. These are functions that the OS will allow you to call when certain states are reached. These are optional, but they can be very useful to act upon specific states. Moreover, these hooks have a greater priority than all tasks, cannot be preempted by ISR2's, and are able to use a subset of OS services. These hooks are:

Alright, now that we know more about the OSEK OS, you will be in a better position to understand the Autosar OS, as the OSEK OS served as the base for it. If you want ot play around with the OSEK OS, you can download the TrampolineRTOS (opens in a new tab) and read the RTA-OSEK manual.

Author: Micael Coutinho (opens in a new tab)

References:

© AutosarToday —@LinkedIn