Microprocessors Laboratory - Exercises page

UFSC/LISHA - Author: Hugo Marcondes, Wolfram Stacklies and Thiago Leao Moreira

Real Time Operating System

This work consists of compiling and running a Real Time Operating System on an AVR micro-controller. We will run benchmarks ensuring that all of the real time constraints are satisfied.

Some RT OS's

There are several implementations of RTOS available for download. We considered the following free implementations :

  1. AVRX
  2. UROS
  3. proc
  4. Free RTOS
  5. RTK
The RTOS we selected for evaluation in this work is the RTK RTOS, which provides the best integration of the AVR microprocessor family and GCC avr compiler. The other systems are only partially available for other AVR compilers like WinAVR and IAR. The AVRX was a port to the GCC compiler but we encountered some problems with file names (case sensitive X case insensitive) and parts of the assembler code.

RTK - Dr. Tak's Real Time Kernel

The Real Time Kernel is a miniature kernel for very small systems, providing support for preempted scheduler, priority levels and blocking and non-blocking semaphores.
The whole OS implementation consits of two files, timer.S (handling the timer interruption for time-slice scheduler) and rtk.S (providing the rest of the systemfunctions).

The process of compilation and building the test applications is straight-forward. The code is written using the header files coming with the rtk. After compiling your application, rtk.S and timer.S (if needed) have just to be linked together and to be converted to an elf executable in ihex format.

Applications

All applications configure a timer for the scheduler. The 16bit-Timer1 of avr at90s8515 was used for this job, and it was configured to create an interrupt @5Khz. The kernel tick (the OS time measure unit) was configured with a frequency of 1Khz, so 1 kernel tick corresponds to 1 ms. Those two values, as also the ISR used by the OS are defined using preprocessor MACROS passed via command line on compile time. The following shows the configuration used:

-DTICK_FREQ=1000 -DISR_FREQ=5000 -DTIMER_ISR=SIG_OUTPUT_COMPARE1A

The preemption slice time is configured in the source code of an application, through the rtkSliceScaler variable, with size of 8bits and defines the number of ISR invocations to occur before preemption. This scale can be modified at runtime. We configured all applications with a scale of 100 ISR, this means that a preemption will occur about every 0.020 seconds (20 ms).

Other macros are used to configure the system, as listed below:

RTK_NUMQUEUES: This macro defines the number of priority queues. If not defined, it is set to 4.

TIMER_RTK_PREEMPT: When this macro is defined, the timer ISR defined in timer.S includes code to perform time slicing.

TIMER_APP_CALL: If this macro is defined, it is the name of an application defined function that attaches to the timer ISR. If this macro is not defined, timer.S assumes there is no application defined logic to execute in the timer ISR.

App1 - main.test1.c

The first test application, instantiates 7 threads. The main thread is responsible to create the other threads, which are launched with distinct priority. We defined four levels of priority. The first of higher priority is used by the main thread, the other 3 priority levels by the other threads, two threads per priority level. Since the first thread has more priority, after creating the other threads, has to kill himself, thus enabling lower priority threads to be scheduled. Each thread lives for a certain time and then kills himself.

App2 - main.test2.c

The second test made is a simple application running two threads. The one with higher priority is responsible to turn led0 on/off. The thread sleeps 1 second each iteration, leaving a time slice for the second thread that runs with lower priority and only lights the led7. This was implemented using the rtkThreadSchedule routine.

App3 - main.test3.c

The test is almost the same as the other application, but now we add another low priority thread to run on system. A semaphore was used to access a shared variable which stores the state (led on/off) of the high priority thread.

App4 - main.test4.c

This is the first version of our final test application, for which we had the idea at the beginning of the project. In this application we use a high priority thread responsible to manage the application user interface. This thread reads the buttons on STK500, and starts a thread responsible to turn on the led corresponding to the pressed button and turn off the others. If the thread is already started, pressing the button will cause the kill of the corresponding thread.

The main thread sleeps for 50 milliseconds on each interaction, leaving some time for the other threads (with lower priority) to run.

In this application 6 threads are launched; three with higher priority (but lower than the main thread) and other three with lower priority. Running this tests we can observe the functionality of the RTOS, creating and destroying threads with different priorities.

App5 - main.test5.c

This is the same that the App4, but now we use three levels of priority for the threads lighting the LEDs, two threads with priority 1, two threads with priority 2, and two with priority 3.

Conclusions

The RTOS requirements are satisfied by RTK. Looking for an small rtos, rtk may be a good choice. The Process of installation and compilation is straight-forward. There comes no memory manager with the rtk, what is no problem on small systems, however may raise problems using larger ones. We did not measure the overhead caused by the scheduler. This requires a modification at the rtk source code and was not in the scope of this project.
Warning: Undefined array key "PATH_TRANSLATED" in /var/www/intranet/teaching/esl/ine5349-2004-1/work/g7/index.php on line 25

Warning: opendir(/rtos): Failed to open directory: No such file or directory in /var/www/intranet/teaching/esl/ine5349-2004-1/work/g7/index.php on line 26