One of the steps to achieve the goal was to enable the realtime scheduler policies in the Linux kernel.
In this case I have selected the SCHED_FIFO policy.
The behaviour of a process scheduled with this policy is that when it becomes runnable it will be inserted in the list of SCHED_FIFO processes. It will stay running until another process in the SCHED_FIFO policy with a higher priority becomes runnable.
For more information refer to the sched_setscheduler function documentation.
In this post I am going to show you how to build a kernel with the PREEMPT-RT profile enabled.
Cause the limited Raspberry Pi resources, I decided to cross-compile the kernel on an Ubuntu system. Thus i have setup the compiling environment on a VirtualBox virtual machine on my Intel Core i7.
The VM is configured with 2 cores and 4 GB of RAM. Make sure to define the Virtual Hard Drive maximum size to at least 20 GB.
From this point I will assume that you have a running and updated Ubuntu 15.10 desktop.
Let's start
Download the kernel sources from the raspberry git repository (~ 160 MB).
Before continuing please bear in mind that the RT-Kernel project provides a specific version of the patch for a specific version of the Linux kernel. So, before downloading a version of the kernel, check if the RT patch is available. In my case I have patched the linux-rpi-4.1.y (Linux 4.1.15) branch sources with the patch-4.1.15-rt17.patch.
~ $ git clone -b rpi-4.1.y https://github.com/raspberrypi/linux.git
Or downloading the archive:
~ $ wget https://github.com/raspberrypi/linux/archive/rpi-4.1.y.zip
~ $ unzip rpi-4.1.y.zip
~ $ mv linux-rpi-4.1.y linux
Download the raspberry tools from the raspberry git repository (~ 300 MB):
~ $ git clone https://github.com/raspberrypi/tools
Or downloading the archive:
~ $ wget https://github.com/raspberrypi/tools/archive/master.zip
~ $ unzip master.zip
~ $ mv tools-master tools
Download the version of RT-patches relative to the kernel version:
~ $ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.1/patch-4.1.15-rt17.patch.xz
Setup the GCC environment:
~ $ export CCPREFIX=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
Test GCC:
~ $ ${CCPREFIX}gcc -v
This should output the version of GCC .
Apply the RT patch:
~ $ cd linux
~/linux $ xzcat ../patch-4.1.15-rt17.patch.xz | patch -p1
Compile the kernel:
It is a good idea to start from an existent configuration. Connect to your Raspberry Pi and download the current configuration:
~/linux $ scp pi@raspberrypi:/proc/config.gz .
Extract the config file:
~/linux $ gunzip -c ../config.gz > .config
Bootstrap the kernel configuration using the provided .config file:
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig
Start the kernel configuration utility and enable the Full real-time profile:
~/linux $ sudo apt-get install libncurses5-dev
~/linux $ make menuconfig
Build the kernel (~35 minutes):
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} make
Consider adding the -j n option to the command line to compile more than one file at time.
Generate kernel modules:
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=../modules make modules_install
Create a new uncompressed kernel image:
~/linux $ cd ../tools/mkimage
~/tools/mkimage $ ./imagetool-uncompressed.py ../../linux/arch/arm/boot/zImage
~/tools/mkimage $ mv kernel.img ../..
Create an archive for all modules:
~ $ cd modules
~/modules $ tar czf modules.tgz *
~/modules $ mv modules.tgz ..
Deploy the new kernel on the Raspberry Pi:
~ $ scp ./kernel.img pi@raspberrypi:/tmp/kernel.img
~ $ scp ./modules.tgz pi@raspberrypi:/tmp/modules.tgz
Complete the deployment in a terminal on the Raspberry PI.
~ $ cd /
/ $ sudo mv /tmp/kernel-test.img /boot
/ $ sudo tar xzf /tmp/modules.tgz
Pwew! Hope you will find this guide useful for your next Raspberry real-time project.