This tutorial will walk you through steps required to build custom Yocto image for STM32MP157F-DK2 board from ST. This board is based on STM32MP157 microprocessor unit (MPU) working on 800MHz frequency with Cortex M4 coprocessor, 512Mb of DDR3 and SD card for storage. Additionally this board contains Ethernet port, USB hub, WiFi/BLE module, HDMI port and 4 inch display connected using MIPI DSI interface.
Yocto sources can be retrieved using ST github repository oe-manifest. This repository contains a file called manifest which has a list of repositories which will be used to download Yocto sources.
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="github" fetch="https://github.com"/>
<remote name="oe" fetch="http://git.openembedded.org"/>
<remote name="OpenSTLinux" fetch="https://github.com/STMicroelectronics"/>
<default remote="OpenSTLinux"/>
<project name="bitbake" path="layers/openembedded-core/bitbake" remote="oe" revision="ac576d6fad6bba0cfea931883f25264ea83747ca"/>
<project name="meta-openembedded" path="layers/meta-openembedded" remote="oe" revision="05dcac98473402d87e0af73bbc2c5a6a840abe93"/>
<project name="meta-qt5/meta-qt5" path="layers/meta-qt5" remote="github" revision="5b71df60e523423b9df6793de9387f87a149ac42"/>
<project name="meta-st-openstlinux" path="layers/meta-st/meta-st-openstlinux" revision="cb736b403d0fef2a02390695613b6b4bb13ca1b7"/>
<project name="meta-st-stm32mp" path="layers/meta-st/meta-st-stm32mp" revision="ca501bd7dbe023682903ceedddaacd940b0898f4"/>
<project name="meta-st-stm32mp-addons" path="layers/meta-st/meta-st-stm32mp-addons" revision="f1a18b73343afd8dd5f9aa7f5b605d139fb9e4a8"/>
<project name="meta-st-scripts" path="layers/meta-st/scripts" revision="bc063e7af04d04aff66401eb73610381bebc49a0"/>
<project name="openembedded-core" path="layers/openembedded-core" remote="oe" revision="f7766da462905ec67bf549d46b8017be36cd5b2a"/>
</manifest>
The utility used to process manifest file is called repo and can be installed separately from googlesource.com. For this tutorial we will use Ubuntu 20.04 as host OS.
$ mkdir -p ~/.bin
$ PATH="${HOME}/.bin:${PATH}"
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
$ chmod a+rx ~/.bin/repo
Once repo is installed, let’s create the folder for Yocto sources – yocto-st.
$ mkdir ~/yocto-st
Download sources to yocto-st folder
$ cd ~/yocto-st
$ repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b kirkstone
Downloading Repo source from https://gerrit.googlesource.com/git-repo
Your identity is: Ros Spolyak <rostokus@gmail.com>
If you want to change this, please re-run 'repo init' with --config-name
repo has been initialized in /home/rostokus/yocto-st
$ repo sync
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (2/2), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 0), reused 2 (delta 0), pack-reused 2
Unpacking objects: 100% (4/4), 1024 bytes | 512.00 KiB/s, done.
Fetching: 100% (8/8), done in 3m47.792s
NOT Garbage collecting: 0% (0/8), done in 0.023s
Checking out: 100% (8/8), done in 1.005s
repo sync has finished successfully.
The repo init command will create .repo folder and initialize it based on files from remote git repository specified by -u parameter. Additionally we can provide -b flag which will select a branch or tag (to download specific tag use the following syntax -b refs/tags/openstlinux-5.4-dunfell-mp1-22-05-20).
Subsequent command repo sync will actually download the sources.
After download you will find new folder layers that contains Yocto meta layers. These layers contains all the required scripts and files which will be used to create Yocto image for specified board.
$ ll layers
total 24
drwxrwxr-x 6 rostokus rostokus 4096 гру 4 10:39 ./
drwxrwxr-x 4 rostokus rostokus 4096 гру 4 10:39 ../
drwxrwxr-x 13 rostokus rostokus 4096 гру 4 10:39 meta-openembedded/
drwxrwxr-x 11 rostokus rostokus 4096 гру 4 10:39 meta-qt5/
drwxrwxr-x 6 rostokus rostokus 4096 гру 4 10:39 meta-st/
drwxrwxr-x 8 rostokus rostokus 4096 гру 4 10:39 openembedded-core/
Before new image can be added we need to initialize Yocto environment. For this Yocto provided oe-init-build-env script which should be sourced in current console:
$ source layers/openembedded-core/oe-init-build-env
You had no conf/local.conf file. This configuration file has therefore been
created for you from /home/rostokus/yocto-st/layers/openembedded-core/meta/conf/local.conf.sample
You may wish to edit it to, for example, select a different MACHINE (target
hardware). See conf/local.conf for more information as common configuration
options are commented.
You had no conf/bblayers.conf file. This configuration file has therefore been
created for you from /home/rostokus/yocto-st/layers/openembedded-core/meta/conf/bblayers.conf.sample
To add additional metadata layers into your configuration please add entries
to conf/bblayers.conf.
The Yocto Project has extensive documentation about OE including a reference
manual which can be found at:
https://docs.yoctoproject.org
For more information about OpenEmbedded see the website:
https://www.openembedded.org/
### Shell environment set up for builds. ###
You can now run 'bitbake <target>'
Common targets are:
core-image-minimal
core-image-full-cmdline
core-image-sato
core-image-weston
meta-toolchain
meta-ide-support
You can also run generated qemu images with a command like 'runqemu qemux86-64'.
Other commonly useful commands are:
- 'devtool' and 'recipetool' handle common recipe tasks
- 'bitbake-layers' handles common layer tasks
- 'oe-pkgdata-util' handles common target package tasks
As a result, this script will create build directory with following files that need to be updated.
conf/bblayers.conf – is the file that lists all the layers and their location on filesystem.
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "7"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/rostokus/yocto-st/layers/openembedded-core/meta \
/home/rostokus/yocto-st/layers/meta-qt5 \
/home/rostokus/yocto-st/layers/meta-openembedded/meta-oe \
/home/rostokus/yocto-st/layers/meta-st/meta-st-openstlinux \
/home/rostokus/yocto-st/layers/meta-st/meta-st-stm32mp \
/home/rostokus/yocto-st/layers/meta-openembedded/meta-python \
/home/rostokus/yocto-st/layers/meta-openembedded/meta-networking \
/home/rostokus/yocto-st/layers/meta-openembedded/meta-webserver \
/home/rostokus/yocto-st/layers/meta-openembedded/meta-gnome \
"
conf/local.conf – is the file that contains all the configurations, like the target hardware, additional packages to install, etc. We need to make a change in this file and set the MACHINE variable to stm32mp1.
...
# Machine Selection
#
# You need to select a specific machine to target the build with. There are a selection
# of emulated machines available which can boot and run in the QEMU emulator:
#
MACHINE = "stm32mp1"
#MACHINE ?= "qemuarm"
#MACHINE ?= "qemuarm64"
#MACHINE ?= "qemumips"
#MACHINE ?= "qemumips64"
#MACHINE ?= "qemuppc"
#MACHINE ?= "qemux86"
#MACHINE ?= "qemux86-64"
#
# This sets the default machine to be qemux86-64 if no other machine is selected:
MACHINE ??= "qemux86-64"
...
With build environment configured, we can proceed to adding new image.
ST Yocto layers already provide several images that can be used out-of-box.
$ find ../layers/meta-st/ -name *image*.bb
meta-st/meta-st-openstlinux/recipes-samples/images/st-example-image-qt.bb
meta-st/meta-st-openstlinux/recipes-samples/images/st-example-image-qtwayland.bb
meta-st/meta-st-openstlinux/recipes-st/images/st-image-weston.bb
meta-st/meta-st-openstlinux/recipes-st/images/st-image-resize-initrd.bb
meta-st/meta-st-openstlinux/recipes-st/images/st-image-core.bb
meta-st/meta-st-stm32mp/recipes-st/images/st-image-userfs.bb
meta-st/meta-st-stm32mp/recipes-st/images/st-image-vendorfs.bb
meta-st/meta-st-stm32mp/recipes-st/images/st-image-bootfs.bb
These images are a good starting point, but once you have validated the hardware you would eventually need to start adding custom applications to your image. Although it is possible to add your applications to existing images, once you have a lot of custom apps, you would start thinking about creating your own image that only contains exactly software you need.
The images in Yocto are recipes and the same as all recipes they can be based on other files. For example, let’s create custom image that is based on existing st-image-core, but with added vim text editor.
New image must reside inside some meta layer, so let’s create new meta layer called meta-cybbed and add a st-image-cybbed.bb image file.
$ cd /home/rostokus/yocto-st/layers
$ bitbake-layers create-layer meta-cybbed
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer meta-cybbed'
$ cd /home/rostokus/yocto-st/build
$ bitbake-layers add-layer "/home/rostokus/yocto-st/layers/meta-cybbed/"
NOTE: Starting bitbake server...
Normally recipes in Yocto are located in corresponding recipes-* folders, so let’s create st-image-cybbed.bb recipe inside meta-cybbed/recipes-core/images:
$ cd ..
$ mkdir -p layers/meta-cybbed/recipes-core/images
$ touch layers/meta-cybbed/recipes-core/images/st-image-cybbed.bb
Open the st-image-cybbed.bb and add the following:
# Use core image as a base
require recipes-st/images/st-image-core.bb
# Image description
DESCRIPTION = "Example image with VIM text editor"
# Additional software to be included in image
IMAGE_INSTALL += "vim"
Now, let’s start the image build. From console type:
$ cd build
$ bitbake st-image-cybbed
Loading cache: 100% |#######################################################################################################################################################################| Time: 0:00:00
Loaded 4164 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "2.0.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "ubuntu-20.04"
TARGET_SYS = "arm-oe-linux-gnueabi"
MACHINE = "stm32mp1"
DISTRO = "nodistro"
DISTRO_VERSION = "nodistro.0"
TUNE_FEATURES = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard"
TARGET_FPU = "hard"
meta = "HEAD:f7766da462905ec67bf549d46b8017be36cd5b2a"
meta-qt5 = "HEAD:5b71df60e523423b9df6793de9387f87a149ac42"
meta-oe = "HEAD:05dcac98473402d87e0af73bbc2c5a6a840abe93"
meta-st-openstlinux = "HEAD:cb736b403d0fef2a02390695613b6b4bb13ca1b7"
meta-st-stm32mp = "HEAD:ca501bd7dbe023682903ceedddaacd940b0898f4"
meta-python
meta-networking
meta-webserver
meta-gnome = "HEAD:05dcac98473402d87e0af73bbc2c5a6a840abe93"
meta-cybbed = "<unknown>:<unknown>"
Initialising tasks: 100% |##################################################################################################################################################################| Time: 0:00:07
Sstate summary: Wanted 1991 Local 0 Mirrors 0 Missed 1991 Current 4 (0% match, 0% complete)
NOTE: Executing Tasks
Setscene tasks: 1995 of 1995
NOTE: Tasks Summary: Attempted 4857 tasks of which 0 didn't need to be rerun and all succeeded.
The image generation was successful so now we can flash the build to target HW and check how it works. Extract the SD card from STM32MP157F-DK2 and type the following command from console:
$ ./flash.sh /dev/<YOUR SD CARD>
flash.sh script convert st-image-cybbed to raw image and then flash it to SD card. The example of flash.sh is as follows:
if [ $# != 1 ]; then
echo "Please specify SD card path. Example, /dev/mmcblk0"
exit
fi
SD_CARD=$1
STM_PATH=tmp-glibc/deploy/images/stm32mp1
echo "Generating flash layout"
./$STM_PATH/scripts/create_sdcard_from_flashlayout.sh $STM_PATH/flashlayout_st-image-cybbed/trusted/FlashLayout_sdcard_stm32mp157f-dk2-trusted.tsv
echo "SD card ${SD_CARD} unmount"
umount ${SD_CARD}p*
echo "Flashing an image"
sudo dd if=$STM_PATH/FlashLayout_sdcard_stm32mp157f-dk2-trusted.raw of=${SD_CARD} bs=8M conv=fdatasync status=progress
Now insert the SD card to the board and power it on. Remember to also connect micro USB cable to onboard ST-LINK for serial connection. Once boot starts, you should see following logs in console:
$ sudo minicom -b 115200 -D /dev/ttyACM0
NOTICE: CPU: STM32MP157FAC Rev.Z
NOTICE: Model: STMicroelectronics STM32MP157F-DK2 Discovery Board
NOTICE: Board: MB1272 Var4.0 Rev.C-02
INFO: PMIC version = 0x20
INFO: Reset reason (0x15):
INFO: Power-on Reset (rst_por)
INFO: FCONF: Reading TB_FW firmware configuration file from: 0x2ffe2000
INFO: FCONF: Reading firmware configuration information for: stm32mp_io
INFO: Using SDMMC
INFO: Instance 1
...
Wait until Linux boot completes and ensure that vim editor was successfully installed by typing:
$ whereis vim
vim: /usr/bin/vim /usr/share/vim
Creating Yocto image for the board is just the first step in creating custom Yocto firmware. In the next article I will highlight how to extend image with custom applications by adding Yocto recipes
Tell us about your IoT or embedded project and our experts will gladly provide you with qualified consultation.