Processes and Scheduling


This document describes the currently implemented processes and their scheduling of Oberon RTS.

See this document for a few basic concepts and considerations of

  • processes
  • scheduling
  • interrupts
  • device sharing

Processes All the Way Down

All activity in Oberon RTS is executed as a process.1 This includes scheduling, command handling, and the garbage collector. Nothing “happens” outside a process. This uniformity makes run-time error handling and device sharing conceptually simpler and easier.


Processes are implemented using coroutines, not tasks. Coroutines make handling of devices easier, as the corresponding processes can be suspended at any time to, say, await a buffer to not be full, without this showing up in the processes' code as a split into different task handlers and state conditions. This is also true for “virtual devices” such as semaphores.2

Process Priority and Type

Processes are assigned a priority, and higher priority processes run before the ones at lower priority, subject to their activation conditions (period, delay, signal, etc.). Processes can change their own priority at run-time.

Each process is of a certain type, indicating its importance:

  • system process
  • essential process
  • other process

System processes and essential processes are so called vital processes.

The process type is mostly relevant for run-time error handling. As the name implies, system processes are reserved for the bare, basic system without any control program, for example the garbage collector and the command handler and user interface.

Essential processes are for the core of the control program, that is, required to implement the control logic. Other processes are auxiliary, ie. non-essential, processes that don’t need to be kept running for the control logic.

Regarding concept and implementation, process timer period (see below), priority, and type are orthogonal. For example, priority and period are not connected, ie. short periods do not automatically mean higher priority. The process designer can choose to set higher frequency processes at a higher prio, but does not have to. The same holds for the process type.


Processes are always run by the scheduler, and always yield control back to the scheduler. Processes are guaranteed to run until they yield control, even if they create or enable a process of higher priority.

Processes can be run in a periodic fashion based on a timer, but don’t have to be. A process can also await a signal from another process, or await a device-signal to run when a device is ready, or any other means to implement a well-coordinated set of processes. For example, a set of processes reading sensors run timed, and a process that evaluates the sensor data awaits a signal from each of these timed processes.

In fact, when a process is created and installed, either by a command, a start-up command, or another process, it is given a process type and priority, but no assumptions are made about the kinds of enabling triggers or synchronisation mechanics it will use. The new process will configure itself.

Upon installation, a new process simply gets enabled, hence will be activated by the scheduler as soon as possible. It then can, for example, enable and set its allocated periodic timer in its initialisation sequence, or use any other await-to-continue facility during its execution, for example a signal from another process.

Upon installation, a process is put into a linked list, which is sorted by priority. Right now, a new process of the same priority as a process already in the list will be added as the first process of that priority.3

The scheduler has two phases, Evaluation and Execution:

  • The Evaluation phase is only entered if any of the processes is ready to run, based on a simple and fast global check for all processes, ie. without evaluating single processes yet. If Evaluation is entered, the process list is traversed, and for each process is checked if its conditions to be executed are met. If yes, the process is set to the ready state. Execution is set to start with the first process in the list.

  • After Evaluation, the scheduler enters Execution. The process list is traversed, and processes in ready state are run. Since the list is sorted by priority, higher priority processes are run first. After each activation of one process, the global check to enter Evaluation is done. As long as Evaluation is not entered, the next ready process in the list is run, that is Execution repeats for each ready process as long Evaluation is not entered. If, or when, Evaluation is run, Execution of ready processes will again start at the beginning of the list.

All timing, including delays and timeouts, is done in the FPGA hardware, that is, no corresponding bookkeeping is required in the scheduler.

An FPGA-based device measures the times spent in Evaluation and Execution, respectively, to assess the efficiency of the scheduler. This is an experimental feature for system development, not meant/planned to be included in an actual controller application.


A process can request a (non-blocking) delay for a certain time period. It will be suspended (ie. yields control) and then reactivated after the delay period.


Processes can set-up a timeout to ensure that they get a required “go ahead” signal or reply within a specified time period. Examples would include receiving a software or hardware signal, getting access to a shared resource via a semaphore, or a reply from an external hardware device. When activated, the process can check if it was triggered by the timeout or the “go ahead” signal or reply, and take action accordingly.

That is, the responsibility of detecting the error situation when a process is “not alive” anymore, but awaits reactivating for too long (or even forever), is to be solved on the individual process level. The other common, “opposite” error situation of a process not yielding control within a defined period of time, is solved on system level using a watchdog timer.

  1. After completion of the system start-up. ↩︎

  2. Also, coroutines are fun. ↩︎

  3. Process period cannot be considered, as not all processes are run periodically. ↩︎