Zephyr Project™ getting started – STM32 Nucleo-64 with STM32F411RE and a docker container

Objectives

This post shows you how to use the Reliable Embedded Systems – Robert Berger e.U. Zephyr Project™ build framework to build/run/debug some basic examples for the STM32 Nucleo-64 board with an STM32F411RE.

Prerequisites

Assuming you already have the Reliable Embedded Systems – Robert Berger e.U. Yocto Project®/OpenEmbedded build framework installed you are already in a good position and can skip the next steps.

Install a minimal Build framework

Install git

sudo apt install git

Default gitconfig

gitconfig: In case you don’t already have your own you can use the one provided with here:

pushd ~
wget https://raw.githubusercontent.com/RobertBerger/manifests/master/gitconfig
mv gitconfig .gitconfig
popd

Install docker

sudo apt install docker.io
sudo usermod -aG docker ${USER}
sudo reboot

Create a directory where you have plenty of space

mkdir -p ~/projects/resy-playground
cd ~/projects/resy-playground
sudo ln -sf ~/projects/resy-playground /workdir

You might need to fix some permissions.

On the host machine

Get udev rules

We need to add udev rules to be able to flash/debug applications.

cd /etc/udev/rules.d/
sudo wget https://raw.githubusercontent.com/RobertBerger/zephyr-build-container/2021-06-14-ub20-v2.6.0/udev-rules/60-openocd.rules
--2021-06-15 12:36:15--  https://raw.githubusercontent.com/RobertBerger/zephyr-build-container/2021-06-14-ub20-v2.6.0/udev-rules/60-openocd.rules
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10941 (11K) [text/plain]
Saving to: ‘60-openocd.rules’

60-openocd.rules                                100%[=====================================================================================================>]  10.68K  --.-KB/s    in 0s      

2021-06-15 12:36:16 (88.1 MB/s) - ‘60-openocd.rules’ saved [10941/10941]
sudo udevadm control --reload-rules
sudo udevadm trigger

Get scripts to start up container

cd /workdir
git clone https://github.com/RobertBerger/zephyr-build-container -b 2021-06-14-ub20-v2.6.0
Cloning into 'zephyr-build-container'...
remote: Enumerating objects: 266, done.
remote: Counting objects: 100% (266/266), done.
remote: Compressing objects: 100% (135/135), done.
remote: Total 266 (delta 108), reused 265 (delta 107), pack-reused 0
Receiving objects: 100% (266/266), 57.44 KiB | 0 bytes/s, done.
Resolving deltas: 100% (108/108), done.
Checking connectivity... done.
cd zephyr-build-container/
git branch -a
* 2021-06-14-ub20-v2.6.0
  remotes/origin/2021-06-14-ub20-v2.6.0
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Start the Zephyr Project™ build container

cd /workdir/zephyr-build-container/non-local_scripts/
./docker_run.sh reliableembeddedsystems/zephyr-build-container:2021-06-14-ub20-v2.6.0
+++ docker ps -a -q --filter ancestor=reliableembeddedsystems/zephyr-build-container:2021-06-14-ub20-v2.6.0
++ ID_TO_KILL=
++ docker ps -a
CONTAINER ID        IMAGE                                                                  COMMAND                  CREATED             STATUS              PORTS                                              NAMES
b91b7e78b5b3        reliableembeddedsystems/icecream-container:2021-04-08                  "/usr/local/bin/icec…"   4 days ago          Up 4 days                                                              icecream_container
d0b419933f78        reliableembeddedsystems/jenkins-container:2021-05-07-jenkins-2.277.4   "/sbin/tini -- /usr/…"   4 weeks ago         Up 5 days           0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jolly_lamarr
++ docker stop
"docker stop" requires at least 1 argument.
See 'docker stop --help'.

Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop one or more running containers
++ docker rm -f
"docker rm" requires at least 1 argument.
See 'docker rm --help'.

Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers
++ docker ps -a
CONTAINER ID        IMAGE                                                                  COMMAND                  CREATED             STATUS              PORTS                                              NAMES
b91b7e78b5b3        reliableembeddedsystems/icecream-container:2021-04-08                  "/usr/local/bin/icec…"   4 days ago          Up 4 days                                                              icecream_container
d0b419933f78        reliableembeddedsystems/jenkins-container:2021-05-07-jenkins-2.277.4   "/sbin/tini -- /usr/…"   4 weeks ago         Up 5 days           0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jolly_lamarr
++ set +x
++ '[' '!' -d /home/student/projects/zephyrproject ']'
++ '[' '!' -d /home/student/projects/zephyr-projects ']'
++ docker run --rm -it --privileged -v /dev/bus/usb:/dev/bus/usb -v /home/student/projects/zephyrproject:/workdir -v /home/student/projects/zephyr-projects:/zephyr-projects reliableembeddedsystems/zephyr-build-container:2021-06-14-ub20-v2.6.0
Unable to find image 'reliableembeddedsystems/zephyr-build-container:2021-06-14-ub20-v2.6.0' locally
2021-06-14-ub20-v2.6.0: Pulling from reliableembeddedsystems/zephyr-build-container
345e3491a907: Pull complete 
57671312ef6f: Pull complete 
5e9250ddb7d0: Pull complete 
56c9410c484c: Pull complete 
13053d431dac: Pull complete 
89ed000480eb: Pull complete 
d82dedaadfe0: Pull complete 
6ded11644cb9: Pull complete 
6963058068f6: Pull complete 
9764a7a17a91: Pull complete 
274b1b4f515e: Pull complete 
2c59315a1a1d: Pull complete 
c5ea1cd9aab6: Pull complete 
6c212b274012: Pull complete 
63362f9ef9d9: Pull complete 
5a57869056ae: Pull complete 
7d1df3f64fa8: Pull complete 
82855d699043: Pull complete 
dd9094f0e0e1: Pull complete 
3f0f3c94e7f4: Pull complete 
d11da5a64a94: Pull complete 
7679827c7ab7: Pull complete 
641ededd079c: Pull complete 
e79ee36a1801: Pull complete 
4302be37b6ed: Pull complete 
500b333ae6e9: Pull complete 
beb912f5dd11: Pull complete 
a6873aa92b83: Pull complete 
cbdfe45a7cb6: Pull complete 
5a8a05cc66ed: Pull complete 
1dc44d26037c: Pull complete 
Digest: sha256:3d304bf8d30d6a9ffdd57c3582b1b0a9248e35cb7ec13463c7e675d761ae1ffa
Status: Downloaded newer image for reliableembeddedsystems/zephyr-build-container:2021-06-14-ub20-v2.6.0
Openbox-Message: Unable to find a valid menu file "/var/lib/openbox/debian-menu.xml"

ERROR: openbox-xdg-autostart requires PyXDG to be installed
user@623043a289ee:/workdir$ Xlib:  extension "DPMS" missing on display ":0".

The VNC desktop is:      623043a289ee:0
PORT=5900

press <ENTER> to get a shell in the container:

In the container

user@623043a289ee:/workdir$

Get the Zephyr Project™ source code

Utilize west to get the Zephyr Project™ source code

# get the Zephyr source code
# latest:
# west init /workdir
# specific version:
west init -m https://github.com/zephyrproject-rtos/zephyr --mr v2.6.0 /workdir
=== Initializing in /workdir
--- Cloning manifest repository from https://github.com/zephyrproject-rtos/zephyr, rev. v2.6.0
Initialized empty Git repository in /workdir/.west/manifest-tmp/.git/
remote: Enumerating objects: 580015, done.
remote: Counting objects: 100% (2260/2260), done.
remote: Compressing objects: 100% (812/812), done.
remote: Total 580015 (delta 1570), reused 1936 (delta 1442), pack-reused 577755
Receiving objects: 100% (580015/580015), 395.04 MiB | 8.97 MiB/s, done.
Resolving deltas: 100% (439889/439889), done.
From https://github.com/zephyrproject-rtos/zephyr
 * tag               v2.6.0                         -> FETCH_HEAD
 * [new branch]      backport-23821-to-v1.14-branch -> origin/backport-23821-to-v1.14-branch
 * [new branch]      backport-24971-to-v1.14-branch -> origin/backport-24971-to-v1.14-branch
 * [new branch]      backport-25852-to-v1.14-branch -> origin/backport-25852-to-v1.14-branch
 * [new branch]      backport-35597-to-v2.4-branch  -> origin/backport-35597-to-v2.4-branch
 * [new branch]      backport-35597-to-v2.5-branch  -> origin/backport-35597-to-v2.5-branch
 * [new branch]      backport-35935-to-v2.4-branch  -> origin/backport-35935-to-v2.4-branch
 * [new branch]      backport-35935-to-v2.5-branch  -> origin/backport-35935-to-v2.5-branch
 * [new branch]      backport-36178-to-v2.6-branch  -> origin/backport-36178-to-v2.6-branch
 * [new branch]      feature-seq-limit              -> origin/feature-seq-limit
 * [new branch]      main                           -> origin/main
 * [new branch]      topic-ble-llcp                 -> origin/topic-ble-llcp
 * [new branch]      topic-sensors                  -> origin/topic-sensors
 * [new branch]      topic-usb                      -> origin/topic-usb
 * [new branch]      v1.10-branch                   -> origin/v1.10-branch
 * [new branch]      v1.11-branch                   -> origin/v1.11-branch
 * [new branch]      v1.12-branch                   -> origin/v1.12-branch
 * [new branch]      v1.13-branch                   -> origin/v1.13-branch
 * [new branch]      v1.14-branch                   -> origin/v1.14-branch
 * [new branch]      v1.5-branch                    -> origin/v1.5-branch
 * [new branch]      v1.6-branch                    -> origin/v1.6-branch
 * [new branch]      v1.7-branch                    -> origin/v1.7-branch
 * [new branch]      v1.8-branch                    -> origin/v1.8-branch
 * [new branch]      v1.9-branch                    -> origin/v1.9-branch
 * [new branch]      v2.0-branch                    -> origin/v2.0-branch
 * [new branch]      v2.1-branch                    -> origin/v2.1-branch
 * [new branch]      v2.2-branch                    -> origin/v2.2-branch
 * [new branch]      v2.3-branch                    -> origin/v2.3-branch
 * [new branch]      v2.4-branch                    -> origin/v2.4-branch
 * [new branch]      v2.5-branch                    -> origin/v2.5-branch
 * [new branch]      v2.6-branch                    -> origin/v2.6-branch
 * [new tag]         v1.0.0                         -> v1.0.0
...
 * [new tag]         zephyr-v1.14.1                 -> zephyr-v1.14.1
 * [new tag]         zephyr-v1.2.0                  -> zephyr-v1.2.0
 * [new tag]         zephyr-v1.3.0                  -> zephyr-v1.3.0
 * [new tag]         zephyr-v1.4.0                  -> zephyr-v1.4.0
 * [new tag]         zephyr-v1.5.0                  -> zephyr-v1.5.0
 * [new tag]         zephyr-v1.6.0                  -> zephyr-v1.6.0
 * [new tag]         zephyr-v1.6.1                  -> zephyr-v1.6.1
 * [new tag]         zephyr-v1.7.0                  -> zephyr-v1.7.0
 * [new tag]         zephyr-v1.7.1                  -> zephyr-v1.7.1
 * [new tag]         zephyr-v1.8.0                  -> zephyr-v1.8.0
 * [new tag]         zephyr-v1.9.0                  -> zephyr-v1.9.0
 * [new tag]         zephyr-v1.9.1                  -> zephyr-v1.9.1
 * [new tag]         zephyr-v1.9.2                  -> zephyr-v1.9.2
 * [new tag]         zephyr-v2.0.0                  -> zephyr-v2.0.0
 * [new tag]         zephyr-v2.1.0                  -> zephyr-v2.1.0
 * [new tag]         zephyr-v2.2.0                  -> zephyr-v2.2.0
 * [new tag]         zephyr-v2.2.1                  -> zephyr-v2.2.1
 * [new tag]         zephyr-v2.3.0                  -> zephyr-v2.3.0
 * [new tag]         zephyr-v2.4.0                  -> zephyr-v2.4.0
 * [new tag]         zephyr-v2.5.0                  -> zephyr-v2.5.0
 * [new tag]         zephyr-v2.6.0                  -> zephyr-v2.6.0
d477a71920b3fd4491dbef3f29906f2421ad2329 refs/tags/v2.6.0
Note: switching to 'v2.6.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 79a6c07536 release: Updates for v2.6.0
--- setting manifest.path to zephyr
=== Initialized. Now run "west update" inside /workdir.
user@623043a289ee:/workdir$ 

Make use of west to update the Zephyr Project™ source code

cd /workdir
west update
=== updating cmsis (modules/hal/cmsis):
--- cmsis: initializing
Initialized empty Git repository in /workdir/modules/hal/cmsis/.git/
--- cmsis: fetching, need revision c3bd2094f92d574377f7af2aec147ae181aa5f8e
remote: Enumerating objects: 563, done.
remote: Counting objects: 100% (563/563), done.
remote: Compressing objects: 100% (296/296), done.
remote: Total 563 (delta 288), reused 523 (delta 262), pack-reused 0
Receiving objects: 100% (563/563), 2.21 MiB | 3.83 MiB/s, done.
Resolving deltas: 100% (288/288), done.
From https://github.com/zephyrproject-rtos/cmsis
 * [new branch]      master     -> refs/west/master
HEAD is now at c3bd209 DSP: fix compiler warning on inline attribute
HEAD is now at c3bd209 DSP: fix compiler warning on inline attribute
=== updating hal_atmel (modules/hal/atmel):
--- hal_atmel: initializing
Initialized empty Git repository in /workdir/modules/hal/atmel/.git/
--- hal_atmel: fetching, need revision d17b7dd92d209b20bc1e15431d068edc29bf438d
remote: Enumerating objects: 2644, done.
remote: Counting objects: 100% (781/781), done.
remote: Compressing objects: 100% (403/403), done.
remote: Total 2644 (delta 564), reused 513 (delta 376), pack-reused 1863
Receiving objects: 100% (2644/2644), 4.21 MiB | 8.88 MiB/s, done.
Resolving deltas: 100% (2025/2025), done.
From https://github.com/zephyrproject-rtos/hal_atmel
...
 * [new tag]         v2.3.0-rc2               -> v2.3.0-rc2
 * [new tag]         v2.3.1                   -> v2.3.1
 * [new tag]         v2.3.2                   -> v2.3.2
 * [new tag]         v2.4.0                   -> v2.4.0
 * [new tag]         v2.4.0-rc0               -> v2.4.0-rc0
 * [new tag]         v2.4.0-rc1               -> v2.4.0-rc1
 * [new tag]         v2.4.0-rc2               -> v2.4.0-rc2
 * [new tag]         v2.4.0-rc3               -> v2.4.0-rc3
 * [new tag]         v2.4.0-rc4               -> v2.4.0-rc4
 * [new tag]         v2.4.1                   -> v2.4.1
 * [new tag]         v2.5.0-rc0               -> v2.5.0-rc0
 * [new tag]         v2.5.0-rc1               -> v2.5.0-rc1
 * [new tag]         v2.5.0-rc2               -> v2.5.0-rc2
Updating files: 100% (23686/23686), done.
HEAD is now at dc70a45a7cc tensorflow: add tensorflow 2.4.1 as a zephyr module
HEAD is now at dc70a45a7cc tensorflow: add tensorflow 2.4.1 as a zephyr module
user@623043a289ee:/workdir$ 

Apply west to get the export the Zephyr Project™ source code

cd /workdir
west zephyr-export
Zephyr (/workdir/zephyr/share/zephyr-package/cmake)
has been added to the user package registry in:
~/.cmake/packages/Zephyr

ZephyrUnittest (/workdir/zephyr/share/zephyrunittest-package/cmake)
has been added to the user package registry in:
~/.cmake/packages/ZephyrUnittest

user@623043a289ee:/workdir$ 

Example: samples/hello_world

west build (configure/build)

# project dir
mkdir -p /zephyr-projects/nucleo_f411re/samples
cd /zephyr-projects/nucleo_f411re/samples
# copy hello_world sample over
cp -r /workdir/zephyr/samples/hello_world .
# build it for nucleo_f411re
cd hello_world
west build -b nucleo_f411re
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyr/cmake/app/boilerplate.cmake
-- Application: /zephyr-projects/nucleo_f411re/samples/hello_world
-- Zephyr version: 2.6.0 (/workdir/zephyr), build: zephyr-v2.6.0
-- Found Python3: /usr/bin/python3.8 (found suitable exact version "3.8.5") found components: Interpreter 
-- Found west (found suitable version "0.11.0", minimum required is "0.7.1")
-- Board: nucleo_f411re
-- Cache files will be written to: /home/user/.cache/zephyr
-- Using toolchain: zephyr 0.12.4 (/opt/toolchains/zephyr-sdk-0.12.4)
-- Found dtc: /opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyr/boards/arm/nucleo_f411re/nucleo_f411re.dts
-- Generated zephyr.dts: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/device_extern.h
Parsing /workdir/zephyr/Kconfig
Loaded configuration '/workdir/zephyr/boards/arm/nucleo_f411re/nucleo_f411re_defconfig'
Merged configuration '/zephyr-projects/nucleo_f411re/samples/hello_world/prj.conf'
Configuration saved to '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config'
Kconfig header saved to '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.12.4/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Configuring done
-- Generating done
-- Build files have been written to: /zephyr-projects/nucleo_f411re/samples/hello_world/build
-- west build: building application
[1/138] Preparing syscall dependency handling

[131/138] Linking C executable zephyr/zephyr_prebuilt.elf

[138/138] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       13788 B       512 KB      2.63%
            SRAM:        4512 B       128 KB      3.44%
        IDT_LIST:          0 GB         2 KB      0.00%
user@623043a289ee:/zephyr-projects/nucleo_f411re/samples/hello_world$ 

west flash (plus preparation)

hello_world: In order to see the output of our example, we’ll need to connect the USB cable to our host machine and have a look at the serial console.

Therefore let’s first inspect the kernel log on the host and then see what happens when we connect the USB cable.

tail -f /var/log/kern.log

Now connect the USB cable:

Jun 15 13:09:18 e450-10 kernel: [503563.699354] usb 3-2.1.1: new full-speed USB device number 9 using xhci_hcd
Jun 15 13:09:18 e450-10 kernel: [503563.805281] usb 3-2.1.1: New USB device found, idVendor=0483, idProduct=374b
Jun 15 13:09:18 e450-10 kernel: [503563.805286] usb 3-2.1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun 15 13:09:18 e450-10 kernel: [503563.805288] usb 3-2.1.1: Product: STM32 STLink
Jun 15 13:09:18 e450-10 kernel: [503563.805291] usb 3-2.1.1: Manufacturer: STMicroelectronics
Jun 15 13:09:18 e450-10 kernel: [503563.805293] usb 3-2.1.1: SerialNumber: 066BFF514855657867193614
Jun 15 13:09:18 e450-10 kernel: [503563.805476] usb 3-2.1.1: ep 0x84 - rounding interval to 1024 microframes, ep desc says 2040 microframes
Jun 15 13:09:19 e450-10 kernel: [503563.860566] usb-storage 3-2.1.1:1.1: USB Mass Storage device detected
Jun 15 13:09:19 e450-10 kernel: [503563.860986] scsi host7: usb-storage 3-2.1.1:1.1
Jun 15 13:09:19 e450-10 kernel: [503563.861381] cdc_acm 3-2.1.1:1.2: ttyACM0: USB ACM device
Jun 15 13:09:20 e450-10 kernel: [503564.860223] scsi 7:0:0:0: Direct-Access     MBED     microcontroller  1.0  PQ: 0 ANSI: 2
Jun 15 13:09:20 e450-10 kernel: [503564.860784] sd 7:0:0:0: Attached scsi generic sg1 type 0
Jun 15 13:09:20 e450-10 kernel: [503564.861119] sd 7:0:0:0: [sdb] 1096 512-byte logical blocks: (561 kB/548 KiB)
Jun 15 13:09:20 e450-10 kernel: [503564.861285] sd 7:0:0:0: [sdb] Write Protect is off
Jun 15 13:09:20 e450-10 kernel: [503564.861289] sd 7:0:0:0: [sdb] Mode Sense: 03 00 00 00
Jun 15 13:09:20 e450-10 kernel: [503564.861449] sd 7:0:0:0: [sdb] No Caching mode page found
Jun 15 13:09:20 e450-10 kernel: [503564.861452] sd 7:0:0:0: [sdb] Assuming drive cache: write through
Jun 15 13:09:20 e450-10 kernel: [503564.881470] sd 7:0:0:0: [sdb] Attached SCSI removable disk

We can see above that /dev/ttyACM0 was created. Let’s monitor this serial console.

On the host machine:

screen /dev/ttyACM0 115200

From the container let’s flash the binary:

cd /zephyr-projects/nucleo_f411re/samples/hello_world
west flash
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner openocd
-- runners.openocd: Flashing file: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/zephyr.hex
Open On-Chip Debugger 0.10.0+dev-01508-gf79c90268-dirty (2021-03-26-16:13)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J30M19 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.255570
Warn : target stm32f4x.cpu examination failed
Error: jtag status contains invalid mode value - communication failure
Polling target stm32f4x.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 100ms
Info : Previous state query failed, trying to reconnect
Error: jtag status contains invalid mode value - communication failure
Polling target stm32f4x.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 300ms
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32f4x.cpu       hla_target little stm32f4x.cpu       unknown

Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Error: mem2array: Read @ 0xe0042004, w=4, cnt=1, failed
Error executing event examine-end on target stm32f4x.cpu:
/opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts/mem_helper.tcl:6: Error:
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 288
in procedure 'mmw' called at file "/opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts/target/stm32f4x.cfg", line 85
in procedure 'mrw' called at file "/opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts/mem_helper.tcl", line 36
at file "/opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts/mem_helper.tcl", line 6
Info : Previous state query failed, trying to reconnect
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080040b0 msp: 0x20002100
Polling target stm32f4x.cpu failed, trying to reexamine
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : device id = 0x10006431
Info : flash size = 512 kbytes
auto erase enabled
wrote 16384 bytes from file /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/zephyr.hex in 0.709784s (22.542 KiB/s)

Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080013f8 msp: 0x20000800
verified 13788 bytes in 0.135022s (99.723 KiB/s)

Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
shutdown command invoked
user@623043a289ee:/zephyr-projects/nucleo_f411re/samples/hello_world$ pwd
/zephyr-projects/nucleo_f411re/samples/hello_world
user@623043a289ee:/zephyr-projects/nucleo_f411re/samples/hello_world$ 

On the host where we are monitoring the serial console you should see:

*** Booting Zephyr OS build zephyr-v2.6.0  ***
Hello World! nucleo_f411re

Example: samples/hello_world reconfigure

west build -t menuconfig

Let’s add a shell and a few other things:

cd /zephyr-projects/nucleo_f411re/samples/hello_world
west build -t menuconfig
Sub Systems and OS Services  ---> 
   [*] Shell  --->
      [*] Enable shell backends (NEW)  --->
      [ ] Default config to reduce flash and memory requirements
      (2048) Shell thread stack size (NEW)
      [*] Default escape code for backspace is DELETE (0x7F) (NEW)
      (256) Shell command buffer size (NEW)
      (30) Shell print buffer size (NEW)
      (80) Default terminal width (NEW)
      (24) Default terminal height (NEW)
      (12) Maximum arguments in shell command (NEW)
      [*] Enable the Tab button support in shell (NEW)
      [*]     Enable commands autocompletion with the Tab button (NEW)
      [*] Enable wildcard support in shell (NEW)
      [*] Enable echo on shell (NEW)
      [ ] Display asterisk when echoing
      [*] Enable colors in shell (NEW)
      [*] Enable getopt support
      [*] Enable metakeys (NEW)
      [*] Enable help message (NEW)
      [*]     Enable printing help on wrong argument count (NEW)
      [*] Enable history in shell (NEW)
      (512)   History buffer in bytes (NEW)
      [*] Enable shell statistics (NEW)
      [*] Enable built-in commands (NEW)
      [*]     Enable resize command (NEW)
      [*]     Enable select command
      [*] Enable kernel shell (NEW)
      [*] Enable device shell (NEW)
   [*] Statistics support
   [*]     Statistic names
General Kernel Options  --->
   Kernel Debugging and Metrics  --->
      [*] Initialize stack areas
      [*] Boot banner
      (0) Boot delay in milliseconds
      [*] Thread monitoring
      [*] Thread name
      (32)    Max length of a thread name
      [*] Thread runtime statistics  --->

save the new configuration:

Filename to save configuration to
   /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config

west build (configure/build)

west build -b nucleo_f411re
-- west build: running target menuconfig
[0/1] cd /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/kconfig && /usr/loca...ings /usr/bin/python3.8 /workdir/zephyr/scripts/kconfig/menuconfig.py /workdir/zephyr/Kconfig
Loaded configuration '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config'
No changes to save (for '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config')
user@623043a289ee:/zephyr-projects/nucleo_f411re/samples/hello_world$ west build -b nucleo_f411re
[0/1] Re-running CMake...
Including boilerplate (Zephyr base (cached)): /workdir/zephyr/cmake/app/boilerplate.cmake
-- Application: /zephyr-projects/nucleo_f411re/samples/hello_world
-- Zephyr version: 2.6.0 (/workdir/zephyr), build: zephyr-v2.6.0
-- Found west (found suitable version "0.11.0", minimum required is "0.7.1")
-- Board: nucleo_f411re
-- Cache files will be written to: /home/user/.cache/zephyr
-- Using toolchain: zephyr 0.12.4 (/opt/toolchains/zephyr-sdk-0.12.4)
-- Found dtc: /opt/toolchains/zephyr-sdk-0.12.4/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyr/boards/arm/nucleo_f411re/nucleo_f411re.dts
-- Generated zephyr.dts: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/device_extern.h
Parsing /workdir/zephyr/Kconfig
Loaded configuration '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config'
No change to configuration in '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/.config'
Kconfig header saved to '/zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/include/generated/autoconf.h'
-- Configuring done
-- Generating done
-- Build files have been written to: /zephyr-projects/nucleo_f411re/samples/hello_world/build
[143/150] Linking C executable zephyr/zephyr_prebuilt.elf

[150/150] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       32864 B       512 KB      6.27%
            SRAM:        9504 B       128 KB      7.25%
        IDT_LIST:          0 GB         2 KB      0.00%
user@623043a289ee:/zephyr-projects/nucleo_f411re/samples/hello_world$ 

“west flash”

From the container let’s flash the binary:

cd /zephyr-projects/nucleo_f411re/samples/hello_world
west flash

On the host where we are monitoring the serial console you should see:

uart:~$ *** Booting Zephyr OS build zephyr-v2.6.0  ***
Hello World! nucleo_f411re


uart:~$ help
Please press the <Tab> button to see all available commands.
You can also use the <Tab> button to prompt or auto-complete all commands or its subcommands.
You can try to call commands with <-h> or <--help> parameter for more information.

Shell supports following meta-keys:
  Ctrl + (a key from: abcdefklnpuw)
  Alt  + (a key from: bf)
Please refer to shell documentation for more details.

Available commands:
  clear    :Clear screen.
  device   :Device commands
  help     :Prints the help message.
  history  :Command history.
  kernel   :Kernel commands
  resize   :Console gets terminal screen size or assumes default in case the
            readout fails. It must be executed after each terminal width change
            to ensure correct text display.
  select   :Selects new root command. In order for the command to be selected,
            it must meet the criteria:
            - it is a static command
            - it is not preceded by a dynamic command
            - it accepts arguments
            Return to the main command tree is done by pressing alt+r.
  shell    :Useful, not Unix-like shell commands.
uart:~$ 
uart:~$ kernel help
kernel - Kernel commands
Subcommands:
  cycles   :Kernel cycles.
  stacks   :List threads stack usage.
  threads  :List kernel threads.
  uptime   :Kernel uptime.
  version  :Kernel version.
uart:~$ kernel cycles
cycles: 395483250 hw cycles
uart:~$ kernel stacks
0x20000438 sysworkq   (real size 1024): unused 864      usage 160 / 1024 (15 %)
0x200001d0 shell_uart (real size 2048): unused 1152     usage 896 / 2048 (43 %)
0x20000298 idle 00    (real size 320):  unused 272      usage 48 / 320 (15 %)
0x20001820 IRQ 00     (real size 2048): unused 1544     usage 504 / 2048 (24 %)
uart:~$ kernel threads
Scheduler: 868 since last call
Threads:
 0x20000438 sysworkq  
        options: 0x0, priority: -1 timeout: 536872112
        state: pending, entry: 0x8004a41
        Total execution cycles: 531 (0 %)
        stack size 1024, unused 864, usage 160 / 1024 (15 %)

*0x200001d0 shell_uart
        options: 0x0, priority: 14 timeout: 536871496
        state: queued, entry: 0x8001d91
        Total execution cycles: 3736221 (0 %)
        stack size 2048, unused 1152, usage 896 / 2048 (43 %)

 0x20000298 idle 00   
        options: 0x1, priority: 15 timeout: 536871696
        state: , entry: 0x800698f
        Total execution cycles: 1108971314 (99 %)
        stack size 320, unused 272, usage 48 / 320 (15 %)

uart:~$ kernel uptime
Uptime: 59826 ms
uart:~$ kernel version
Zephyr version 2.6.0
uart:~$ 
uart:~$ device help
device - Device commands
Subcommands:
  levels  :List configured devices by levels
  list    :List configured devices
uart:~$ device levels
PRE KERNEL 1:
- rcc@40023800
- interrupt-controller@40013c00
- UART_2
- UART_1
PRE KERNEL 2:
- sys_clock
POST_KERNEL:
- GPIOH
- GPIOE
- GPIOD
- GPIOC
- GPIOB
- GPIOA
APPLICATION:
- None
uart:~$ device list
devices:
- rcc@40023800 (READY)
- interrupt-controller@40013c00 (READY)
- UART_2 (READY)
  requires: rcc@40023800
- UART_1 (READY)
  requires: rcc@40023800
- sys_clock (READY)
- GPIOH (READY)
  requires: rcc@40023800
- GPIOE (READY)
  requires: rcc@40023800
- GPIOD (READY)
  requires: rcc@40023800
- GPIOC (READY)
  requires: rcc@40023800
- GPIOB (READY)
  requires: rcc@40023800
- GPIOA (READY)
  requires: rcc@40023800
uart:~$ 

“west debug”

From the container let’s debug the binary:

cd /zephyr-projects/nucleo_f411re/samples/hello_world
west debug
-- west debug: rebuilding
ninja: no work to do.
-- west debug: using runner openocd
Open On-Chip Debugger 0.10.0+dev-01508-gf79c90268-dirty (2021-03-26-16:13)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J30M19 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.257143
GNU gdb (crosstool-NG 1.24.0.212_d7da3a9) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-build_pc-linux-gnu --target=arm-zephyr-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /zephyr-projects/nucleo_f411re/samples/hello_world/build/zephyr/zephyr.elf...
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32f4x.cpu       hla_target little stm32f4x.cpu       running

target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x08002bfa psp: 0x200016d0
Info : Listening on port 6333 for tcl connections
Info : Listening on port 4444 for telnet connections
Remote debugging using :3333
Info : accepting 'gdb' connection on tcp/3333
Debugger attaching: halting execution
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08002c78 msp: 0x20001560
force hard breakpoints
Info : device id = 0x10006431
Info : flash size = 512 kbytes
Info : flash size = 512 bytes
Warn : Prefer GDB command "target extended-remote 3333" instead of "target remote 3333"
z_arm_reset () at /workdir/zephyr/arch/arm/core/aarch32/cortex_m/reset.S:104
104         movs.n r0, #_EXC_IRQ_DEFAULT_PRIO
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08002c78 msp: 0x20001560
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Loading section rom_start, size 0x198 lma 0x8000000
Loading section text, size 0x684a lma 0x8000198
Loading section .ARM.exidx, size 0x8 lma 0x80069e4
Loading section initlevel, size 0x80 lma 0x80069ec
Loading section sw_isr_table, size 0x2b0 lma 0x8006a6c
Loading section shell_area, size 0x2c lma 0x8006d1c
Loading section shell_root_cmds_sections, size 0x40 lma 0x8006d48
Loading section device_handles, size 0x74 lma 0x8006d88
Loading section rodata, size 0x1098 lma 0x8006dfc
Loading section datas, size 0xc4 lma 0x8007e94
Loading section devices, size 0x108 lma 0x8007f58
Info : Padding image section 0 at 0x080069e2 with 2 bytes
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08002c78 msp: 0x20001560
Start address 0x08002c78, load size 32862
Transfer rate: 17 KB/sec, 2738 bytes/write.
(gdb) b main
Breakpoint 1 at 0x80004a4: file ../src/main.c, line 12.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, main () at ../src/main.c:12
12              printk("Hello World! %s\n", CONFIG_BOARD);
(gdb) l
7       #include <zephyr.h>
8       #include <sys/printk.h>
9
10      void main(void)
11      {
12              printk("Hello World! %s\n", CONFIG_BOARD);
13      }
(gdb) s
Info : halted: PC: 0x080004a6
halted: PC: 0x080004a6
Info : halted: PC: 0x080004a8
halted: PC: 0x080004a8
Info : halted: PC: 0x080047f4
halted: PC: 0x080047f4
printk (fmt=0xa "") at /workdir/zephyr/lib/os/printk.c:213
213             va_start(ap, fmt);
(gdb) s
Info : halted: PC: 0x080047f6
halted: PC: 0x080047f6
Info : halted: PC: 0x080047f8
halted: PC: 0x080047f8
Info : halted: PC: 0x080047fa
halted: PC: 0x080047fa
Info : halted: PC: 0x080047fe
halted: PC: 0x080047fe
Info : halted: PC: 0x08004800
halted: PC: 0x08004800
218                     vprintk(fmt, ap);
(gdb) s
Info : halted: PC: 0x080004d0
halted: PC: 0x080004d0
vprintk (fmt=0x8007310 "Hello World! %s\n", fmt@entry=0x8007e63 "*** Booting Zephyr OS build %s %s ***\n", ap=..., ap@entry=...) at /workdir/zephyr/lib/os/printk.c:148
148             struct out_context ctx = { 0 };
(gdb) s
Info : halted: PC: 0x080004d2
halted: PC: 0x080004d2
Info : halted: PC: 0x080004d4
halted: PC: 0x080004d4
Info : halted: PC: 0x080004d6
halted: PC: 0x080004d6
Info : halted: PC: 0x080004d8
halted: PC: 0x080004d8
Info : halted: PC: 0x080004da
halted: PC: 0x080004da
153             cbvprintf(char_out, &ctx, fmt, ap);
(gdb) bt
#0  vprintk (fmt=fmt@entry=0x8007310 "Hello World! %s\n", ap=..., ap@entry=...) at /workdir/zephyr/lib/os/printk.c:153
#1  0x08004804 in printk (fmt=0x8007310 "Hello World! %s\n") at /workdir/zephyr/lib/os/printk.c:218
#2  0x080037ac in bg_thread_main (unused1=<optimized out>, unused2=<optimized out>, unused3=<optimized out>) at /workdir/zephyr/kernel/init.c:224
#3  0x0800481a in z_thread_entry (entry=0x800378d <bg_thread_main>, p1=<optimized out>, p2=<optimized out>, p3=<optimized out>) at /workdir/zephyr/lib/os/thread_entry.c:29
#4  0x08002bd8 in arch_switch_to_main_thread (main_thread=<optimized out>,
    stack_ptr=0x20001580 <z_idle_stacks> "\324\370t2\233\006\373տ\363[\217\004\365\035t", <incomplete sequence \350>, _main=0x800378d <bg_thread_main>)
    at /workdir/zephyr/arch/arm/core/aarch32/thread.c:539
#5  0xd5fb069a in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Conclusion

As you can see above, just by changing the kernel configuration and without writing a single line of code we can add a shell to the system plus simple kernel stack/thread debugging from the shell.

To learn more about small real-time systems like FreeRTOS have a look here. If you want to learn about how Embedded Linux works plus how to add some real-time capabilities to it have a look here.

Upcoming Events

Our 3 points

of differentiation

We provide host and target hardware during all our teaching.

Three or more people from the same company? We provide private customized training – consulting included.

Subject matter experts develop high-quality, job-related, up-to-date, authentic courseware.