Zephyr Docker Image Build - joectchan/blog GitHub Wiki

Summary

I use zephy-build docker image to build zephyr 2.3.0 source code.

Steps

  • Fork Zephyr upstream

  • git clone my fork to local drive. ~/ws/github/joectchan/zephyr

cd ~/ws/github/joectchan

git clone [email protected]:joectchan/zephyr.git

cd zephyr

git checkout -b joectchan/master-2020-06-25

~/ws/github/joectchan/zephyr$ ls
arch            CODE_OF_CONDUCT.md  drivers  Kconfig.zephyr  Makefile    samples  subsys        west.yml
boards          CODEOWNERS          dts      kernel          misc        scripts  tests         zephyr-env.cmd
cmake           CONTRIBUTING.rst    include  lib             modules     share    VERSION       zephyr-env.sh
CMakeLists.txt  doc                 Kconfig  LICENSE         README.rst  soc      version.h.in
  • Install docker per link and link

  • Test I can run docker image as myself, instead of sudo.

docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
  • Pull pre-built zephyr-build docker image. Or build your docker image with instructions on github page here. Map the location of my local copy of the zephyr code to /workdit in the docker image.
docker run -ti -v ~/ws/github/joectchan/zephyr:/workdir docker.io/zephyrprojectrtos/zephyr-build:latest

Unable to find image 'zephyrprojectrtos/zephyr-build:latest' locally
latest: Pulling from zephyrprojectrtos/zephyr-build

It takes a long time, but eventually:

ce4d121d51fd: Pull complete 
1fb0d7f6988a: Pull complete 
Digest: sha256:21db381769d9bb942075275ac149a29d626bda10421b6da9cfdd4e9a70b7e7be
Status: Downloaded newer image for zephyrprojectrtos/zephyr-build:latest
Openbox-Message: Unable to find a valid menu file "/var/lib/openbox/debian-menu.xml"
user@2a2f4095b2a2:/workdir$ 
The VNC desktop is:      2a2f4095b2a2:0
PORT=5900

user@2a2f4095b2a2:/workdir$ ls
arch            CODE_OF_CONDUCT.md  drivers  Kconfig.zephyr  Makefile    samples  subsys        west.yml
boards          CODEOWNERS          dts      kernel          misc        scripts  tests         zephyr-env.cmd
cmake           CONTRIBUTING.rst    include  lib             modules     share    VERSION       zephyr-env.sh
CMakeLists.txt  doc                 Kconfig  LICENSE         README.rst  soc      version.h.in
user@2a2f4095b2a2:/workdir$

Note that it is now running inside the docker image and able to see the contents of ~/ws/github/joectchan/zephyr as in /workdir

  • Build sample application hello world
cd samples/hello_world
mkdir build
cd build
cmake -DBOARD=qemu_x86 ..
make run

Take a short time to compile. The result is:

Scanning dependencies of target zephyr_final
[ 97%] Building C object zephyr/CMakeFiles/zephyr_final.dir/misc/empty_file.c.obj
[ 98%] Linking C executable zephyr.elf
Generating files from zephyr.elf for board: qemu_x86
[ 98%] Built target zephyr_final
Scanning dependencies of target run
[100%] 
To exit from QEMU enter: 'CTRL+a, x'
[QEMU] CPU: qemu32,+nx,+pae
SeaBIOS (version rel-1.12.1-0-ga5cab58-dirty-20200214_052440-f7294c49af13-zephyr
)
Booting from ROM..Optimal CONFIG_X86_MMU_PAGE_POOL_PAGES 6
*** Booting Zephyr OS build zephyr-v2.3.0-602-gf42cddf0830c  ***
Hello World! qemu_x86

  • Exit QEMU with ctrl-a, x and exit docker image by exit
QEMU: Terminated
[100%] Built target run

exit
  • Start docker image and map vnc port 5900 to host port 5900. This let us use vnc client on the host to connect to the zephyr display running inside the docker image.
docker run -ti -p 5900:5900 -v ~/ws/github/joectchan/zephyr:/workdir docker.io/zephyrprojectrtos/zephyr-build:latest
  • Build display sample applciation for native POSIX board
cd /workdir/samples/display/cfb
mkdir build
cd build
cmake -DBOARD=native_posix -GNinja ..
ninja run

Take a short time to compile. The result is:

[64/65] cd /workdir/samples/display/cfb/build && /workdir/samples/display/cfb/build/zephyr/zephyr.exe
*** Booting Zephyr OS build zephyr-v2.3.0-359-g8e4faab30a50  ***
initialized DISPLAY
[00:00:00.000,000] <dbg> cfb.cfb_framebuffer_init: number of fonts 3
font width 10, font height 16
font width 15, font height 24
font width 20, font height 32
x_res 250, y_res 120, ppt 8, rows 15, cols 250
  • Use a VNC client on your host can connect to localhost:5900. I use Remmina as my VNC client. Search for "password" on github page here to find the default VNC password.

  • After watching zephyr display applciation shows falling text string via VNC, ctrl-c in the docker image to stop zephyr app. I could use exit to end the docker image and the VNC session.

  • In my first attempt, I proceeded to build a binary for my STM disco_l475_iot1 test board. I did not exit my docker.

  • Go back to samples/hello_world. Create another dir to build binary for my disco_l475_iot1 in this new dir.

cd /workdir/samples/hello_world
mkdir build_disco_l475_iot1               
cd build_disco_l475_iot1
cmake -DBOARD=disco_l475_iot1 ..

user@dcfcf0b032c0:/workdir/samples/hello_world/build_disco_l475_iot1$ cmake -DBOARD=disco_l475_iot1 ..
Including boilerplate (Zephyr base): /workdir/cmake/app/boilerplate.cmake
-- Application: /workdir/samples/hello_world
-- Zephyr version: 2.3.99 (/workdir)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: disco_l475_iot1
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
FATAL ERROR: no west workspace found from "/workdir"; "west topdir" requires one.
Things to try:
  - Change directory to somewhere inside a west workspace and retry.
  - Set ZEPHYR_BASE to a zephyr repository path in a west workspace.
  - Run "west init" to set up a workspace here.
  - Run "west init -h" for additional information.

-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0
", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/boards/arm/disco_l475_iot1/disco_l475_iot1.dts
-- Generated zephyr.dts: /workdir/samples/hello_world/build_disco_l475_iot1/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/samples/hello_world/build_disco_l475_iot1/zephyr/include/generated/devicetre
e_unfixed.h
Parsing /workdir/Kconfig
Loaded configuration '/workdir/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig'
Merged configuration '/workdir/samples/hello_world/prj.conf' 
Configuration saved to '/workdir/samples/hello_world/build_disco_l475_iot1/zephyr/.config'
Kconfig header saved to '/workdir/samples/hello_world/build_disco_l475_iot1/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/samples/hello_world/build_disco_l475_iot1
user@dcfcf0b032c0:/workdir/samples/hello_world/build_disco_l475_iot1$ ls zephyr
arch    CMakeFiles                    disco_l475_iot1.dts.pre.d    include  lib       runners.yaml  zephyr.dts
boards  cmake_install.cmake           disco_l475_iot1.dts.pre.tmp  kconfig  Makefile  soc
cmake   disco_l475_iot1.dts_compiled  drivers                      kernel   misc      subsys
user@dcfcf0b032c0:/workdir/samples/hello_world/build_disco_l475_iot1$ make
Scanning dependencies of target parse_syscalls_target
[  1%] Generating misc/generated/syscalls.json, misc/generated/struct_tags.json
[  2%] Built target parse_syscalls_target
Scanning dependencies of target kobj_types_h_target
[  3%] Generating include/generated/kobj-types-enum.h, include/generated/otype-to-str.h
[  3%] Built target kobj_types_h_target
Scanning dependencies of target syscall_list_h_target
[  3%] Generating include/generated/syscall_dispatch.c, include/generated/syscall_list.h
[  6%] Built target syscall_list_h_target
Scanning dependencies of target driver_validation_h_target
[  7%] Generating include/generated/driver-validation.h
[  9%] Built target driver_validation_h_target
Scanning dependencies of target offsets
[ 10%] Building C object zephyr/CMakeFiles/offsets.dir/arch/arm/core/offsets/offsets.c.obj
In file included from /workdir/include/arch/arm/aarch32/cortex_m/cmsis.h:17,
                 from /workdir/include/arch/arm/aarch32/cortex_m/mpu/arm_mpu_v7m.h:10,
                 from /workdir/include/arch/arm/aarch32/cortex_m/mpu/arm_mpu.h:13,
                 from /workdir/include/arch/arm/aarch32/arch.h:248,
                 from /workdir/include/arch/cpu.h:19,
                 from /workdir/include/kernel_includes.h:39,
                 from /workdir/include/kernel.h:17,
                 from /workdir/arch/arm/core/offsets/offsets_aarch32.c:25,
                 from /workdir/arch/arm/core/offsets/offsets.c:12:
/workdir/soc/arm/st_stm32/stm32l4/soc.h:27:10: fatal error: stm32l4xx.h: No such file or directory
   27 | #include <stm32l4xx.h>
      |          ^~~~~~~~~~~~~
compilation terminated.
zephyr/CMakeFiles/offsets.dir/build.make:62: recipe for target 'zephyr/CMakeFiles/offsets.dir/arch/arm/core/offsets/offs
ets.c.obj' failed
make[2]: *** [zephyr/CMakeFiles/offsets.dir/arch/arm/core/offsets/offsets.c.obj] Error 1
CMakeFiles/Makefile2:1558: recipe for target 'zephyr/CMakeFiles/offsets.dir/all' failed
make[1]: *** [zephyr/CMakeFiles/offsets.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
  • I exit docker image. Create a new dir on the host filesystem. Leave it empty and map to docker image as /workdir.
cd ~/ws/github/joectchan
mkdir zephyr_docker_workdir
docker run -ti -v ~/ws/github/joectchan/zephyr_docker_workdir:/workdir docker.io/zephyrprojectrtos/zephyr-build:latest

Since I am starting from sratch again, I follow Getting Started Guide link to download the source again using the west from the docker image.

user@822c237b9851:/workdir$ west init zephyrproject

=== Initializing in /workdir/zephyrproject                                                                              
--- Cloning manifest repository from https://github.com/zephyrproject-rtos/zephyr, rev. master                          
Initialized empty Git repository in /workdir/zephyrproject/.west/manifest-tmp/.git/                                     
remote: Enumerating objects: 38, done.                                                                                  
remote: Counting objects: 100% (38/38), done.                                                                           
remote: Compressing objects: 100% (34/34), done.                                                                        
remote: Total 469778 (delta 13), reused 13 (delta 4), pack-reused 469740                                                
Receiving objects: 100% (469778/469778), 329.28 MiB | 1.37 MiB/s, done.                                                 
Resolving deltas: 100% (354657/354657), done.                                                                           
From https://github.com/zephyrproject-rtos/zephyr                                                                       
 * branch                  master                  -> FETCH_HEAD          
 * [new branch]            arch_timer_ppi          -> origin/arch_timer_ppi
 * [new branch]            master                  -> origin/master

After a long time ...

 * [new tag]               zephyr-v2.2.1           -> zephyr-v2.2.1                                                     
 * [new tag]               zephyr-v2.3.0           -> zephyr-v2.3.0                                                     
22be0d8fd5902da11c9bf55a44012abc7c2cf1c1 refs/remotes/origin/master       
Checking out files: 100% (12374/12374), done.                                                                           
Branch 'master' set up to track remote branch 'master' from 'origin'.      
Already on 'master'                                                                                                     
--- setting manifest.path to zephyr                                                                                     
=== Initialized. Now run "west update" inside /workdir/zephyrproject.                                                   

Follow the instruction to run west update. This will pull in a lot of modules

user@822c237b9851:/workdir$ ls                                                                                          
zephyrproject

user@822c237b9851:/workdir$ cd zephyrproject/
user@822c237b9851:/workdir/zephyrproject$ west update
=== updating cmsis (modules/hal/cmsis):
--- cmsis: fetching, need revision 542b2296e6d515b265e25c6b7208e8fea3014f90
remote: Enumerating objects: 535, done.
remote: Total 535 (delta 267), reused 508 (delta 251), pack-reused 0
Receiving objects: 100% (535/535), 2.20 MiB | 2.15 MiB/s, done.
Resolving deltas: 100% (267/267), done.
From https://github.com/zephyrproject-rtos/cmsis
 * [new branch]      master     -> refs/west/master
HEAD is now at 542b229 DSP: Integrate CMSIS-DSP 1.8.0 (CMSIS 5.7.0)
HEAD is now at 542b229 DSP: Integrate CMSIS-DSP 1.8.0 (CMSIS 5.7.0)
=== updating hal_atmel (modules/hal/atmel):

Another long wait ...

=== updating edtt (tools/edtt):
--- edtt: initializing
Initialized empty Git repository in /workdir/zephyrproject/tools/edtt/.git/
--- edtt: fetching, need revision c39888ff74acf421eeff9a7514fa9b172c3373f7
remote: Enumerating objects: 213, done.
remote: Counting objects: 100% (213/213), done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 213 (delta 131), reused 172 (delta 90), pack-reused 0
Receiving objects: 100% (213/213), 225.78 KiB | 1.76 MiB/s, done.
Resolving deltas: 100% (131/131), done.
From https://github.com/zephyrproject-rtos/edtt
 * [new branch]      public_master -> refs/west/public_master
HEAD is now at c39888f Update unsupported commands test to handle command status response
HEAD is now at c39888f Update unsupported commands test to handle command status response
=== updating trusted-firmware-m (modules/tee/tfm):
--- trusted-firmware-m: initializing
Initialized empty Git repository in /workdir/zephyrproject/modules/tee/tfm/.git/
--- trusted-firmware-m: fetching, need revision 7de2daa1967b2dc12cbe0fcc0171ac3064ea596b
remote: Enumerating objects: 45, done.
remote: Counting objects: 100% (45/45), done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 5067 (delta 18), reused 24 (delta 9), pack-reused 5022
Receiving objects: 100% (5067/5067), 19.21 MiB | 2.71 MiB/s, done.
Resolving deltas: 100% (1764/1764), done.
From https://github.com/zephyrproject-rtos/trusted-firmware-m
 * [new branch]      master     -> refs/west/master
HEAD is now at 7de2daa zephyr: cmake: TF-M libraries to be used by the ns-app
HEAD is now at 7de2daa zephyr: cmake: TF-M libraries to be used by the ns-app

user@822c237b9851:/workdir/zephyrproject$

Confirm the missing file from the previous step is present.

user@822c237b9851:/workdir/zephyrproject$ find . -name stm32l4xx.h
./modules/hal/stm32/stm32cube/stm32l4xx/soc/stm32l4xx.h
./modules/lib/loramac-node/src/boards/NucleoL476/cmsis/stm32l4xx.h
user@822c237b9851:/workdir/zephyrproject$ 

Export a Zephyr CMake package with west zephyr-export. This link describe this step using west and without using west.

If you follow the link, you will see a section called "Zephyr application structure". When we develop a real project, we will need to know that. I am just trying to run hello world app for now, which is a "Zephyr repository application". I think "Zephyr freestanding application" would be a better structure for non-trivial projects.

user@822c237b9851:/workdir/zephyrproject$ west zephyr-export
WARNING: ZEPHYR_BASE=/workdir in the calling environment will be used,
but the zephyr.base config option in /workdir/zephyrproject is "zephyr"
which implies a different ZEPHYR_BASE=/workdir/zephyrproject/zephyr
To disable this warning in the future, execute 'west config --global zephyr.base-prefer env'
Zephyr (/workdir/zephyrproject/zephyr/share/zephyr-package/cmake)
has been added to the user package registry in:
~/.cmake/packages/Zephyr

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

user@822c237b9851:/workdir/zephyrproject$

I didn't know what that error is about. I try to proceed to build, but ran into it again.

user@822c237b9851:/workdir/zephyrproject$ west build -p auto -s zephyr/samples/hello_world -d build-hello-world -b disco_l475_iot1

user@822c237b9851:/workdir/zephyrproject$ west build -p auto -s zephyr/samples/hello_world -d build-hello-world -b disco
_l475_iot1
WARNING: ZEPHYR_BASE=/workdir in the calling environment will be used,
but the zephyr.base config option in /workdir/zephyrproject is "zephyr"
which implies a different ZEPHYR_BASE=/workdir/zephyrproject/zephyr
To disable this warning in the future, execute 'west config --global zephyr.base-prefer env'
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/cmake/app/boilerplate.cmake
CMake Error at /workdir/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:24 (include):
  include could not find load file:

    /workdir/cmake/app/boilerplate.cmake
Call Stack (most recent call first):
  /workdir/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:35 (include_boilerplate)
  CMakeLists.txt:5 (find_package)

I found the file is in

user@822c237b9851:/workdir/zephyrproject$ ls /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
/workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake

zephyr.base-prefer is explained in the file zephyr/doc/guides/west/config.rst

   * - ``zephyr.base-prefer``
     - String, one the values ``"env"`` and ``"configfile"``. If set to
       ``"env"`` (the default), setting :envvar:`ZEPHYR_BASE` in the calling
       environment overrides the value of the ``zephyr.base`` configuration
       option. If set to ``"configfile"``, the configuration option wins
       instead.

Hence, I want to use "configfile" in my situation. I decide to wipe out my failed build dir and start again.

cd /workdir/zephyrproject
rm -rf build-hello-world
west config --global zephyr.base-prefer configfile
west zephyr-export
west build -p auto -s zephyr/samples/hello_world -d build-hello-world -b disco_l475_iot1

This is my screenshot

user@822c237b9851:/workdir/zephyrproject$ cd /workdir/zephyrproject
user@822c237b9851:/workdir/zephyrproject$ rm -rf build-hello-world
user@822c237b9851:/workdir/zephyrproject$ west config --global zephyr.base-prefer configfile
user@822c237b9851:/workdir/zephyrproject$ west zephyr-export

user@822c237b9851:/workdir/zephyrproject$ west build -p auto -s zephyr/samples/hello_world -d build-hello-world -b disco_l475_iot1
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/zephyr/samples/hello_world
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: disco_l475_iot1
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1.dts
-- Generated zephyr.dts: /workdir/zephyrproject/build-hello-world/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/build-hello-world/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/zephyr/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig'
Merged configuration '/workdir/zephyrproject/zephyr/samples/hello_world/prj.conf'
Configuration saved to '/workdir/zephyrproject/build-hello-world/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/build-hello-world/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/build-hello-world
-- west build: building application
[1/130] Preparing syscall dependency handling

... (Cutting out some lines) ...

[125/130] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       13128 B         1 MB      1.25%
            SRAM:        4304 B        96 KB      4.38%
        IDT_LIST:         168 B         2 KB      8.20%
[130/130] Linking C executable zephyr/zephyr.elf

Confirming the file is there.

user@822c237b9851:/workdir/zephyrproject$ ls -al build-hello-world/zephyr/zephyr.elf 
-rwxr-xr-x 1 user user 488780 Jun 25 20:53 build-hello-world/zephyr/zephyr.elf

I exit my docker image. Connect host USB port to ST-Link on the disco_l475_iot1. I use ll /dev/ttyACM0 to confirm the host can see the target board.

user@822c237b9851:/workdir/zephyrproject$ exit
exit
caught signal: 1

I exit restart my docker image with --privileged to give it full access to host. This is security problem! But I will just get it work first.

joseph@hp-envy:~/ws/github/joectchan$ docker run -ti --privileged -v ~/ws/github/joectchan/zephyr_docker_workdir:/workdir docker.io/zephyrprojectrtos/zephyr-build:latest
Openbox-Message: Unable to find a valid menu file "/var/lib/openbox/debian-menu.xml"
user@483d548d939a:/workdir$ 
The VNC desktop is:      483d548d939a:0
PORT=5900

user@483d548d939a:/workdir$ ls /dev
autofs           i2c-0     loop15        port    sg0       tty17  tty34  tty51      ttyS0   ttyS26   vcs    vcsu5
bsg              i2c-1     loop2         ppp     sg1       tty18  tty35  tty52      ttyS1   ttyS27   vcs1   vcsu6
btrfs-control    i2c-2     loop3         psaux   sg2       tty19  tty36  tty53      ttyS10  ttyS28   vcs2   vfio
bus              i2c-3     loop4         ptmx    shm       tty2   tty37  tty54      ttyS11  ttyS29   vcs3   vga_arbiter
console          i2c-4     loop5         pts     snapshot  tty20  tty38  tty55      ttyS12  ttyS3    vcs4   vhci
core             i2c-5     loop6         random  snd       tty21  tty39  tty56      ttyS13  ttyS30   vcs5   vhost-net
cpu              i2c-6     loop7         rfkill  stderr    tty22  tty4   tty57      ttyS14  ttyS31   vcs6   vhost-vsock
cpu_dma_latency  i2c-7     loop8         rtc0    stdin     tty23  tty40  tty58      ttyS15  ttyS4    vcsa   video0
cuse             input     loop9         sda     stdout    tty24  tty41  tty59      ttyS16  ttyS5    vcsa1  video1
dri              kmsg      loop-control  sda1    tty       tty25  tty42  tty6       ttyS17  ttyS6    vcsa2  zero
drm_dp_aux0      kvm       mapper        sda2    tty0      tty26  tty43  tty60      ttyS18  ttyS7    vcsa3  zfs
ecryptfs         lightnvm  mcelog        sda3    tty1      tty27  tty44  tty61      ttyS19  ttyS8    vcsa4
fb0              loop0     media0        sda4    tty10     tty28  tty45  tty62      ttyS2   ttyS9    vcsa5
fd               loop1     mei0          sda5    tty11     tty29  tty46  tty63      ttyS20  udmabuf  vcsa6
full             loop10    mem           sda6    tty12     tty3   tty47  tty7       ttyS21  uhid     vcsu
fuse             loop11    mqueue        sda7    tty13     tty30  tty48  tty8       ttyS22  uinput   vcsu1
hidraw0          loop12    net           sdb     tty14     tty31  tty49  tty9       ttyS23  urandom  vcsu2
hpet             loop13    null          sdb1    tty15     tty32  tty5   ttyACM0    ttyS24  usb      vcsu3
hwrng            loop14    nvram         sdc     tty16     tty33  tty50  ttyprintk  ttyS25  userio   vcsu4

Go back to the "/workdir/zephyrproject/" dir. Because I restart docker image, "west" complained about zephyr.base again. Add the command to set up zephyr.base-prefer to use configfile. Use west flash -d build-hello-world to flash the elf image to target.

cd /workdir/zephyrproject/
west config --global zephyr.base-prefer configfile
west flash -d build-hello-world

-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner openocd
-- runners.openocd: Flashing file: /workdir/zephyrproject/build-hello-world/zephyr/zephyr.hex
Open On-Chip Debugger 0.10.0+dev-01340-ga0e8edc4e-dirty (2020-02-14-05:38)
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
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : clock speed 500 kHz
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: open failed


FATAL ERROR: command exited with status 1: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/openocd -s /workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/support -s /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts -f /workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/support/openocd.cfg -c init -c targets -c 'reset halt' -c 'flash write_image erase /workdir/zephyrproject/build-hello-world/zephyr/zephyr.hex' -c 'reset halt' -c 'verify_image /workdir/zephyrproject/build-hello-world/zephyr/zephyr.hex' -c 'reset run' -c shutdown
user@483d548d939a:/workdir/zephyrproject$ 

One of the step in Zephyr Getting Start Guide link says that we need to:

Install udev rules, which allow you to flash most Zephyr boards as a regular user: That file is already in the docker image. We need to install it onto the host. First, copy the rule in docker image to the shared dir between docker and host, i.e. /workdir/

cp /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /workdir/

On the host, sudo copy the rule from the shared dir, i.e. /ws/github/joectchan/zephyr_docker_workdir/, to /etc/udev/rules.d/ Then, enable the new rule

joseph@hp-envy:~/ws/github/joectchan$ sudo cp zephyr_docker_workdir/60-openocd.rules /etc/udev/rules.d
joseph@hp-envy:~/ws/github/joectchan$ sudo udevadm control --reload

I was not able to get the new rule to work without a reboot of my host machine. I spent over an hour searching and testing various ideas. Maybe I will discover exactly what's wrong someday. For now, a reboot of the host machine and starting my priviledged docker image can let me flash my disco_l475_iot1

joseph@hp-envy:~$ docker run -ti --privileged -v ~/ws/github/joectchan/zephyr_docker_workdir:/workdir docker.io/zephyrpr
ojectrtos/zephyr-build:latest                               
Openbox-Message: Unable to find a valid menu file "/var/lib/openbox/debian-menu.xml"
user@8a609e637ea0:/workdir$                                                                                             
The VNC desktop is:      8a609e637ea0:0
PORT=5900                                                                                                               
                                                                                                                        user@8a609e637ea0:/workdir$ cd /workdir/zephyrproject/
user@8a609e637ea0:/workdir/zephyrproject$ west config --global zephyr.base-prefer configfile                            user@8a609e637ea0:/workdir/zephyrproject$ west flash -d build-hello-world
-- west flash: rebuilding                                                                                               ninja: no work to do.
-- west flash: using runner openocd                    
-- runners.openocd: Flashing file: /workdir/zephyrproject/build-hello-world/zephyr/zephyr.hex
Open On-Chip Debugger 0.10.0+dev-01340-ga0e8edc4e-dirty (2020-02-14-05:38)
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
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
                                                            
Info : clock speed 500 kHz
Info : STLINK V2J36M26 (API v2) VID:PID 0483:374B                                                                       
Info : Target voltage: 3.218898
Error: jtag status contains invalid mode value - communication failure
Polling target stm32l4x.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 stm32l4x.cpu failed, trying to reexamine
Examination failed, GDB will be halted. Polling again in 300ms
Info : Listening on port 3333 for gdb connections                                                                       
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32l4x.cpu       hla_target little stm32l4x.cpu       unknown

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Error: mem2array: Read @ 0xe0042004, w=4, cnt=1, failed
Error executing event examine-end on target stm32l4x.cpu:
/opt/toolchains/zephyr-sdk-0.11.2/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 230
in procedure 'mmw' called at file "/opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scr
ipts/target/stm32l4x.cfg", line 91
in procedure 'mrw' called at file "/opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scr
ipts/mem_helper.tcl", line 36
at file "/opt/toolchains/zephyr-sdk-0.11.2/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: 0x08002f24 msp: 0x200063e8
Polling target stm32l4x.cpu failed, trying to reexamine
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev: 4)
Info : flash size = 1024kbytes 
Info : flash mode : dual-bank
Warn : Adding extra erase range, 0x08003348 .. 0x080037ff
auto erase enabled
wrote 13128 bytes from file /workdir/zephyrproject/build-hello-world/zephyr/zephyr.hex in 0.825071s (15.538 KiB/s)

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000f40 msp: 0x20000790
verified 13128 bytes in 0.455112s (28.170 KiB/s)

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
shutdown command invoked
user@8a609e637ea0:/workdir/zephyrproject$ 

I use PuTTY (on Ubuntu) to watch the output from disco_l475_iot1. Select Connection type to be serial. Serial line is /dev/ttyACM0 on my host. Speed is 115200.

The "Hello World" message is printed once after the target board boots. If you missed it, try running west flash -d build-hello-world in the docker image. That will reprogram the flash on the target and reboot. Watch your PuTTY and catch the "Hello World" string.

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
Hello World! disco_l475_iot1

Since I know my whole process is working, I will avoid giving the docker image "--privileged". On the host, use lsusb to find the ST-LINK device exposed by the disco_l475_iot1 board.

joseph@hp-envy:~$ lsusb
Bus 002 Device 002: ID 0483:374b STMicroelectronics ST-LINK/V2.1

Exit my docker image and start it with the ST-LINK device directly.

docker run -ti --device=/dev/bus/usb/002/002 -v ~/ws/github/joectchan/zephyr_docker_workdir:/workdir docker.io/zephyrprojectrtos/zephyr-build:latest

Try the same command in docker image to confirm you can still flash the target. Watch PuTTY to confirm "Hello World" string still appears on ttyACM0.

cd /workdir/zephyrproject/
west config --global zephyr.base-prefer configfile
west flash -d build-hello-world

Next, I try to build DRU sample application in docker image. I wrote a wiki about how to do that on native host development environment. I will repeat the procedure using this docker image. The first step is building MCUBoot.

west build -p auto -s bootloader/mcuboot/boot/zephyr -d build-mcuboot -b disco_l475_iot1                                                                                               
[2/217] Generating zephyr/autogen-pubkey.c                                                                       
FAILED: zephyr/autogen-pubkey.c
cd /workdir/zephyrproject/build-mcuboot && /usr/bin/python3.6 /workdir/zephyrproject/bootloader/mcuboot/scripts/imgtool.
py getpub -k /workdir/zephyrproject/bootloader/mcuboot/root-rsa-2048.pem > /workdir/zephyrproject/build-mcuboot/zephyr/a
utogen-pubkey.c
Traceback (most recent call last):
  File "/workdir/zephyrproject/bootloader/mcuboot/scripts/imgtool.py", line 17, in <module>
    from imgtool import main
  File "/workdir/zephyrproject/bootloader/mcuboot/scripts/imgtool/main.py", line 21, in <module>
    import imgtool.keys as keys
  File "/workdir/zephyrproject/bootloader/mcuboot/scripts/imgtool/keys/__init__.py", line 19, in <module>
    from cryptography.hazmat.backends import default_backend
ModuleNotFoundError: No module named 'cryptography'
[11/217] Building C object zephyr/CMakeFiles/zephyr.dir/subsys/logging/log_output.c.obj
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake --build /workdir/zephyrproject/build-mcuboot

The docker image is missing a package. Manually install it and re-try building MCUBoot.

pip3 search cryptography                           
cryptography (2.9.2)                      - cryptography is a package which provides cryptographic recipes and
                                            primitives to Python developers.      


pip3 install cryptography
Collecting cryptography
  Downloading https://files.pythonhosted.org/packages/58/95/f1282ca55649b60afcf617e1e2ca384a2a3e7a5cf91f724cf83c8fbe76a1/cryptography-2.9.2-cp35-abi3-manylinux1_x86_64.whl (2.7MB)


west build -p auto -s bootloader/mcuboot/boot/zephyr -d build-mcuboot -b disco_l475_iot1 
[202/207] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       44392 B        64 KB     67.74%
            SRAM:       29576 B        96 KB     30.09%
        IDT_LIST:         168 B         2 KB      8.20%
[207/207] Linking C executable zephyr/zephyr.elf

The MCUBoot binary is properly compiled. Note the "zephyr.elf" is the MCUBoot binary.

Use "west flash" to download this binary to the target.

west flash -d build-mcuboot                                            [3/671]
-- west flash: rebuilding                                                                                               
ninja: no work to do.                                                                                                   
-- west flash: using runner openocd
-- runners.openocd: Flashing file: /workdir/zephyrproject/build-mcuboot/zephyr/zephyr.hex
Open On-Chip Debugger 0.10.0+dev-01340-ga0e8edc4e-dirty (2020-02-14-05:38)
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
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : clock speed 500 kHz
Info : STLINK V2J36M26 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.215748
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32l4x.cpu       hla_target little stm32l4x.cpu       running

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08002f7c msp: 0x200065a8
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev: 4)
Info : flash size = 1024kbytes 
Info : flash mode : dual-bank
Warn : Adding extra erase range, 0x0800ad68 .. 0x0800afff
auto erase enabled
wrote 44392 bytes from file /workdir/zephyrproject/build-mcuboot/zephyr/zephyr.hex in 2.059766s (21.047 KiB/s)

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08002f7c msp: 0x200065a8
verified 44392 bytes in 1.343986s (32.256 KiB/s)

Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
shutdown command invoked

PuTTY shows MCUBoot coming up and presenting a USB DFU device.

*** Booting Zephyr OS build zephyr-v2.2.0-1791-g8d984b336ed4  ***
[00:00:00.062,000] <inf> main: This device supports USB DFU class.

Connect the other USB on disco_l475_iot1 to host USB. Confirm the DRU device appears on host.

I used a Ubuntu 20.04 host and lsusb knows about ZEPHYR. When I use a Ubuntu 18.04 host, lsusb does not know ZEPHYR, but vendor:product id will be the same.

lsusb

Bus 002 Device 008: ID 2fe3:0005 ZEPHYR Zephyr DFU sample

Second step is building USB DFU sample application. Compilation went smoothly.

user@1c30b4900ba4:/workdir/zephyrproject$ ls zephyr/samples/subsys/usb/dfu/
CMakeLists.txt  Kconfig  prj.conf  README.rst  sample.yaml  src

user@1c30b4900ba4:/workdir/zephyrproject$ west build -p auto -s zephyr/samples/subsys/usb/dfu -d build-dfu -b disco_l475_iot1
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: disco_l475_iot1
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1.dts
-- Generated zephyr.dts: /workdir/zephyrproject/build-dfu/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/build-dfu/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig'
Merged configuration '/workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/prj.conf'
Configuration saved to '/workdir/zephyrproject/build-dfu/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/build-dfu/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
CMake Warning at ../../../../subsys/usb/CMakeLists.txt:28 (message):
  CONFIG_USB_DEVICE_VID has default value 0x2FE3.

  This value is only for testing and MUST be configured for USB products.


-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/build-dfu
-- west build: building application
[1/155] Preparing syscall dependency handling

[150/155] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       41952 B       432 KB      9.48%
            SRAM:       11376 B        96 KB     11.57%
        IDT_LIST:         184 B         2 KB      8.98%
[155/155] Linking C executable zephyr/zephyr.elf

However, we will NOT use the elf. We will use the bin file in the next step to created a signed binary. Confirm the bin file has been properly created.

ll build-dfu/zephyr/zephyr.bin 
-rwxr-xr-x 1 user user 41952 Jun 26 22:33 build-dfu/zephyr/zephyr.bin*

Sign the bin file.

I added pip3 install because I had a power failure at home and started docker image again. Need to install the missing crytography after I restart the image.

pip3 install cryptography

bootloader/mcuboot/scripts/imgtool.py sign --key bootloader/mcuboot/root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.2 --slot-size 0x6C000 build-dfu/zephyr/zephyr.bin signed-dfu-app.bin

Comfirm the signed bin is present.

ll signed-dfu-app.bin 
-rw-r--r-- 1 user user 42288 Jun 26 22:39 signed-dfu-app.bin

In my previous wiki, I chose to download this bin manually using pyocd, which is built-in to the standard zephyr sdk toolchain. Now, I use pyocd inside this docker image. I got some error messages.

user@1c30b4900ba4:/workdir/zephyrproject$ pyocd cmd
0000637:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
0000641:WARNING:board:Generic 'cortex_m' target type is selected; is this intentional? You will be able to debug but not program flash. To set the target type use the '--target' argument or 'target_override' option. Use 'pyocd list --targets' to see available targets types.
Connected to CoreSightTarget [Sleeping]: 0670FF323535474B43132338
>>> show map

>>> quit

However, I knew from the last time that pyocd saw my disco_l475_iot1 board as "stm32l475xg". It is the same physical board after all. I specified the target manually and that worked.

user@1c30b4900ba4:/workdir/zephyrproject$ pyocd cmd -t stm32l475xg
0000626:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L475xG [Sleeping]: 0670FF323535474B43132338
>>> show map
 Region  Start       End         Size        Access  Sector      Page       
 flash   0x08000000  0x080fffff  0x00100000  rx      0x00000800  0x00000400 
 sram2   0x10000000  0x10007fff  0x00008000  rwx     -           -          
 sram1   0x20000000  0x20017fff  0x00018000  rwx     -           -          
>>> 

Flashing to slot0 manually also worked. (Flashing bin file needs quite a number of command line options to specify where the image must go.)

user@1c30b4900ba4:/workdir/zephyrproject$ pyocd flash -e sector -a 0x08020000 -t stm32l475xg signed-dfu-app.bin
0001057:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
[====================] 100%
0004243:INFO:loader:Erased 43008 bytes (21 sectors), programmed 43008 bytes (42 pages), skipped 0 bytes (0 pages) at 14.62 kB/s

PuTTY showed bootloader messages "mcuboot", followed by app messages "main"

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.007,000] <inf> mcuboot: Primary image: magic=good, swap_type=0x4, copy_done=0x1, image_ok=0x1
[00:00:00.007,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.007,000] <inf> mcuboot: Boot source: none
[00:00:00.007,000] <inf> mcuboot: Swap type: none
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.062,000] <inf> main: This device supports USB DFU class.

Finally, I built Blinky app to run in slot-1.

west build -p auto -s zephyr/samples/basic/blinky -d build-blinky -b disco_l475_iot1 -- -DCONFIG_BOOTLOADER_MCUBOOT=y
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/zephyr/samples/basic/blinky
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: disco_l475_iot1
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1.dts
-- Generated zephyr.dts: /workdir/zephyrproject/build-blinky/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/build-blinky/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/zephyr/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1_defconfig'
Merged configuration '/workdir/zephyrproject/zephyr/samples/basic/blinky/prj.conf'
Merged configuration '/workdir/zephyrproject/build-blinky/zephyr/misc/generated/extra_kconfig_options.conf'
Configuration saved to '/workdir/zephyrproject/build-blinky/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/build-blinky/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/build-blinky
-- west build: building application
[1/130] Preparing syscall dependency handling

[125/130] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       14252 B       432 KB      3.22%
            SRAM:        4304 B        96 KB      4.38%
        IDT_LIST:         168 B         2 KB      8.20%
[130/130] Linking C executable zephyr/zephyr.elf

Use "west sign" got error.

user@1c30b4900ba4:/workdir/zephyrproject$ west sign -t imgtool -p bootloader/mcuboot/scripts/imgtool.py -d build-blinky -- --key bootloader/mcuboot/root-rsa-2048.pem
FATAL ERROR: extension command "sign" couldn't be run
  Hint: could not import /workdir/zephyrproject/zephyr/scripts/west_commands/sign.py
  See /tmp/west-exc-udf788su.txt for a traceback.


user@1c30b4900ba4:/workdir/zephyrproject$ more /tmp/west-exc-udf788su.txt
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/west/commands.py", line 369, in __call__
    mod = _commands_module_from_file(self.py_file)
  File "/usr/local/lib/python3.6/dist-packages/west/commands.py", line 338, in _commands_module_from_file
    spec.loader.exec_module(mod)
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/workdir/zephyrproject/zephyr/scripts/west_commands/sign.py", line 25, in <module>
    import edtlib
ModuleNotFoundError: No module named 'edtlib'

It turns out edtlib.py is part of zephyr script.

ls zephyr/scripts/dts/edtlib.py
zephyr/scripts/dts/edtlib.py

The first step of a non-docker build is to source zephyr-env.sh inside the zephyr source code directory. I thought this docker has already setup everything related to the environment. I was wrong. I should have done that initially before starting anything.

After source zephyr-env.sh, west sign worked.

user@1c30b4900ba4:/workdir/zephyrproject$ cd zephyr/
user@1c30b4900ba4:/workdir/zephyrproject/zephyr$ source zephyr-env.sh
user@1c30b4900ba4:/workdir/zephyrproject/zephyr$ cd ..


user@1c30b4900ba4:/workdir/zephyrproject$ west sign -t imgtool -p bootloader/mcuboot/scripts/imgtool.py -d build-blinky -- --key bootloader/mcuboot/root-rsa-2048.pem                                                                        
=== image configuration:                            
partition offset: 131072 (0x20000) 
partition size: 442368 (0x6c000)                                                                        
text section offset: 512 (0x200)                           
=== signed binaries:                                                     
bin: /workdir/zephyrproject/build-blinky/zephyr/zephyr.signed.bin
hex: /workdir/zephyrproject/build-blinky/zephyr/zephyr.signed.hex

The docker image already has dfu-util. I cannot use it inside docker image because the DFU device is not forwarded to the docker image yet.

user@1c30b4900ba4:/workdir/zephyrproject$ sudo dfu-util --alt 1 --download build-blinky/zephyr/zephyr.signed.bin
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
dfu-util: Cannot open DFU device 2fe3:0005
dfu-util: No DFU capable USB device available

I install dfu-util on the host and run it on the host.

/workdir/ in docker image is the new zephyr_docker_workdir/ I created. I can access the signed bin from the host.

sudo apt-get install dfu-util

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  dfu-util

Use dfu-util on the host to download the bin file. (Bin file!!!)

sudo dfu-util --alt 1 --download build-blinky/zephyr/zephyr.signed.bin

dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 2fe3:0005
Run-time device DFU version 0110
Claiming USB DFU Runtime Interface...
Determining device status: state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
Resetting USB...
Opening DFU USB Device...
Claiming USB DFU Interface...
Setting Alternate Setting #1 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0110
Device returned transfer size 128
Copying data from PC to DFU device
Download        [=========================] 100%        14588 bytes
Download done.
state(2) = dfuIDLE, status(0) = No error condition is present
Done!

Reset target with pyOCD to see the swapping of image.

user@1c30b4900ba4:/workdir/zephyrproject$ pyocd cmd -t stm32l475xg
0000564:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L475xG [Sleeping]: 0670FF323535474B43132338
>>> reset
Resetting target
>>> 

PuTTY

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.007,000] <inf> mcuboot: Primary image: magic=good, swap_type=0x4, copy_done=0x1, image_ok=0x1
[00:00:00.007,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.007,000] <inf> mcuboot: Boot source: none
[00:00:00.007,000] <inf> mcuboot: Swap type: test
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***

LED on the target board is blinking. It is the LED beside the ST-LINK usb port on my disco_l475_iot1.

When you are done watching the blinking LED, reset target with pyOCD to revert back to original image.

user@1c30b4900ba4:/workdir/zephyrproject$ pyocd cmd -t stm32l475xg
0000564:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L475xG [Sleeping]: 0670FF323535474B43132338
>>> reset
Resetting target
>>> 

PuTTY

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.007,000] <inf> mcuboot: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x3
[00:00:00.007,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.007,000] <inf> mcuboot: Boot source: none
[00:00:00.007,000] <inf> mcuboot: Swap type: revert
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.062,000] <inf> main: This device supports USB DFU class.

Build DFU example for STM nucleo_l452re board. First confirm the board name with west boards

west boards | grep 452
nucleo_l452re

Prepare the environment based on prior experience.

pip3 install cryptography
cd zephyrproject/
pushd  zephyr/ ; source zephyr-env.sh ; popd

Build bootloader

west build -p auto -s bootloader/mcuboot/boot/zephyr -d nucleo_l452re_build-mcuboot -b nucleo_l452re              

Actual result is an error.

west build -p auto -s bootloader/mcuboot/boot/zephyr -d nucleo_l452re_build-mcuboot -b nucleo_l452re 
-- west build: generating a build system
Including boilerplate (Zephyr base (cached)): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Board: nucleo_l452re
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts
-- Found devicetree overlay: /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr/dts.overlay
-- Found devicetree overlay: /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr/dts.overlay
nucleo_l452re.dts.pre.tmp:5.9-13: ERROR (path_references): /chosen: Reference to non-existent node or label "boot_partition"

  also defined at nucleo_l452re.dts.pre.tmp:29.9-32.4
  also defined at nucleo_l452re.dts.pre.tmp:513.9-519.4
  also defined at nucleo_l452re.dts.pre.tmp:574.9-576.4
  also defined at nucleo_l452re.dts.pre.tmp:579.9-581.4
ERROR: Input tree has errors, aborting (use -f to force output)
CMake Error at /workdir/zephyrproject/zephyr/cmake/dts.cmake:195 (message):
  command failed with return code: 2
Call Stack (most recent call first):
  /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake:510 (include)
  /workdir/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:24 (include)
  /workdir/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:40 (include_boilerplate)
  CMakeLists.txt:44 (find_package)


-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -B/workdir/zephyrproject/nucleo_l452re_build-mcuboot -S/workdir/zephyrproject/bootloader/mcuboot/boot/zephyr -GNinja

The DTS file for disco_l475_iot1 board is zephyr/boards/arm/disco_l475_iot1/disco_l475_iot1.dts. Under &flash0 node:

&flash0 {
	/*
	 * For more information, see:
	 * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
	 */
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 0x00010000>;
			read-only;
		};

		/*
		 * The flash starting at offset 0x10000 and ending at
		 * offset 0x1ffff is reserved for use by the application.
		 */

		slot0_partition: partition@20000 {
			label = "image-0";
			reg = <0x00020000 0x0006C000>;
		};
		slot1_partition: partition@8c000 {
			label = "image-1";
			reg = <0x0008C000 0x0006C000>;
		};
		scratch_partition: partition@f8000 {
			label = "image-scratch";
			reg = <0x000F8000 0x00006000>;
		};

		storage_partition: partition@fc000 {
			label = "storage";
			reg = <0x000fc000 0x00004000>;
		};
	};
};

The DTS file for nucleo_l452re board is zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts. The supplied file defines one big blob of flash address.

&flash0 {
	/*
	 * For more information, see:
	 * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
	 */
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;
		/*
		 * Reserve the final 16 KiB for file system partition
		 */
		storage_partition: partition@7c000 {
			label = "storage";
			reg = <0x0007c000 0x00008000>;
		};
	};
};

I need to create my own partition layout. I will check the size and address of the flash on NUCLEO-L452RE board with the help of pyocd. I need to learn the board type of NUCLEO-L452RE, according to pyocd.

pyocd list -b | grep 452
  0821   NUCLEO-L452RE                    stm32l452re             None                               
  0829   NUCLEO-L452RE-P                  stm32l452re             None

pyocd list
0000532:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
  #   Probe          Unique ID                 
-----------------------------------------------
  0   STM32 STLink   066DFF515055657867072315  

Pyocd does not have built-in target for stm32l452re. pyocd pack -f nor pyocd pack -i did not work.

I need to follow the steps for manual pack usage here. I got good help from the community throughout my troubleshooting link

First, download MDK5 Software Packs for STMicroelectronics STM32L4 Series Device here to my development host. This file is over 200MB. When the download completes, I move the file to make it appear to the docker image at /workdir/. Inside the docker image, use this command to see all variations of L452.

pyocd list --targets --pack /workdir/Keil.STM32L4xx_DFP.2.4.0.pack | grep 452
  stm32l452ccux             STMicroelectronics      STM32L452CCUx                STM32L4 Series, STM32L452   pack     
  stm32l452ceux             STMicroelectronics      STM32L452CEUx                STM32L4 Series, STM32L452   pack     
  stm32l452rcix             STMicroelectronics      STM32L452RCIx                STM32L4 Series, STM32L452   pack     
  stm32l452rctx             STMicroelectronics      STM32L452RCTx                STM32L4 Series, STM32L452   pack     
  stm32l452rcyx             STMicroelectronics      STM32L452RCYx                STM32L4 Series, STM32L452   pack     
  stm32l452reix             STMicroelectronics      STM32L452REIx                STM32L4 Series, STM32L452   pack     
  stm32l452retx             STMicroelectronics      STM32L452RETx                STM32L4 Series, STM32L452   pack     
  stm32l452reyx             STMicroelectronics      STM32L452REYx                STM32L4 Series, STM32L452   pack     
  stm32l452vcix             STMicroelectronics      STM32L452VCIx                STM32L4 Series, STM32L452   pack     
  stm32l452vctx             STMicroelectronics      STM32L452VCTx                STM32L4 Series, STM32L452   pack     
  stm32l452veix             STMicroelectronics      STM32L452VEIx                STM32L4 Series, STM32L452   pack     
  stm32l452vetx             STMicroelectronics      STM32L452VETx                STM32L4 Series, STM32L452   pack

From STM32CubeIDE project for my NUCLEO-L452RE board, I know the part on the board should use stm32l452retx. Testing using command line option.

Next, I created a file called mypyocd.yaml, according to insructions in configuration.md. Be careful with the ** indentation **! The docker image does not have vi nor nano. I created the file on the host and make it available to the docker image at /workdir/mypyocd.yaml

probes:
  066DFF515055657867072315: # Probe's unique ID. Replace with yours; don't use  mine.
    target_override:  stm32l452retx

# Global options
auto_unlock: false
frequency: 480000 # I have another dev board that use slow swd speed. You can try increasing the speed, until your probe fail to talk.
pack:
  - /workdir/Keil.STM32L4xx_DFP.2.4.0.pack

Invoke pyocd with my config yaml. The ERROR line is ok because I do not expose a USB mass storage volume from ST-LINK. Here for details.

pyocd cmd --config /workdir/mypyocd.yaml 
0000528:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L452RETx [Halted]: 066DFF515055657867072315
>>> reg
     r0: 0x00000000       r6: 0x00000000      r12: 0x00000000  
     r1: 0x2000011c       r7: 0x20027ff8       sp: 0x20027ff8  
     r2: 0x08006d18       r8: 0x00000000       lr: 0x080011f3  
     r3: 0x00000000       r9: 0x00000000       pc: 0x080004ec  
     r4: 0x00000000      r10: 0x00000000     xpsr: 0x61000000  
     r5: 0x00000000      r11: 0x00000000  primask: 0x00000000  
>>> show map
 Region      Start       End         Size        Access  Sector      Page       
 Main_Flash  0x08000000  0x0807ffff  0x00080000  rx      0x00000800  0x00000400 
 IRAM2       0x10000000  0x10007fff  0x00008000  rwx     -           -          
 SRAM        0x20000000  0x2001ffff  0x00020000  rwx     -           -          
 IRAM1       0x20000000  0x2001ffff  0x00020000  rwx     -           -          
>>>

You can halt the target if it is running. You need it to halt before you can interact with it. Interacting with the target confirms pyocd is properly configured.

Setting up pyocd for STM32L452RE is a digression. However, it is very useful. For example, I can build the blinky test app and flash it to my NUCLEO-L452RE using:

west build -p auto -s zephyr/samples/basic/blinky -d nucleo_l452re_build-blinky -b nucleo_l452re

pyocd flash --config /workdir/mypyocd.yaml nucleo_l452re_build-blinky/zephyr/zephyr.elf

I can also flash an elf file built from any other code base and toolchain, such as an STM32CubeIDE project.

pyocd flash --config mypyocd.yaml ~/STM32CubeIDE/workspace_1.2.0/swo/Debug/swo.elf
[====================] 100%
0001804:INFO:loader:Erased 2048 bytes (1 sector), programmed 2048 bytes (2 pages), skipped 14336 bytes (14 pages) at 16.43 kB/s

Back to the problem of partition. show map above tells me the start and end of flash on nucleo_l452re. Repeat that procedure on disco_l475_iot1 gives me the start and end of flash, and we can see the end address is different.

user@5d1ead943ded:/workdir$ pyocd cmd --config=/workdir/mypyocd.yaml 
0000630:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L475xG [Sleeping]: 0670FF323535474B43132338
>>> show map
 Region  Start       End         Size        Access  Sector      Page       
 flash   0x08000000  0x080fffff  0x00100000  rx      0x00000800  0x00000400 
 sram2   0x10000000  0x10007fff  0x00008000  rwx     -           -          
 sram1   0x20000000  0x20017fff  0x00018000  rwx     -           -          
>>> 

To fix this properly, I should create overlay dts. I am new to Zephyr and not yet familiar with that procedure. I just git branch the source and directly edit dts in my branch.

In my copy of zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts, I append the line zephyr,code-partition = &slot0_partition; at the end of chosen{} and replace the original &flash with its counterpart found in zephyrproject/zephyr/boards/arm/nucleo_f401re/nucleo_f401re.dts. The partition map of nucleo_f401re will fit the flash size of nucleo_l452re.

/*
 * Copied from nucleo_f401re.dts
 */

	chosen {
		zephyr,console = &usart2;
		zephyr,shell-uart = &usart2;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,can-primary = &can1;
		zephyr,code-partition = &slot0_partition;
	};

&flash0 {
	/*
	 * For more information, see:
	 * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
	 */
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 0x00010000>;
			read-only;
		};

		/*
		 * The flash starting at offset 0x10000 and ending at
		 * offset 0x1ffff is reserved for use by the application.
		 */

		slot0_partition: partition@20000 {
			label = "image-0";
			reg = <0x00020000 0x00020000>;
		};
		slot1_partition: partition@40000 {
			label = "image-1";
			reg = <0x00040000 0x00020000>;
		};
		scratch_partition: partition@60000 {
			label = "image-scratch";
			reg = <0x00060000 0x00020000>;
		};
	};
};

After a lot of work to figure out exact what to change, I can use docker image to build my MCUBoot for nucleo_l452re:

user@665c17764380:/workdir/zephyrproject$ pushd zephyr/                                                                                       [3/4767]
/workdir/zephyrproject/zephyr /workdir/zephyrproject                                                                                                  
user@665c17764380:/workdir/zephyrproject/zephyr$ source zephyr-env.sh                                                                                 
user@665c17764380:/workdir/zephyrproject/zephyr$ popd                                                                                                 
/workdir/zephyrproject                                                     
user@665c17764380:/workdir/zephyrproject$ pip3 install cryptography
Collecting cryptography
  Downloading https://files.pythonhosted.org/packages/58/95/f1282ca55649b60afcf617e1e2ca384a2a3e7a5cf91f724cf83c8fbe76a1/cryptography-2.9.2-cp35-abi3-
manylinux1_x86_64.whl (2.7MB)
    100% |████████████████████████████████| 2.7MB 246kB/s 
Collecting cffi!=1.11.3,>=1.8 (from cryptography)
  Downloading https://files.pythonhosted.org/packages/f1/c7/72abda280893609e1ddfff90f8064568bd8bcb2c1770a9d5bb5edb2d1fea/cffi-1.14.0-cp36-cp36m-manyli
nux1_x86_64.whl (399kB)
    100% |████████████████████████████████| 399kB 592kB/s 
Collecting six>=1.4.1 (from cryptography)
  Downloading https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.w
hl
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography)
  Downloading https://files.pythonhosted.org/packages/ae/e7/d9c3a176ca4b02024debf82342dab36efadfc5776f9c8db077e8f6e71821/pycparser-2.20-py2.py3-none-a
ny.whl (112kB)
    100% |████████████████████████████████| 112kB 2.0MB/s 
Installing collected packages: pycparser, cffi, six, cryptography
Successfully installed cffi-1.14.0 cryptography-2.9.2 pycparser-2.20 six-1.15.0
user@665c17764380:/workdir/zephyrproject$ west build -p always -s bootloader/mcuboot/boot/zephyr -d nucleo_l452re_build-mcuboot -b nucleo_l452re
-- west build: making build dir /workdir/zephyrproject/nucleo_l452re_build-mcuboot pristine
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: nucleo_l452re
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6"
)
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts
-- Found devicetree overlay: /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr/dts.overlay
-- Generated zephyr.dts: /workdir/zephyrproject/nucleo_l452re_build-mcuboot/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/nucleo_l452re_build-mcuboot/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/bootloader/mcuboot/boot/zephyr/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re_defconfig'
Merged configuration '/workdir/zephyrproject/bootloader/mcuboot/boot/zephyr/prj.conf'
Configuration saved to '/workdir/zephyrproject/nucleo_l452re_build-mcuboot/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/nucleo_l452re_build-mcuboot/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/nucleo_l452re_build-mcuboot
-- west build: building application
[1/240] Preparing syscall dependency handling

[235/240] Linking C executable zephyr/zephyr_prebuilt.elf                   
Memory region         Used Size  Region Size  %age Used
           FLASH:       43800 B        64 KB     66.83%
            SRAM:       26384 B       160 KB     16.10%
        IDT_LIST:         136 B         2 KB      6.64%
[240/240] Linking C executable zephyr/zephyr.elf 

Flash MCUBoot to nucleo_l452re

pyocd flash nucleo_l452re_build-mcuboot/zephyr/zephyr.elf
0000569:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
[====================] 100%
0003548:INFO:loader:Erased 45056 bytes (22 sectors), programmed 45056 bytes (44 pages), skipped 0 bytes (0 pages) at 17.50 kB/s

Watch nucleo_l452re boots with PuTTY

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.006,000] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Boot source: primary slot
[00:00:00.009,000] <inf> mcuboot: Swap type: none
[00:00:00.009,000] <err> mcuboot: Unable to find bootable image

There is not bootable image because I haven't built and flash DFU app into slot 0. I try to build slot 0 DFU app with:

west build -p auto -s zephyr/samples/subsys/usb/dfu -d nucleo_l452re_build-dfu -b nucleo_l452re

Again, error:

user@665c17764380:/workdir/zephyrproject$ west build -p always -s zephyr/samples/subsys/usb/dfu -d nucleo_l452re_build-dfu -b nucleo_l452re [117/5069]
-- west build: making build dir /workdir/zephyrproject/nucleo_l452re_build-dfu pristine                                                               
-- west build: generating a build system                                                                                                              
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake                                                        
-- Application: /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu                                                                                  
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: nucleo_l452re
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6"
)
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts
-- Generated zephyr.dts: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re_defconfig'
Merged configuration '/workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/prj.conf'
Configuration saved to '/workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
CMake Warning at ../../../../subsys/usb/CMakeLists.txt:28 (message):
  CONFIG_USB_DEVICE_VID has default value 0x2FE3.

  This value is only for testing and MUST be configured for USB products.


-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/nucleo_l452re_build-dfu
-- west build: building application
[1/155] Preparing syscall dependency handling

[76/155] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/usb/device/usb_dc_stm32.c.obj
FAILED: zephyr/CMakeFiles/zephyr.dir/drivers/usb/device/usb_dc_stm32.c.obj  
ccache /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -DBUILD_VERSION=zephyr-v2.3.0-608-g22be0d8fd590 -DCORE_CM4 -DKERNEL -
DSTM32L452xx -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -D_FORTIFY_SOURCE=2 -D__PROGRAM_START -D__ZEPHYR__=1 -I/workdir/zephyrproject/zephyr/include -Izeph
yr/include/generated -I/workdir/zephyrproject/zephyr/soc/arm/st_stm32/stm32l4 -I/workdir/zephyrproject/zephyr/drivers -I/workdir/zephyrproject/zephyr/
subsys/usb -I/workdir/zephyrproject/modules/hal/cmsis/CMSIS/Core/Include -I/workdir/zephyrproject/modules/hal/stm32/stm32cube/stm32l4xx/soc -I/workdir
/zephyrproject/modules/hal/stm32/stm32cube/stm32l4xx/drivers/include -I/workdir/zephyrproject/modules/hal/stm32/stm32cube/stm32l4xx/drivers/include/Le
gacy -isystem /workdir/zephyrproject/zephyr/lib/libc/minimal/include -isystem /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/../lib/gcc/arm-zep
hyr-eabi/9.2.0/include -isystem /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/9.2.0/include-fixed -Os -imacros/work
dir/zephyrproject/nucleo_l452re_build-dfu/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -mcpu=cortex-m4 -mthumb -mabi=aapcs -imacr
os/workdir/zephyrproject/zephyr/include/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-main -Wno-address-of-p
acked-member -Wno-pointer-sign -Wpointer-arith -Wno-unused-but-set-variable -Werror=implicit-int -fno-asynchronous-unwind-tables -fno-pie -fno-pic -fn
o-strict-overflow -fno-reorder-functions -fno-defer-pop -fmacro-prefix-map=/workdir/zephyrproject/zephyr/samples/subsys/usb/dfu=CMAKE_SOURCE_DIR -fmac
ro-prefix-map=/workdir/zephyrproject/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/workdir/zephyrproject=WEST_TOPDIR -ffunction-sections -fdata-sections -std
=c99 -nostdinc -MD -MT zephyr/CMakeFiles/zephyr.dir/drivers/usb/device/usb_dc_stm32.c.obj -MF zephyr/CMakeFiles/zephyr.dir/drivers/usb/device/usb_dc_s
tm32.c.obj.d -o zephyr/CMakeFiles/zephyr.dir/drivers/usb/device/usb_dc_stm32.c.obj   -c /workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.
c
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:183:44: error: 'USB_NUM_BIDIR_ENDPOINTS' undeclared here (not in a function)
  183 |  struct usb_dc_stm32_ep_state out_ep_state[USB_NUM_BIDIR_ENDPOINTS];
      |                                            ^~~~~~~~~~~~~~~~~~~~~~~
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c: In function 'usb_dc_stm32_clock_enable':
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:229:10: error: 'USB_CLOCK_BUS' undeclared (first use in this function)
  229 |   .bus = USB_CLOCK_BUS,
      |          ^~~~~~~~~~~~~
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:229:10: note: each undeclared identifier is reported only once for each function it ap
pears in
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:230:10: error: 'USB_CLOCK_BITS' undeclared (first use in this function)
  230 |   .enr = USB_CLOCK_BITS,
      |          ^~~~~~~~~~~~~~
In file included from /workdir/zephyrproject/zephyr/include/arch/arm/aarch32/irq.h:20,
                 from /workdir/zephyrproject/zephyr/include/arch/arm/aarch32/arch.h:27,
                 from /workdir/zephyrproject/zephyr/include/arch/cpu.h:19,
                 from /workdir/zephyrproject/zephyr/include/kernel_includes.h:39,
                 from /workdir/zephyrproject/zephyr/include/kernel.h:17,
                 from /workdir/zephyrproject/zephyr/include/init.h:11,
                 from /workdir/zephyrproject/zephyr/include/device.h:22,
                 from /workdir/zephyrproject/zephyr/include/drivers/usb/usb_dc.h:20,
                 from /workdir/zephyrproject/zephyr/include/usb/usb_device.h:39,
                 from /workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:51:
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c: In function 'usb_dc_stm32_init':
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:421:14: error: 'USB_IRQ' undeclared (first use in this function); did you mean 'USB_IR
Qn'?
  421 |  IRQ_CONNECT(USB_IRQ, USB_IRQ_PRI,
      |              ^~~~~~~
/workdir/zephyrproject/zephyr/include/sw_isr_table.h:71:5: note: in definition of macro 'Z_ISR_DECLARE'
   71 |    {irq, flags, (void *)&func, (void *)param}
      |     ^~~
/workdir/zephyrproject/zephyr/include/irq.h:49:2: note: in expansion of macro 'ARCH_IRQ_CONNECT'
   49 |  ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
      |  ^~~~~~~~~~~~~~~~
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:421:2: note: in expansion of macro 'IRQ_CONNECT'
  421 |  IRQ_CONNECT(USB_IRQ, USB_IRQ_PRI,
      |  ^~~~~~~~~~~
In file included from /workdir/zephyrproject/zephyr/include/arch/arm/aarch32/arch.h:27,
                 from /workdir/zephyrproject/zephyr/include/arch/cpu.h:19,
                 from /workdir/zephyrproject/zephyr/include/kernel_includes.h:39,
                 from /workdir/zephyrproject/zephyr/include/kernel.h:17,
                 from /workdir/zephyrproject/zephyr/include/init.h:11,
                 from /workdir/zephyrproject/zephyr/include/device.h:22,
                 from /workdir/zephyrproject/zephyr/include/drivers/usb/usb_dc.h:20,
                 from /workdir/zephyrproject/zephyr/include/usb/usb_device.h:39,
                 from /workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:51:
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:421:23: error: 'USB_IRQ_PRI' undeclared (first use in this function); did you mean 'US
B_IRQn'?
  421 |  IRQ_CONNECT(USB_IRQ, USB_IRQ_PRI,
      |                       ^~~~~~~~~~~
/workdir/zephyrproject/zephyr/include/arch/arm/aarch32/irq.h:111:32: note: in definition of macro 'ARCH_IRQ_CONNECT'
  111 |  z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
      |                                ^~~~~~~~~~
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:421:2: note: in expansion of macro 'IRQ_CONNECT'
  421 |  IRQ_CONNECT(USB_IRQ, USB_IRQ_PRI,
      |  ^~~~~~~~~~~
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c: In function 'usb_dc_ep_configure':
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:608:7: error: 'USB_RAM_SIZE' undeclared (first use in this function); did you mean 'SR
AM2_SIZE'?
  608 |   if (USB_RAM_SIZE <=
      |       ^~~~~~~~~~~~
      |       SRAM2_SIZE
In file included from /workdir/zephyrproject/zephyr/include/arch/arm/aarch32/irq.h:19,
                 from /workdir/zephyrproject/zephyr/include/arch/arm/aarch32/arch.h:27,
                 from /workdir/zephyrproject/zephyr/include/arch/cpu.h:19,
                 from /workdir/zephyrproject/zephyr/include/kernel_includes.h:39,
                 from /workdir/zephyrproject/zephyr/include/kernel.h:17,
                 from /workdir/zephyrproject/zephyr/include/init.h:11,
                 from /workdir/zephyrproject/zephyr/include/device.h:22,
                 from /workdir/zephyrproject/zephyr/include/drivers/usb/usb_dc.h:20,
                 from /workdir/zephyrproject/zephyr/include/usb/usb_device.h:39,
                 from /workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:51:
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c: In function 'usb_dc_ep_write':
/workdir/zephyrproject/zephyr/drivers/usb/device/usb_dc_stm32.c:776:15: error: 'USB_IRQ' undeclared (first use in this function); did you mean 'USB_IR
Qn'?
  776 |   irq_disable(USB_IRQ);
      |               ^~~~~~~
/workdir/zephyrproject/zephyr/include/irq.h:399:43: note: in definition of macro 'irq_disable'
  399 | #define irq_disable(irq) arch_irq_disable(irq)
      |                                           ^~~
[81/155] Building C object zephyr/arch/arch/arm/core/aarch32/cortex_m/mpu/CMakeFiles/arch__arm__core__aarch32__cortex_m__mpu.dir/arm_core_mpu.c.obj
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake --build /workdir/zephyrproject/nucleo_l452re_build-dfu

I had built the DFU sample app for disco_l475_iot1 without any error. What is wrong with nucleo_l452re?? After a long deliberation, I tried building DFU app for several nucleo boards. I found that these work:

west build -p auto -s zephyr/samples/subsys/usb/dfu -d nucleo_wb55rg_build-dfu -b nucleo_wb55rg
west build -p auto -s zephyr/samples/subsys/usb/dfu -d disco_l475_iot1_build-dfu -b disco_l475_iot1
west build -p auto -s zephyr/samples/subsys/usb/dfu -d nucleo_f429zi_build-dfu -b nucleo_f429zi

These failed:

west build -p auto -s zephyr/samples/subsys/usb/dfu -d nucleo_f401re_build-dfu -b nucleo_f401re
west build -p auto -s zephyr/samples/subsys/usb/dfu -d nucleo_f446re_build-dfu -b nucleo_f446re

I read the files in their board directories to find out what did the successful boards have in common versus those failed boards. It turned out the reason makes perfect sense. The dts files of the successful boards had usb enabled; failed boards had nothing.

disco_l475_iot1.dts
&usbotg_fs {
	status = "okay";
};

nucleo_wb55rg.dts
&usb {
	status = "okay";
};

nucleo_f429zi.dts
&usbotg_fs {
	status = "okay";
};

I used STM32CubeIDE to check the USB hardware on disco_l475_iot1 and nucleo_l452re. My STM32CubeIDE project for disco_l475_iot1 showed the usb hardware was usbotg_fs. My STM32CubeIDE project for nucleo_l452re showed the usb hardware was usb. Hence, the solution is to enable usb in nucleo_l452re.dts with

&usb {
	status = "okay";
};

Successfully build DFU app for slot 0

west build -p always -s zephyr/samples/subsys/usb/dfu -d nucleo_l452re_build-dfu -b nucleo_l452re
-- west build: making build dir /workdir/zephyrproject/nucleo_l452re_build-dfu pristine
-- west build: generating a build system
Including boilerplate (Zephyr base): /workdir/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu
-- Zephyr version: 2.3.99 (/workdir/zephyrproject/zephyr)
-- Found Python3: /usr/bin/python3.6 (found suitable exact version "3.6.9") found components: Interpreter 
-- Board: nucleo_l452re
-- Found toolchain: zephyr (/opt/toolchains/zephyr-sdk-0.11.2)
-- Found west: /usr/local/bin/west (found suitable version "0.7.2", minimum required is "0.7.1")
-- Found dtc: /opt/toolchains/zephyr-sdk-0.11.2/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
-- Found BOARD.dts: /workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re.dts
-- Generated zephyr.dts: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/include/generated/devicetree_unfixed.h
Parsing /workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/Kconfig
Loaded configuration '/workdir/zephyrproject/zephyr/boards/arm/nucleo_l452re/nucleo_l452re_defconfig'
Merged configuration '/workdir/zephyrproject/zephyr/samples/subsys/usb/dfu/prj.conf'
Configuration saved to '/workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/.config'
Kconfig header saved to '/workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/include/generated/autoconf.h'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/toolchains/zephyr-sdk-0.11.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Cache files will be written to: /home/user/.cache/zephyr
CMake Warning at ../../../../subsys/usb/CMakeLists.txt:28 (message):
  CONFIG_USB_DEVICE_VID has default value 0x2FE3.

  This value is only for testing and MUST be configured for USB products.


-- Configuring done
-- Generating done
-- Build files have been written to: /workdir/zephyrproject/nucleo_l452re_build-dfu
-- west build: building application
[1/155] Preparing syscall dependency handling

[150/155] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       39968 B       128 KB     30.49%
            SRAM:       11152 B       160 KB      6.81%
        IDT_LIST:         136 B         2 KB      6.64%
[155/155] Linking C executable zephyr/zephyr.elf

Sign DFU app

user@665c17764380:/workdir/zephyrproject$ west sign -t imgtool -p bootloader/mcuboot/scripts/imgtool.py -d nucleo_l452re_build-dfu -- --key bootloader/mcuboot/root-rsa-2048.pem
=== image configuration:
partition offset: 131072 (0x20000)
partition size: 131072 (0x20000)
text section offset: 512 (0x200)
=== signed binaries:
bin: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/zephyr.signed.bin
hex: /workdir/zephyrproject/nucleo_l452re_build-dfu/zephyr/zephyr.signed.hex

Flash the hex file to slot 0. (Flashing hex file is easy. The file contains destination address.)

user@665c17764380:/workdir/zephyrproject$ pyocd flash nucleo_l452re_build-dfu/zephyr/zephyr.signed.hex
0000579:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
[====================] 100%
0003482:INFO:loader:Erased 40960 bytes (20 sectors), programmed 40960 bytes (40 pages), skipped 0 bytes (0 pages) at 17.00 kB/s

Watch target boot via PuTTY. This time I have mcuboot messages and main message from the DFU app.

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.006,000] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Boot source: primary slot
[00:00:00.009,000] <inf> mcuboot: Swap type: none
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> main: This device supports USB DFU class.

Build slot 1 blinky app (with CONFIG_BOOTLOADER_MCUBOOT=y). Surprise. It succeeded without any issue at all.

west build -p auto -s zephyr/samples/basic/blinky -d nucleo_l452re_build-blinky -b nucleo_l452re -- -DCONFIG_BOOTLOADER_MCUBOOT=y

Sign blinky app

user@665c17764380:/workdir/zephyrproject$ west sign -t imgtool -p bootloader/mcuboot/scripts/imgtool.py -d nucleo_l452re_build-blinky -- --key bootloader/mcuboot/root-rsa-2048.pem
=== image configuration:
partition offset: 131072 (0x20000)
partition size: 131072 (0x20000)
text section offset: 512 (0x200)
=== signed binaries:
bin: /workdir/zephyrproject/nucleo_l452re_build-blinky/zephyr/zephyr.signed.bin
hex: /workdir/zephyrproject/nucleo_l452re_build-blinky/zephyr/zephyr.signed.hex

Hardware engineer at work had soldered a USB cable to the USB pins of the L452RE. I plugged that USB cable to x86 host running ubuntu 20.04. lsusb showed the DFU device.

Bus 002 Device 016: ID 2fe3:0005 ZEPHYR Zephyr DFU sample

On the host, use dfu-util to download the signed bin file of blinky app. (Bin file!!!)

sudo dfu-util --alt 1 --download  nucleo_l452re_build-blinky/zephyr/zephyr.s
igned.bin
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 2fe3:0005
Run-time device DFU version 0110
Claiming USB DFU Runtime Interface...
Determining device status: state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
Resetting USB...
Opening DFU USB Device...
Claiming USB DFU Interface...
Setting Alternate Setting #1 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0110
Device returned transfer size 128
Copying data from PC to DFU device
Download        [=========================] 100%        13660 bytes
Download done.
state(2) = dfuIDLE, status(0) = No error condition is present
Done!

Use pyocd in docker image to reset the target.

user@7edb1e020c48:/workdir/zephyrproject$ pyocd cmd
0000916:ERROR:linux:Could not get disk devices by id. This could be because your Linux distribution does not use udev, or does not create /dev/disk/by-id symlinks. Please submit an issue to github.com/armmbed/mbed-ls.
Connected to STM32L452RETx [Running]: 066DFF515055657867072315
>>> reset
Resetting target
>>> 

Watch target boot via PuTTY. Notice mcuboot says Swap type: test

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.006,000] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Boot source: primary slot
[00:00:00.009,000] <inf> mcuboot: Swap type: test
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***

I don't see any blinking LED on nucleo_l452re. I guess that may require more dts changes. I had worked so hard to accomplish all the above. I am too tired to fight for a blinking LED.

I reset my target board again to confirm MCUBoot revert back to the previous app. Sure enough mcuboot showed Swap type: revert and main showed This device supports USB DFU class. Daiseikou!!!

*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> mcuboot: Starting bootloader
[00:00:00.006,000] <inf> mcuboot: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.006,000] <inf> mcuboot: Boot source: none
[00:00:00.006,000] <inf> mcuboot: Swap type: revert
*** Booting Zephyr OS build zephyr-v2.3.0-608-g22be0d8fd590  ***
[00:00:00.005,000] <inf> main: This device supports USB DFU class.
⚠️ **GitHub.com Fallback** ⚠️