Snapping a lowlatency kernel for your Raspberry Pi

Some applications, such as real-time digital audio processing, require a system with minimum latency, usually around 2msec. This requirement can’t usually be met by common or standard linux kernels. To turn a linux kernel into a realtime or lowlatency kernel, a specific kernel configuration should be applied, or extra patches should be integrated (such PREEMPT_RT patch or XENOMAI framework).

I recently tried to snap a Digital Audio Workstation called sushi for my Raspberry pi4. Sushi is part of ELK project, a digital audio OS, XENOMAI based, which runs on x86 and Raspberry pi4. My goal would be to run sushi (+other audio packages needed by sushi, such jackd) on Ubuntu Core, fully confined, so to turn my rpi4 in a headless synthesizer that once connected to a usb piano keyboard just starts to play. The work is still in progress and can be found here.

Coming back to lowlatency kernel … to run my sushi snap on Raspberry Pi, the standard uc18 image is not suitable, the kernel should be replaced with a lowlatency one. I decided to create a new kernel with a lowlatency configuration, and create a new uc image with it.

In case you are interested to build your lowlatency uc image for rpi, follow the steps below:

  1. Install lxd, snapcraft and ubuntu-image on your ubuntu host
    sudo snap install lxd
    lxd init (just leave default values)

  2. Launch a bionic container
    lxc launch ubuntu:18.04 bionic-lowlatency

  3. Open a bash shell to the bionic container, and clone the git repo
    lxc exec bionic-lowlatency /bin/bash --

  4. Install snapcraft and ubuntu-image
    sudo apt update
    sudo apt upgrade
    sudo snap install snapcraft --classic
    sudo snap install ubuntu-image --classic

  5. Clone the rapsberry lowlatency kernel repo
    git clone https://github.com/dbruno74/linux-raspberrypi-org.git
    cd linux-raspberrypi-org

  6. Look at snap/snapcraft.yaml. Check lowlatency configuration (look for “configuring low latency”) and make modifications if needed

...
   kernel:
         ....
         kconfigs:
                    ...
                   # configuring low latency
                    - CONFIG_HZ=1000
                    - CONFIG_HZ_1000=y
                    - '# CONFIG_HZ_250 is not set'
                    - CONFIG_IRQ_FORCED_THREADING_DEFAULT=y
                    - CONFIG_PREEMPT=y
                    - '# CONFIG_PREEMPT_VOLUNTARY is not set'
  1. Snap the kernel
    snapcraft --target-arch=armhf

  2. Create the model assertion (if you don’t know how to do this, go here), name it “pi4-lowlatency-model.json”

{
  "type": "model",
  "authority-id": "<your-id>",
  "brand-id": "<your-id>",
  "series": "16",
  "model": "lowlatency-pi4",
  "architecture": "armhf",
  "base": "core18",
  "gadget": "pi=18-pi",
  "kernel": "linux-raspberrypi-org",
  "timestamp": "<timestamp>"
}
  1. Sign your model assertion
    snap sign -k <your_key> pi4-lowlatency-model.json | tee pi4-lowlatency-model.assert

  2. Build the image
    ubuntu-image snap -i 2G --extra-snaps linux-raspberrypi-org_raspi-5.4.0-1009.9_armhf.snap pi4-lowlatency-model.assert

  3. Insert a microsd card in your microsd drive and flash the image (I assume the device name of your microsd reader is “mmcblk0”)
    sudo dd if=pi.img of=/dev/mmcblk0 bs=32M

  4. Boot your ubuntu core lowlatency image!

4 Likes

Another interesting approach to low latency is PREEMPT_RT. I’ve just learned that @bugraaydogar did a great post about it, in case you are interested, check it out!