PREEMPT RT Install for Ubuntu 20.04

Preamble

I have recently been working with robotic systems that have a greater requirement for deterministic operation. While Ubuntu will likely never be an RTOS the PREEMPT RT patch does allow for soft real-time constraints on specified threads which can be enough of a step up for many research applications.

While there are other guides on how to do this online (some linked below) this post will present as a record for the steps I needed to follow recently for my system.

Dependencies

sudo apt-get install build-essential bc ca-certificates gnupg2 libssl-dev wget gawk flex bison dwarves

Download

Supported Linux RT kernel patches found here. Check your kernel version and find an appropriate patch.

uname -r

For my system this returns 5.15.0-76-generic so I’ll need Joseph Salisbury’s patch located here.

wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.15/patch-5.15.119-rt65.patch.xz

wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.15/patch-5.15.119-rt65.patch.sign

wget https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.15.119.tar.xz

wget https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.15.119.tar.sign
xz -dk patch-5.15.119-rt65.patch.xz
xz -d linux-5.15.119.tar.xz

Verification

You will need to get the appropriate keys for your patch maintainer.

# Main Kernel
gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org 

# Patch Maintainer
gpg2 --locate-keys joseph.salisbury@canonical.com
gpg2 --keyserver hkp://keyserver.ubuntu.com --search-keys "Joseph Salisbury"
gpg2 --verify linux-5.15.119.tar.sign
gpg2 --verify patch-5.15.119-rt65.patch.sign

Apply the Patch to the Kernel

tar xf linux-5.15.119.tar
cd linux-5.15.119/
xzcat ../patch-5.15.119-rt65.patch.xz | patch -p1

Select fully pre-emptable kernel option and just enter through the rest

cp /boot/config-5.15.0-76-generic .config
make menuconfig

Activate “Fully Preemptible Kernel (Real-Time)” option from “General setup” / “Preemption Model” then SAVE and EXIT.

Apply this fix to the .config file.

Build and Install

sudo make

Wait a long time…

sudo make modules_install
sudo make install

Real-Time User Privileges

Description of the limits conf on manpage here.

sudo groupadd realtime
sudo usermod -aG realtime $(whoami)

Edit /etc/security/limits.conf to contain…

@realtime soft rtprio 99
@realtime soft priority 99
@realtime soft memlock 102400
@realtime hard rtprio 99
@realtime hard priority 99
@realtime hard memlock 102400

Grub Settings

Edit /etc/default/grub to contain…

 GRUB_DEFAULT=saved
 GRUB_SAVEDEFAULT=true
sudo update-grub

Then reboot and choose the RT kernel from the Advanced Options for Ubuntu in Grub

sudo reboot

Assigning Priorities to System Services

You can leverage the RT kernel by setting the priority of the threads spawned by your system services (see my previous post on running ROS nodes on boot). Use the CPUSchedulingPolicy and CPUSchedulingPriority directives under the Service section of a system service. Take a look at this guide from RedHat for a run down on the options, but for robotics I’d tend to use CPUSchedulingPolicy=rr and either CPUSchedulingPriority=2-49, for CPU-bound tasks and CPUSchedulingPriority=51-98 for I/O bound tasks, see the example usage below.

[Unit]
Requires=roscore.service
After=network-online.target roscore.service

[Service]
Type=simple
User=your_robots_user
ExecStart=/usr/sbin/ros_package_auto_launch
CPUSchedulingPolicy=rr
CPUSchedulingPriority=90

[Install]
WantedBy=multi-user.target

Resources and Further Reading

Further Considerations for Real-Time Setup

See here and here.

See here for example usage or PREEMPT RT in your own code and some advice here.

Also, see realtime_tools for a real time publisher implementation.

Hey you!

Found this useful or interesting?

Consider donating to support.

Any question, comments, corrections or suggestions?

Reach out on the social links below through the buttons.