Yocto Raspberry Pi Tutorial¶
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