Document fait avec Nvu Document made with Nvu

Technical pages
The Real-Time kernel



The real-time kernel developed in this system is relatively simple. The principle is to make a scan of a task descriptors chained list every millisecond. Those descriptors contains 5 informations by task:

  • a word (16 bits) giving the task priority level what allows to have 65535 different levels. The level 0 is reserved to the FORTH interpreter/compiler
  • a word (16 bits) giving the duration in millisecondes (up to 8192) to wait before launching task. This number is initialized in every activation of the task (instruction " T_ACTIVE " or "T_PERIODE") and decremented at every millisecondes by the real-time kernel. Task is launched when its value is zero and when the priority level is superior at the level of tasks in the course of execution. This value is put in "-1" when task is effectively launched.
  • a long word (32 bits) giving the address of the following task descriptor.
  • a word (16 bits) giving the task periodicity in milliseconds (up to 8192) when it is initialized with the instruction "T_PERIODE".
  • a word (16 bits) giving the next duration in milliseconds (up to 8192) to wait before lauching again the task with the instruction "T_ACTIVE".

At every millisecond, the real-time kernel increments the variable "TEMPS" and scans this list pointed by the variable "TACHE". The priority level of the current executed task is stored in the variable "PRIORITE". The list is automatically ordered by decreasing set of priorities in order to optimize the execution times of the priority tasks.

If the scanned priority level is null, it considers that there is no task to manage. Otherwise, it reads the number of milliseconds.

If the number of millisecondes is strictly superior to zero, it decrements its and jumps to in the following task. If it is negative, it is that task is sleepy. If it is zero, it compares the priority level with tha wich is memorized.

If the priority level of the new task is lower or equal at the memorized level, the sequencer only decrements the counters of the following tasks.

In the end of the scanning, the sequencer examines memorized address. If it is zero, it is that no task must be launched. Otherwise, it pushs in the return stack the priority level in the variable "PRIORITE" which is then loaded with the new level. It launches then the execution of the new task. Once ended task, it pulls from the return stack the previous priority level and stores it in variable "PRIORITE".

The experts will have understood it, so that it works, the real-time kernel is recursive.


- TEMPS adresse

Variable containing the value of a free counter ( 32 bits) incremented all the millisecondes by the real-time kernel

- PRIORITE adresse

Variable indicating the current level of priority to the real-time kernel

- T_SUSPEND adresse

Variable allowing to suspend the real-time kernel (if different from 0)

- TACHE adresse

Address of the beginning of the list chained by the tasks of the real-time kernel

- TACHE: "name" -

Task definition header, word following this instruction gives the name of the task
This definition will be ended with the instruction ";"
WARNING: a task has to leave the stack in the same state before and after its execution (what does no prevent it from using it)

When task is called with its name, it returns only the execution address

tâche T_EXECUTE -

Running of the specified task (used for debugging)

task, level T_AJOUTE -

Addition of the task specified in the tasks tablewith the specified priority level (1 - 65535)

task, millisecondes T_ACTIVE -

Activation of the specified task in the specified number of millisecondes (1 - 8192)

millisecondes, tâche T_PERIODE -

Periodic activation of the specified task in the specified number of millisecondes (1 - 8192)

task T_RETIRE -

Supression of the specified task from the tasks table


List tasks managed by the real time kernel with priority level and activation state


The real-time kernel described in this page is effective by its simplicity of functioning. This does not go without requiring a certain rigour of the developer.

It is indeed in the developer to administer correctly the various durations of tasks execution and their sleeping. It is necessary to consider that the more task is priority, the more it must be quickly executed and more the sleeping duration must be long (proportionally) to allow the execution of the leas priority tasks.

For example, a peripheral managemen task will be of high priority and will content with putting into dialogue with the system through a first in-first out stack.

On the other hand, a printing task, relatively long because data must in dress rehearsal be converted (picture for example) in the size of the printer which, most of the time, is relatively slow, will be as for it of low priority with of numerous injury time optimized according to the time of answer of the printer.

In the system presented on this site, all the tasks making access to the graphic screen are for the same priority level, fixed arbitrarily to 32768, what allows to synchronize refreshment of the various windows. The tasks peripherals access tasks, as serial link, are so of level superior to 32768 and thorough tasks, as the printing, are of level lower than 32768.


Better to dread the possibilities of the real-time kernel, here is a simple program which uses all the tasks management instructions.

It is about a program allowing to emit a tone (instruction " BELL ") all the seconds.

The edition window gives the contents of the program. Instruction " BIP_ON " declares task " T_BIP " in the tasks table and instruction " BIP_OFF " allows to remove it (useful when that begins to unbearable being).

It is also possible to use the instruction T_PERIODE wich activate and run again automaticaly the task: