This article deals with installing RTLinux, and creating a sample real-time module that can be loaded in it.
An operating system is responsible for managing, accessing, controlling and interacting with the computer hardware for general and special purposes. Most common PC operating systems (Windows, Macintosh, Linux and UNIX) are general-purpose operating systems (GPOS), but some tasks require special-purpose operating systems that provide specific services that are not available in GPOS. One such task is to obtain outputs from process execution in deterministic time frames. Such execution within a specific time bracket is known as real-time processing, for which you need a real-time operating system (RTOS).
In an RTOS, the basic idea is to assign the complete hardware resources to the application, and successfully execute it within a deterministic time. In GPOS, a process might be starved of CPU resources if a higher-priority process is scheduled. For example, your music file, playing in a media player, might be kicked off from the processor if the OS needs to service an interrupt. In GPOS, it’s hard to avoid random elements; execution doesn’t actually work on real-time deadlines.
RTOS take into consideration various mathematical formulas in order to execute the task; thus random elements in service availability, initialisation time and input parameters must be avoided, since they can seriously affect the real-time deadline of applications.
Many companies have worked on the development of different RTOS, including VxWorks, Windows CE, RTLinux and QNX. RTLinux (Real-Time Linux) is what I will be discussing in the course of this article, because it incorporates a beginner-friendly, fast and flexible architecture for providing hard real-time capabilities. RTLinux, developed by Wind River, is available in two variants:
- Open RTLinux (under the GPL)
- Wind River real-time core.
We will use Open RTLinux, with the freedom of the GPL (which is also free of cost). RTLinux has patches for both the 2.4 and 2.6 kernel series, but I would prefer the 2.4.x version, since it’s been extensively tested, and is almost free of bugs.
Let’s discuss the architecture of RTLinux. Figure 1 shows the traditional architecture of the general-purpose Linux system, where the kernel directly interacts with the hardware. All the interrupts are intercepted by the kernel itself.
Figure 2 depicts the design of the RTLinux system. Three important aspects are displayed by the figure:
- RTLinux sits between the real hardware and the kernel.
- It acts as the hardware for the kernel.
- It treats the kernel as a single big process.
The RT scheduler schedules the kernel on the processor. The priority of the kernel is lower compared to real-time tasks, and it can be pre-empted. All hardware interrupts are intercepted by the RTLinux layer, and if it’s not for an RT task, then the interrupt is passed to the Linux kernel as a software interrupt, when RTLinux is sitting idle.
Thus, two features are provided:
- All RT tasks will get a real-time response whenever they need resources.
- All non-RT tasks can be executed by the kernel when the RTLinux system is idle.
Configuring your system for RTLinux
Let’s now set about getting RTLinux running on a system. To test RTLinux, I have configured my system as follows:
- Pentium 4 machine running CentOS 3 (Linux 2.4.21 as the base kernel).
- ext2 for the root filesystem.
- 2 GB of RAM
Prerequisites
Download the Linux kernel source, and the RTLinux patch. Here’s the link for my chosen kernel version, and rtlinux-3.2-wr.tar.bz2
from here.
Organise the source
Move these compressed files to the /usr/src
directory and uncompress them (as root, but you already knew that!), as follows:
mv linux-2.4.21.tar.bz2 /usr/src mv rtlinux-3.2-wr.tar.bz2 /usr/src cd /usr/src tar -jxvf linux-2.4.21.tar.bz2 tar -jxvf rtlinux-3.2-wr.tar.bz2
Let’s give these extracted directories shorter, easier-to-use aliases by creating soft links to them:
ln -s linux-2.4.21 linux ln -s rtlinux-3.2-wr rtlinux
Patch it up
Apply the RTLinux patch to the vanilla kernel source, using the following steps:
cd linux patch -p1 < ../rtlinux/patches/kernel-patch-2.4.21-rtl3.2-pre3
You may see this error during patching:
patch: **** malformed patch at line 1047: *+/
If so, then edit ./rtlinux/patches/kernel_patch-2.4.21-rtl3.2-pre3
in an editor. Go to line 1047 and change the following text:
(*+/ )
to:
(+*/ )
Once again, extract the Linux source code (to revert to the original source) and then apply the modified patch, with the same commands given above.
Compile and install Linux
After the RTL patch is applied, proceed through the following steps to compile the kernel:
cd /usr/src/linux make menuconfig
In the configuration menu, choose the exact processor type. You can find the name of the processor on your machine by running the cat /proc/cpuinfo
command. Disable SMP support, and set the version information on all module symbols. Then proceed with the following code:
make dep make modules make modules_install make install
Reboot your system. In the GRUB menu, you will find a new entry for the newly compiled kernel.
Compiling and installing RTLinux
Issue the following commands:
cd /usr/src/rtlinux make menuconfig make make devices make install
Post installation
After this, run the commands to check the status of the RTLinux modules. First of all, you should run the regression test:
./scripts/regression.sh
You should get [OK]
for all the tests. If you get a [Failed]
, then it’s a fatal error; if you start RTLinux, it might crash the kernel. Something has gone wrong during the compilation and installation of the kernel.
If all tests return [OK]
, then run the following commands:
rtlinux status rtlinux start
These will install all the modules present in the /usr/src/rtlinux/modules
directory. Our own module will use only the symbols that are present in these modules.
Let’s get our hands dirty
Once RTLinux is set up, it’s ready to run a test module. To understand it better, there are a lot of examples provided along with the RTLinux patch, which you will find in the examples subdirectory. Let’s say “Hello” to RTLinux using the hello
module.
- To compile, go to the
examples
directory, and execute themake
command. TheMakefile
that should be already there will be used to create the object file. - Now run the command
insmod filename.o
, wherefilename
is the module name you want to load into the running kernel. For example,insmod hello.o
. - To view a list of loaded modules, use the
lsmod
command. - To view the messages output by the newly loaded module, use the
dmesg
command.
A code fragment decoded
This program can be found in examples/hello
. The aim of the module is to execute twice a second; during each execution, it will print the message “I’m here, my arg is 0”.
#include <rtl.h> #include <time.h> #include <pthread.h> pthread_t thread; void * start_routine(void *arg) { struct sched_param p; p.sched_priority = 1; pthread_setschedparam (pthread_self(), SCHED_FIFO, &p); pthread_make_periodic_np (pthread_self(), gethrtime(), 500000000); while (1) { pthread_wait_np(); rtl_printf("I'm here; my arg is %x\n", (unsigned) arg); } return 0; } int init_module(void) { return pthread_create (&thread, NULL, start_routine, 0); } void cleanup_module(void) { pthread_cancel (thread); pthread_join (thread, NULL); }
Now let me explain what each part of this code does.
init_module()
— The module is initialised using this function. It executespthread_create
to create a thread, and returns its success status. On successful execution ofpthread_create
, thestart_routine
function is called, with0
as its argument.start_routine()
— This comprises three components: initialisation, run-time and termination.
Initialisation
Executed when the code is run the first time after loading, the section of code written before the while
loop tells the scheduler to assign this thread scheduling a priority of one, using p.sched_priority
. It then sets the scheduler’s behaviour to be SCHED_FIFO
for all subsequent executions, using pthread
setschedparam
. Finally, it calls the function pthread_make_periodic_np
to run this thread after the given time period of 500 milliseconds.
Run-time
The block of code inside the while
loop blocks all further execution of the thread using pthread_wait_np()
. Once the thread is called again, after 500 milliseconds, it executes the rest of the code inside the while
loop. However, since this is an infinite loop, with no exit condition, unless the module is unloaded using the rmmod
command, it will keep executing the thread every 500 milliseconds.
Termination
The function *cleanup_module()*
is called when the module is unloaded using rmmod
command.
*# rmmod hello*
Then it calls pthread_cancel()
to cancel the thread and pthread_join()
to wait for the thread termination. This helps in freeing up any resources being used by the module.
Nice article
How to then copy this created operating system to another system ?
As indicated by the struck-out link, the RTlInuxFree site is down.
I searched for the rtlinux-3.2-wr.tar.bz2 file, but only got a pointer to a dodgy-sounding Chinese site. Do you have (a) a good link for the file, or (b) a copy you could share?
Regards & thanks
Thanks for your easy-to-understand words to RT-Linux.
And I wonder how the RT-Linux delays the interrupt for GP Linux kernel? The software interrupt? Do you mean a system call or sth else? I hope it can be more specific :-)
Thanks for your easy-to-understand words to RT-Linux.
And I wonder how the RT-Linux delays the interrupt for GP Linux kernel? The software interrupt? Do you mean a system call or sth else? I hope it can be more specific :-)