So I'm writing this article for a couple reasons. 1) I'm doing this for my master's thesis (the real time control part), 2) I've run into a couple interesting problems so I figured posting them to the internet would hopefully help someone else searching for a solution in the future and 3) I'm a Linux newbie so its an adventure for me as well.
Now lets provide a little bit of technical background. With the 2.6 kernel there are lots of processes that are fully preemptable. So in terms of a real time system this is bad. We need what is called a 'hard real time system' which means that when the system receives an interrupt it responds within a certain deterministic period of time to it. There are two types of real time systems in this case, 'hard' and 'soft'. A simple example would be that a 'soft real time system' is like answering your cell phone, you can pick it up immediately (deterministic) you can miss the call (failing the interrupt) but still call the person back and your cell phone doesn't blow up. If you fail the interrupt for a hard real time system, like say not reacting fast enough to an obstacle in the road while driving a car, you'll hit the object and wreck your car. So failing to respond properly to interrupts in this case has dire consequences.
So our goal is to find a way to schedule our process threads in that they always start and end within a specific period of time.
Enter the Real Time Application Interface (RTAI)! So I won't go into a discussion here, but there are lots of available solutions to this real time problem. Since I'm doing this at a university I want free (and on Linux so open source). In that case you can check out Xenomai, RTAI, and PREEMPT_RT, as well as numerous others. The other benefits of RTAI are that you can link it with SciLab (open source MatLab) and use Scicos (open source Simulink) and create block diagrams that support DAQ cards and related hardware. I'm using a single board computer and not a standard DAQ that is supported by this so I'll be writing a bunch of C code instead of using a nice GUI. (Also this means that you'll have to consider looking at other guides to install those parts.)
Now to take a quick tangent, why do you care about real time systems? Well it can be fun to screw around with if you are so inclined, plus if you have a really old computer, you can use your standard parallel port to do real time i/o! So you can do real time control without purchasing a $1000+ DAQ.
So, moving on. RTAI has a good amount of documentation and install guides around in case you want to find it. This is their complete guide to RTAI 3.6 and the Scilab extensions. I used this as a general guide but I want to provide a guide that is specific to Fedora 8, as well as address some of the interesting problems I ran into. In general almost all errors were fixed by a good google search, and the guys behind RTAI respond quickly to their mail list if you ask a question.
So to get to where I am, with just the patched real time kernel and RTAI installed to where I can run real time programs, you don't need a lot (2 files). The first is the newest RTAI release, 3.6-cv is the closure version of their 3.6 software. You can download the tarball here. (The hidden thing here is that there are lots of kernel versions supported, you can find them all once you extract the tarball and check out the ../rtai/base/arch/i386/patches/... directory. ((also they support x86_64 architectures as well)) I'm using Fedora 8 because it natively supports the kernel version that RTAI supports. (We pulled a Goldilocks approach the first time, Fedora 7 upgrade to 2.6.23 which didn't work, and a Fedora 10 to a lower patch with also failed). So download rtai-3.6-cv.tar.bz2 to wherever you want. I'll be working out of /usr/src by default so keep that in mind as you follow along.
So I've unpacked rtai into /usr/src/rtai-3.6-cv . You might consider making links so its quicker, but tab-complete[1] works wonders as well.
Now because of prior knowledge I know I want to work with the 2.6.23 kernel version. Go to kernel.org and download the vanilla kernel 2.6.23.tar.bz2 (the absolute base version, no updates). Unpack it and create another link if you want
So now move the linux directory and we have to apply the RTAI patch first before we mess with the config file.
Let that run and when its done run copy over your current install config and then run make menuconfig
First in menuconfig go down and select 'Load Alternate Configuration". Load up the config file you just copied over, note that this line doesn't respond to tab-complete so type it in correctly! So now in menuconfig we want to select a couple things and either make sure they are off or won't get in the way later. (Oh god did I spend so much time fixing things that got in the way later... kernel compiles on a 367 Mhz machine take forever!)
I've pulled these directly from the RTAI documentation:
- Enable loadable module support: select “Enable module support”, “Module unloading”, and “Auto-matic module loading”. Deselect “Module versioning support”; RTAI modules are not version dependent.
- Processor type and features: Select your Subarchitecture Type (PC-Compatible) and Processor family. Select ”Preemption Model (Preemptible kernel (Low-Latency Desktop))”. You might need “High Memory Support (4GB)” if you use a PCMCIA data acquisition card. Deselect ”Use register arguments (EXPERIMENTAL)”. Possibly deselect “Local APIC support on uniprocessors[2]”.
- Power Management options: Select ACPI Support and features relevant to your hardware. Leave APM deselected. Leave CPU Frequency scaling unselected. Warning: ACPI support may be a problem on laptops that use the “screen closed” button to put the computer into sleep or standby modes.
- Bus options: Leave the default. Check the support for your hardware. Laptops need PCCARD (PCMCIA/CardBus) support and PC-card bridges. e.g. CardBus yenta-compatible bridge support
So now make sure to save your config when you exit out. If for some reason it doesn't ask if you want to save it when you exit, just 'Save As Alternate Configuration' and save it as .config .
Run make, and walk away depending on the speed of your computer. Then run the make commands and reboot into your new -rtai kernel. I wouldn't edit your grub.conf yet just it case your kernel compile doesn't boot
So now that you have rebooted into your rtai patched kernel go to your rtai directory and run make menuconfig. There aren't really any options in here you want to mess with, this is just the quickest way to get the .config file built! The only option you might want to check is the 'Menu Machine (x86): adjust Number of CPUs (default = 2)' for the obvious reasons. Exit out of this and it runs make automatically.
Now we check to make sure that you can load the RTAI modules and then you are at square 1 to start writing real time code!
If those load up without error you are good to go! Congrats, go control something!
Also if you stop here I would also consider downloading the User Guide 3.4 because it has a lot of example code and such if you aren't going to use the graphical interface in Scilab. Available here.
To come later. Writing RTAI script files and module compilation!
[1] Use tab-complete where available, I didn't write down the exact code I used in my notes but just the general outline
[2] APIC support is tricky. If your computer has an APIC (setting in BIOS) you can leave this enabled and you should be fine. The second interesting thing is that in make menuconfig the option doesn't exist at all! So I had to edit the .config file itself to manually set the _APIC=n options. Then! after running make it runs another script file for configurations which resets these! So I had to edit ./arch/i386/Kconfig and set all the _APIC settings here to 'default=n'
[3] Since I'm a Linux newbie some of that stuff can be run as user and the makes all as root. I just pretty much do things as root, which is apparently bad practice...
Now lets provide a little bit of technical background. With the 2.6 kernel there are lots of processes that are fully preemptable. So in terms of a real time system this is bad. We need what is called a 'hard real time system' which means that when the system receives an interrupt it responds within a certain deterministic period of time to it. There are two types of real time systems in this case, 'hard' and 'soft'. A simple example would be that a 'soft real time system' is like answering your cell phone, you can pick it up immediately (deterministic) you can miss the call (failing the interrupt) but still call the person back and your cell phone doesn't blow up. If you fail the interrupt for a hard real time system, like say not reacting fast enough to an obstacle in the road while driving a car, you'll hit the object and wreck your car. So failing to respond properly to interrupts in this case has dire consequences.
So our goal is to find a way to schedule our process threads in that they always start and end within a specific period of time.
Enter the Real Time Application Interface (RTAI)! So I won't go into a discussion here, but there are lots of available solutions to this real time problem. Since I'm doing this at a university I want free (and on Linux so open source). In that case you can check out Xenomai, RTAI, and PREEMPT_RT, as well as numerous others. The other benefits of RTAI are that you can link it with SciLab (open source MatLab) and use Scicos (open source Simulink) and create block diagrams that support DAQ cards and related hardware. I'm using a single board computer and not a standard DAQ that is supported by this so I'll be writing a bunch of C code instead of using a nice GUI. (Also this means that you'll have to consider looking at other guides to install those parts.)
Now to take a quick tangent, why do you care about real time systems? Well it can be fun to screw around with if you are so inclined, plus if you have a really old computer, you can use your standard parallel port to do real time i/o! So you can do real time control without purchasing a $1000+ DAQ.
So, moving on. RTAI has a good amount of documentation and install guides around in case you want to find it. This is their complete guide to RTAI 3.6 and the Scilab extensions. I used this as a general guide but I want to provide a guide that is specific to Fedora 8, as well as address some of the interesting problems I ran into. In general almost all errors were fixed by a good google search, and the guys behind RTAI respond quickly to their mail list if you ask a question.
So to get to where I am, with just the patched real time kernel and RTAI installed to where I can run real time programs, you don't need a lot (2 files). The first is the newest RTAI release, 3.6-cv is the closure version of their 3.6 software. You can download the tarball here. (The hidden thing here is that there are lots of kernel versions supported, you can find them all once you extract the tarball and check out the ../rtai/base/arch/i386/patches/... directory. ((also they support x86_64 architectures as well)) I'm using Fedora 8 because it natively supports the kernel version that RTAI supports. (We pulled a Goldilocks approach the first time, Fedora 7 upgrade to 2.6.23 which didn't work, and a Fedora 10 to a lower patch with also failed). So download rtai-3.6-cv.tar.bz2 to wherever you want. I'll be working out of /usr/src by default so keep that in mind as you follow along.
So I've unpacked rtai into /usr/src/rtai-3.6-cv . You might consider making links so its quicker, but tab-complete[1] works wonders as well.
Code:
ln -s rtai-3.6-cv rtai
Code:
tar -xvjf linux-2.6.23.tar.bz2
ln -s linux-2.6.23 linux
So now move the linux directory and we have to apply the RTAI patch first before we mess with the config file.
Code:
cd /usr/src/linux
patch -p1 < /usr/src/rtai/base/arch/i386/patches/hal-linux-2.6.23-i386-1.12-03.patch
Code:
cp /boot/config-2.6.23.1-42.fc8 /usr/src/linux
make menuconfig
I've pulled these directly from the RTAI documentation:
- Enable loadable module support: select “Enable module support”, “Module unloading”, and “Auto-matic module loading”. Deselect “Module versioning support”; RTAI modules are not version dependent.
- Processor type and features: Select your Subarchitecture Type (PC-Compatible) and Processor family. Select ”Preemption Model (Preemptible kernel (Low-Latency Desktop))”. You might need “High Memory Support (4GB)” if you use a PCMCIA data acquisition card. Deselect ”Use register arguments (EXPERIMENTAL)”. Possibly deselect “Local APIC support on uniprocessors[2]”.
- Power Management options: Select ACPI Support and features relevant to your hardware. Leave APM deselected. Leave CPU Frequency scaling unselected. Warning: ACPI support may be a problem on laptops that use the “screen closed” button to put the computer into sleep or standby modes.
- Bus options: Leave the default. Check the support for your hardware. Laptops need PCCARD (PCMCIA/CardBus) support and PC-card bridges. e.g. CardBus yenta-compatible bridge support
So now make sure to save your config when you exit out. If for some reason it doesn't ask if you want to save it when you exit, just 'Save As Alternate Configuration' and save it as .config .
Run make, and walk away depending on the speed of your computer. Then run the make commands and reboot into your new -rtai kernel. I wouldn't edit your grub.conf yet just it case your kernel compile doesn't boot
Code:
make
make modules
make modules_install
make install
So now that you have rebooted into your rtai patched kernel go to your rtai directory and run make menuconfig. There aren't really any options in here you want to mess with, this is just the quickest way to get the .config file built! The only option you might want to check is the 'Menu Machine (x86): adjust Number of CPUs (default = 2)' for the obvious reasons. Exit out of this and it runs make automatically.
Code:
make install
Now we check to make sure that you can load the RTAI modules and then you are at square 1 to start writing real time code!
Code:
insmod /usr/realtime/modules/rtai_hal.ko
insmod /usr/realtime/modules/rtai_up.ko # or rtai_lxrt.ko
insmod /usr/realtime/modules/rtai_fifos.ko
insmod /usr/realtime/modules/rtai_sem.ko
insmod /usr/realtime/modules/rtai_mbx.ko
insmod /usr/realtime/modules/rtai_msg.ko
insmod /usr/realtime/modules/rtai_netrpc.ko ThisNode="127.0.0.1"
insmod /usr/realtime/modules/rtai_shm.ko
insmod /usr/realtime/modules/rtai_signal.ko
insmod /usr/realtime/modules/rtai_tasklets.ko
Also if you stop here I would also consider downloading the User Guide 3.4 because it has a lot of example code and such if you aren't going to use the graphical interface in Scilab. Available here.
To come later. Writing RTAI script files and module compilation!
[1] Use tab-complete where available, I didn't write down the exact code I used in my notes but just the general outline
[2] APIC support is tricky. If your computer has an APIC (setting in BIOS) you can leave this enabled and you should be fine. The second interesting thing is that in make menuconfig the option doesn't exist at all! So I had to edit the .config file itself to manually set the _APIC=n options. Then! after running make it runs another script file for configurations which resets these! So I had to edit ./arch/i386/Kconfig and set all the _APIC settings here to 'default=n'
[3] Since I'm a Linux newbie some of that stuff can be run as user and the makes all as root. I just pretty much do things as root, which is apparently bad practice...