**5. Periodic tasks**

The task concept is an abstraction of a program text. There are roughly three approaches to periodic tasks, depending on the primitives the operating system provides. Figure 5 illustrates the possible implementations of periodic tasks, where function *fi*() represents the body of task *τ<sup>i</sup>* (i.e. the actual work done during each job of task *τi*).


Fig. 5. Possible implementations of a periodic task.

In Figure 5.a, the periodic behavior is programmed explicitly while in Figure 5.b this periodicity is implicit. The first syntax is typical for a system without support for periodicity, like *μ*C/OS-II. It provides two methods for managing time: *GetTime*() which returns the current time, and *DelayFor*(*t*) which delays the execution of the current task for *t* time units relative to the time when the method was called. As an important downside, the approach in Figure 5.a may give rise to jitter, when the task is preempted between *now* := *GetTime*() and *DelayFor*().

In order to go from Figure 5.a to 5.c we extract the periodic timer management from the task in two functions: a registration of the task as periodic and a synchronization with the timer system. A straightforward implementation of *TaskWaitPeriod()* is a suspension on a semaphore. Note that we wait at the beginning of the while loop body (rather than at the end) in case *φ<sup>i</sup>* > 0. Going from interface in Figure 5.b to 5.c is now a simple implementation issue.

Note that the task structure described in Figure 5.b guarantees that a job will not start before the previous job has completed, and therefore makes sure that two jobs of the same task will not overlap if the first job's response time exceeds the task's period.

### **RELTEQ primitives for periodic tasks**

In order to provide the periodic task interface in 5.b, we need to implement a timer which expires periodically and triggers the task waiting inside the *TaskWaitPeriod()* call.

To support periodic tasks we introduce a new kind of RELTEQ events: a *period event*. Each period event *ei* points to a task *τi*. The expiration of a period event *ei* indicates the arrival of a periodic task *τ<sup>i</sup>* upon which (i) the event time of the *ei* is set to *Ti* and reinserted into the system queue using *InsertEvent()*, and (ii) the semaphore blocking *τ<sup>i</sup>* is raised.

To support periodic tasks we have equipped each task with three additional variables: *TaskPeriod*, expressed in the number of ticks, *TaskPeriodSemaphore*, pointing to the semaphore guarding the release of the task, and *TaskPeriodEvent*, pointing to a RELTEQ period event. For efficiency reasons we have added these directly to the Task Control Block (TCB), which is the *μ*C/OS-II structure storing the state information about a task. Our extensions could, however, reside in a separate structure pointing back to the original TCB.

A task *τ<sup>i</sup>* is made periodic by calling *TaskMakePeriodic(τi, φi, Ti)*, which

