Yocto Raspberry Pi Tutorial

../_images/yocto_project_logo.png ../_images/raspberry-pi-logo.png

This section serves as a comprehensive guide to assist in creating and understanding the key points of a basic Safe DDS application using the Yocto Project build system for Raspberry Pi.

Note

This guide has been tested with Poky - Yocto 5.0.10 and Raspberry Pi 4 Model B. In order to get support please contact support@eProsima.com.

Note

It is recommended to first read the Getting Started section to gain a better understanding of the basic concepts and terminology used in this section.

Project Configuration

This section describes how to configure a Yocto image that includes the Safe DDS library and a sample application.

1. Download and Build Base Raspberry Pi Image

Start by downloading Poky (Yocto) and configuring it for the target architecture:

# Download Yocto
git clone --branch yocto-5.0.10 --depth 1 https://git.yoctoproject.org/poky

Note

On Ubuntu systems you might need to allow unprivileged users to run bitbake.

echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns

Initialize the build environment, add the Raspberry Pi layer, and build a minimal base image. This first build can take a while:

# Change to poky directory and clone the meta-raspberrypi layer
cd poky
git clone -b scarthgap --depth 1 https://git.yoctoproject.org/meta-raspberrypi

# Initialize a 64-bit Raspberry Pi build directory and add the meta-raspberrypi layer
source oe-init-build-env build-raspi64
bitbake-layers add-layer ../meta-raspberrypi

# Basic Raspberry Pi 4-64 configuration
echo 'MACHINE = "raspberrypi4-64"' >> conf/local.conf
echo 'IMAGE_FSTYPES += "wic.bz2"' >> conf/local.conf
echo 'ENABLE_UART = "1"' >> conf/local.conf

# Build a minimal image as a sanity check (this can take a while)
bitbake core-image-minimal

2. Create Safe DDS Layer

Create a custom layer for Safe DDS and add it to the build:

# From the build directory (poky/build-raspi64)
bitbake-layers create-layer ../meta-safedds
bitbake-layers add-layer ../meta-safedds

3. Create Safe DDS Recipe

Create the recipes for the Safe DDS library and the getting-started application inside the newly created layer with the following structure:

meta-safedds/
├─ conf/layer.conf
└─ recipes-safedds/
    ├─ safedds/
    │  ├─ safedds.bb
    │  └─ files/                 <--- Add Safe DDS library source here
    │      ├─ CMakeLists.txt
    │      ├─ cmake/
    │      ├─ include/
    │      └─ src/
    └─ safedds-getting-started/
        ├─ safedds-getting-started.bb
        └─ files/                <--- Add Getting Started app source here
            ├─ CMakeLists.txt
            ├─ include/
            └─ src/

Populate the safedds.bb file with the following content:

SUMMARY = "Safe DDS"
DESCRIPTION = "Recipe for the Safe DDS Library"
LICENSE = "CLOSED"

SRC_URI = "file://CMakeLists.txt \
           file://cmake/ \
           file://include/ \
           file://src/"

S = "${WORKDIR}"

inherit cmake

# Configure Release builds by default
EXTRA_OECMAKE:append = " -DCMAKE_BUILD_TYPE=Release"

# Package splits
FILES:${PN}-dev += " \
    ${prefix}/safedds/include \
    ${prefix}/safedds/*Config*.cmake \
    ${prefix}/safedds/*-targets*.cmake \
"
FILES:${PN}-staticdev += " \
    ${prefix}/safedds/lib/*.a \
"

# Install Safe DDS files into sysroot for use by other recipes
SYSROOT_PREPROCESS_FUNCS += "safedds_sysroot_preprocess"
safedds_sysroot_preprocess() {
    install -d ${SYSROOT_DESTDIR}${prefix}/safedds
    cp -a ${D}${prefix}/safedds/include ${SYSROOT_DESTDIR}${prefix}/safedds/
    cp -a ${D}${prefix}/safedds/lib ${SYSROOT_DESTDIR}${prefix}/safedds/
    for f in ${D}${prefix}/safedds/*Config*.cmake ${D}${prefix}/safedds/*-targets*.cmake; do
        [ -f "$f" ] && cp -a "$f" ${SYSROOT_DESTDIR}${prefix}/safedds/
    done
}

Similarly, populate the safedds-getting-started.bb file with the following content:

SUMMARY = "Safe DDS Getting Started Example"
DESCRIPTION = "Recipe for the Safe DDS Getting Started Example"
LICENSE = "CLOSED"

SRC_URI = "file://CMakeLists.txt \
           file://include/ \
           file://src/"

S = "${WORKDIR}"

inherit cmake

# Build-time dependency on the Safe DDS library
DEPENDS = "safedds"

EXTRA_OECMAKE:append = " -DCMAKE_BUILD_TYPE=Release"

# Install the resulting binary
do_install:append() {
    install -d ${D}${bindir}
    install -m 0755 ${B}/safedds_getting_started ${D}${bindir}/
}

Check that both packages build correctly:

bitbake safedds safedds-getting-started

4. Build Final Image with Safe DDS Layer

From the build directory, add the packages to the final image:

echo 'IMAGE_INSTALL:append = " safedds-dev safedds-staticdev safedds-getting-started"' >> conf/local.conf

Finally, build the image:

bitbake core-image-minimal

Running the Application

1. Flash Image to SD Card

After the build is complete, flash the generated image to an SD card from the build directory:

# Replace /dev/sdX with your SD card device (use 'lsblk' to identify it)
sudo bmaptool copy --nobmap tmp/deploy/images/raspberrypi4-64/core-image-minimal-raspberrypi4-64.rootfs.wic.bz2 /dev/sdX

Note

If a busy device error occurs during flashing, unmount the SD card first.

2. Run Safe DDS Application

Once the Yocto image is flashed to the SD card, insert it into the Raspberry Pi and power it on.

Log in to the system using the default credentials (username: root, password: none).

Execute two instances of the Safe DDS Getting Started application on different ports:

safedds_getting_started 8000 &
safedds_getting_started 8001

The console output should show messages similar to the following:

[DW: 0] Message: HelloWorld with index: 5
[DW: 16777216] Message: HelloWorld with index: 1
[DW: 0] Message: HelloWorld with index: 6
[DW: 16777216] Message: HelloWorld with index: 2