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
Convenient symlink on the host
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.