Sunday 24 January 2016

Raspberry Pi real time kernel

I have recently worked on a realtime application for Raspberry Pi 2.

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.


No comments:

Post a Comment