In this step we will download the Linux kernel 3.8.13. This version is compatible with the real-time framework we will use. We will then prepare the Linux tree in order to include the Xenomai support.
userk@dopamine:~$ cd ~/RaspberryPi
userk@dopamine:~/RaspberryPi$ mkdir Xenomai-RPI && cd Xenomai-RPI
The Cross Compiler
userk@dopamine:~/RaspberryPi/Xenomai-RPI$ wget https://github.com/raspberrypi/tools/archive/master.tar.gz
userk@dopamine:~/RaspberryPi/Xenomai-RPI$ tar xzf master.tar.gz
Xenomai
userk@dopamine:~/RaspberryPi/Xenomai-RPI$ wget -q -O - http://download.gna.org/xenomai/stable/xenomai-2.6.3.tar.bz2 | tar -xjf -
The Linux Kernel
userk@dopamine:~/RaspberryPi/Xenomai-RPI$ git clone -b rpi-3.8.y git://github.com/raspberrypi/linux.git linux-3.8.13
userk@dopamine:~/RaspberryPi/Xenomai-RPI$ cd linux-3.8.13
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$
Apply patches
Xenomai needs special kernel support to deliver fast and deterministic response time to external interrupts, and also to provide real-time services highly integrated with the standard Linux kernel.
This support is provided by the interrupt pipeline (aka I-pipe) in the form of a kernel patch.
You can find the latest patches in the xenomai-2.6.3/ksrc/arch/arm/patches/raspberry folder.
Let’s apply the first one.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ patch -Np1 < ../xenomai-2.6.3/ksrc/arch/arm/patches/raspberry/ipipe-core-3.8.13-raspberry-pre-2.patch
Now, let’s apply the ipipe patch. Hopefully the prepare-kernel.sh script located in the scripts folder will do the job. We just need to specify the path of the target kernel source tree, the Adeos patch to apply against the tree and the target architecture.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ ../xenomai-2.6.3/scripts/./prepare-kernel.sh --arch=arm --linux=./ --adeos=../xenomai-2.6.3/ksrc/arch/arm/patches/ipipe-core-3.8.13-arm-3.patch
The above command prepares the Linux tree located at ./linux-3.8.13 in order to include the Xenomai support. From Xenomai installation guide:
Once the target kernel has been prepared, the kernel should be configured following its usual configuration procedure. All Xenomai configuration options are available from the “Real-time subsystem” toplevel menu.
Let’s apply the last patch:
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ patch -Np1 < ../xenomai-2.6.3/ksrc/arch/arm/patches/raspberry/ipipe-core-3.8.13-raspberry-post-2.patch
Kernel compilation
Clean the configuration file and check the one for the Raspberry pi.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ make ARCH=arm mrproper
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ make ARCH=arm help | grep rpi
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ make ARCH=arm bcmrpi_quick_defconfig
I2C and SPI support
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ make menuconfig
- Go to Device Drivers menu and check the I2C support pressing ‘Y’.
- Enter the I2C menu, go to I2C device interface and Press ‘M’ for module support.
- Enter the I2C Hardware Bus support menu and press ‘M’ BCM2708 BSC
- Check the SPI support pressing ‘Y’ and enter the sub menu
- Press ‘M’ near the BCM2708 SPI controller driver
Configuration Options
Frequency scaling creates issues with Xenomai timing code, as well as unpredictable run-time for your real-time threads, and possibly high latencies when CPU frequency is changed dynamically
Disable this option in CPU Power Management -> CPU Frequency scaling. Press ‘n’ to disable.
Next, disable CPU idle PM support.
CONFIG_CPU_IDLE allows the CPU to enter deep sleep states, increasing the time it takes to get out of these sleep states, hence the latency of an idle system. Also, on some CPU, entering these deep sleep states causes the timers used by Xenomai to stop functioning.
Save the configuration and cross-compile.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ make ARCH=arm CROSS_COMPILE=../tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-
The kernel image is now available to be transferred in the Raspberry Pi Boot partition. The image called ‘zImage’ is located in the arch/arm/boot/ folder. Copy it in the Boot partition.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ ls arch/arm/boot/ | grep zImage
zImage
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ sudo cp arch/arm/boot/zImage /media/$USER/Boot/zImage
Kernel modules are installed into the /lib/modules/x.y.z directory on the target system. Copy them into the SD card in /media/$USER/Root.
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$ sudo make ARCH=arm INSTALL_MOD_PATH=/media/$USER/Root modules_install
Compile Xenomai user space
userk@dopamine:~/RaspberryPi/Xenomai-RPI/linux-3.8.13$$ cd ../xenomai-2.6.3
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ PATH=$PATH:/home/$USER/RaspberryPi/Xenomai-RPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ ./configure --host=arm-linux-gnueabihf CFLAGS='-march=armv6' LDFLAGS='-march=armv6'
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ make
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ make DESTDIR=$(pwd)/RPI install
Compress the sbin, bin and lib folder and copy them to the Root partition
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ tar cjf xenomai-rpi.tar.bz2 usr/xenomai/bin/ usr/xenomai/sbin/ usr/xenomai/lib/ usr/xenomai/include/
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ sudo cp xenomai-rpi.tar.bz2 /media/$USER/Root/
userk@dopamine:~/RaspberryPi/Xenomai-RPI/xenomai-2.6.3$ cd /media/%USER/Root/
userk@dopamine:~/media/%USER/Root/$ sudo tar xjf xenomai-rpi.tar.bz2 && sudo rm xenomai-rpi.tar.bz2 && cd ..
userk@dopamine:~/media/%USER/$ sudo umount /dev/sdb1 /dev/sdb2
Finally, we have our dual kernel embedded system with Xenomai!