- My thesis (made to graduate in computer sciences at the ULg)
- The goal of my thesis was to design a modular and generic embedded system. The hardware would be made of several modules and the software would be as portable as possible. The software architecture had to be the so called "real time operating system" and hence it would have to provide at least two major features:
- a scheduler that would choose the active task with the highest (fixed) priority in the system,
- and a communication scheme between the tasks (semaphores, for example).
The thesis can be downloaded here (in French): PS[PDF]. This document describes, with many details and examples, a possible solution to the problem described above.
No additional information will be provided here, check the thesis itself for details.
Let us summarize the characteristics of our real time operating system (see the thesis for details):
it contains a scheduler which, when activated, will start the execution of the highest priority active task (if any),
tasks can be started or stopped from user tasks or interrupt routines,
semaphores can be read or written and wait and signal operations can be applied to them.
it is not preemptive but cooperative, meaning that the tasks have to yield the processor to the scheduler in order for it to function properly,
it is written in pure C code (no target specific code).
Details about the way the kernel works can be found here.
The kernel source code (in ANSI-C)
An archive with the complete source code can be downloaded here: kernel.zip.
You can also have a look at each of the different files of the project:
kernel.c: contains the source code of the internal kernel function and the scheduler (function "schedule"),
kernel.h: header definitions that have to be included in the user application, in user.c or user.h; this file contains also macros that can be used in the user's application and two useful macros to parametrize the kernel: MAX_SEM which is set to the number of semaphores and MAX_TASK, the maximal number of tasks in the system,
sema.c: contains the functions specific to the semaphores handling; if the semaphores are not used (MAX_SEM not defined), this file can be removed from the project,
sema.h: header definitions for sema.c,
dispatch.c: contains the user defined function "dispatch" which makes the link between every task numbers and the code of the corresponding tasks,
dispatch.h: provided header file for dispatch.c. This file should not be modified by the user,
common.h: common definitions that have to be included both in kernel code and in user code,
user.c: user supplied tasks codes as long as the "main" function,
user.h: user supplied header file for user.c; this file must contain the prototypes for all the task functions defined in user.c.
The user.c, user.h and dispatch.c files above are given as an example. They define two tasks.
The main function starts the task number 1 (see user.c). This task executes some iterations in a loop and then starts the task 2, which has a higher priority. The scheduler, which has been called by task 1 to start task 2 will then put task 1 in an idle state and make the task 2 run.
Task 2 will also loop a bit and then it will wait on semaphore 0 (WAIT operation on this semaphore which has a value of 0, in this example). Since task 2 is not active anymore, but waiting, task 1 can resume its execution. Task 1 will perform a signal operation on the semaphore 0 and hence unblock task 2. When task 2 will terminate, task 1 will then be able to terminate too.
Task 2 tests also the operation SET_SEM, see explanations above. SET_SEM is used to set the semaphore 0 to 48. Then task 2 performs a WAIT operation to check if the value of the semaphore becomes 47, as it has to. Task 1 will read the value of the semaphore 0 by means of the GET_SEM operation. The execution of this program displays these messages (on a system equipped with a terminal, of course):
task 1 is at pos 0, loop iteration number 0
task 1 is at pos 1, loop iteration number 1
task 1 is at pos 1, loop iteration number 2
task 1 is at pos 1, loop iteration number 3
task 1 is at pos 1, loop iteration number 4
task 2 is at pos 0 0
task 2 is at pos 1 1
task 2 is at pos 1 2
Task 2 is waiting on semaphore 0
task 1 is at pos 1, loop iteration number 5
task 1 is at pos 1, loop iteration number 6
Task 2, previously waiting on semaphore 0, is restarted
task 2 is at pos 1 3
task 2 is at pos 1 4
task 2 is at pos 1 5
task 2 is at pos 1 6
task 2 is at pos 1 7
task 2 is at pos 1 8
Sem 0 value is 47
task 2 is about to exit
task 1 is at pos 1, loop iteration number 7
task 1 is at pos 1, loop iteration number 8
Sem 0 value is 48
task 1 is about to exit
Last modification: january 2004.