stm32f429i-disc1#

Pigweed AI summary: The STMicroelectronics STM32F429I-DISC1 development board is the primary target for on-device testing and development for Pigweed. To build for this target, simply build the top-level "stm32f429i" Ninja target. When working in upstream Pigweed, building this target will build all Pigweed modules' unit tests. These tests can be run on-device in a few different ways, including running a unit test or running multiple tests using Pigweed's "pw test" command

The STMicroelectronics STM32F429I-DISC1 development board is currently Pigweed’s primary target for on-device testing and development.

Building#

Pigweed AI summary: To build for the Pigweed target, the top-level "stm32f429i" Ninja target should be built using the command "ninja -C out stm32f429i".

To build for this Pigweed target, simply build the top-level “stm32f429i” Ninja target.

$ ninja -C out stm32f429i

Testing#

Pigweed AI summary: The article explains how to run unit tests for Pigweed modules on an STM32f429I-DISC1 device. It provides instructions for running a single test, running multiple tests, and running tests affected by code changes. The article also explains how to set up a test server and configure GN to enable incremental testing.

When working in upstream Pigweed, building this target will build all Pigweed modules’ unit tests. These tests can be run on-device in a few different ways.

Run a unit test#

Pigweed AI summary: To run unit tests using the "out" build directory, the tests can be found in a specific location and can be run on a device using the stm32f429i-disc1 target helper script. The script flashes the test to the device and runs it. To run the test, the pigweed environment must be set up and the stm32f429i_disc1_unit_test_runner command must be used with the path to the binary.

If using out as a build directory, tests will be located in out/stm32f429i_disc1_debug/obj/[module name]/[test_name].elf. To run these on device, the stm32f429i-disc1 target provides a helper script that flashes the test to a device and then runs it.

# Setup pigweed environment.
$ source activate.sh
# Run test.
$ stm32f429i_disc1_unit_test_runner /path/to/binary

Run multiple tests#

Pigweed AI summary: To make running multiple tests easier, use Pigweed's "pw test" command and pass it a path to the build directory and the name of the test runner. The command can be restricted to specific test targets using the "--group" argument or individual test binaries can be specified with the "--test" option. A sample command is provided in a literal block.

Running all tests one-by-one is rather tedious. To make running multiple tests easier, use Pigweed’s pw test command and pass it a path to the build directory and the name of the test runner. By default, pw test will run all tests, but it can be restricted it to specific pw_test_group targets using the --group argument. Alternatively, individual test binaries can be specified with the --test option.

# Setup Pigweed environment.
$ source activate.sh
# Run test.
$ pw test --root out/stm32f429i_disc_debug/  \
      --runner stm32f429i_disc1_unit_test_runner

Run tests affected by code changes#

Pigweed AI summary: This article explains how to run tests that are affected by code changes using GN/Ninja build. The process involves using a pw_target_runner_server that Ninja can send tests to as it rebuilds affected targets. This method also enables distributed testing across multiple devices to speed up testing. The article provides three steps to follow: starting the test server, configuring GN, and building changes. The article also includes a tip that if any hardware changes occur, the test server needs to be restarted for proper detection.

When writing code that will impact multiple modules, it’s helpful to only run all tests that are affected by a given code change. Thanks to the GN/Ninja build, this is possible! This is done by using a pw_target_runner_server that Ninja can send the tests to as it rebuilds affected targets.

Additionally, this method enables distributed testing. If multiple devices are connected, the tests will be run across all attached devices to further speed up testing.

Step 1: Start test server#

Pigweed AI summary: To run tests on multiple devices, Ninja sends test requests to a background server. The first step is to launch this server, which by default detects all attached STM32f429I-DISC1 boards. A custom server configuration file can be provided to override this behavior. If any hardware changes occur, the test server must be restarted. The command to start the test server is "stm32f429i_disc1_test_server".

To allow Ninja to properly serialize tests to run on an arbitrary number of devices, Ninja will send test requests to a server running in the background. The first step is to launch this server. By default, the script will attempt to automatically detect all attached STM32f429I-DISC1 boards and use them for testing. To override this behavior, provide a custom server configuration file with --server-config.

Tip

If you unplug or plug in any boards, you’ll need to restart the test server for hardware changes to properly be detected.

$ stm32f429i_disc1_test_server

Step 2: Configure GN#

Pigweed AI summary: This section explains how to configure GN for a hardware target by enabling the pw_use_test_server build arg, which allows requests to be sent to a running stm32f429i_disc1_test_server. The article provides a code snippet that shows how to modify and save the args file to use pw_target_runner.

By default, this hardware target has incremental testing via pw_target_runner disabled. Enabling the pw_use_test_server build arg tells GN to send requests to a running stm32f429i_disc1_test_server.

$ gn args out
# Modify and save the args file to use pw_target_runner.
pw_use_test_server = true

Step 3: Build changes#

Pigweed AI summary: This section explains that running "ninja -C out stm32f429i" will build and run affected tests on attached devices, or alternatively, "pw watch" can be used to automatically build and test whenever changes are made to source files.

Whenever you run ninja -C out stm32f429i, affected tests will be built and run on the attached device(s). Alternatively, you may use pw watch to set up Pigweed to build/test whenever it sees changes to source files.

RPC server#

Pigweed AI summary: The stm32f429i target has a system RPC server that can be accessed through a UART driver. To connect to a device running the RPC server, use the command "pw rpc -d <device> -b 115200 <protos>".

The stm32f429i target implements a system RPC server that over a simple UART driver. To communicate with a device running the RPC server, run pw rpc -d <device> -b 115200 <protos>.

Debugging#

Pigweed AI summary: The article discusses how to debug a device using OpenOCD debugger and STLink debugger on the Discovery board. The article provides a step-by-step guide on how to connect OpenOCD to the device, connect GDB to the running OpenOCD instance, flash, run, and debug the device. The article also provides typical output for each step and suggests using commercial tools like SEGGER's J-Link for debugging.

There are multiple ways to debug the device, including using commercial tools like SEGGER’s J-Link. However, the Discovery board has an on-board STLink debugger, which is supported by the open source OpenOCD debugger. To debug with OpenOCD requires a few steps. Summary version of the steps:

  1. Connect OpenOCD to the device in terminal A. Leave this running

    $ openocd -f targets/stm32f429i_disc1/py/stm32f429i_disc1_utils/openocd_stm32f4xx.cfg
    
  2. Connect GDB to the running OpenOCD instance in terminal B

    $ arm-none-eabi-gdb -ex "target remote :3333" \
      out/stm32f429i_disc1_debug/obj/pw_assert/test/assert_facade_test.elf
    
  3. Flash (load), run (mon reset run; continue), and debug

    (gdb) set print pretty on
    (gdb) load
    (gdb) mon reset run
    (gdb) continue
    
  4. You can re-flash the device after compiling by running load.

Step 1: Start an OpenOCD server and connect to the device#

Pigweed AI summary: This section provides instructions on how to start an OpenOCD server and connect it to a device, specifically the Discovery board. OpenOCD is a persistent server that bridges between GDB and the device. The command to run OpenOCD for the Discovery board is provided, along with typical output that includes information on the selected transport, listening ports, clock speed, target voltage, and starting the gdb server.

OpenOCD is a persistent server that you run and leave running to bridge between GDB and the device. To run it for the Discovery board:

$ openocd -f targets/stm32f429i_disc1/py/stm32f429i_disc1_utils/openocd_stm32f4xx.cfg

Typical output:

Open On-Chip Debugger 0.10.0+dev-01243-ge41c0f49-dirty (2020-05-21-10:27)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter driver' not 'interface'
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 : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Info : STLINK V2J25M14 (API v2) VID:PID 0483:374B
Info : Target voltage: 2.871879
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections

Step 2: Start GDB and connect to the OpenOCD server#

Pigweed AI summary: This section provides instructions on how to start GDB and connect it to the OpenOCD server. The user needs to point GDB to the correct .elf file and specify the OpenOCD server port (default is 3333). The example provided debugs the assert facade test, but the user can substitute their own ELF file. The output should show the GDB version and configuration details, as well as the remote debugging using the specified port.

Start GDB pointing to the correct .elf file, and tell it to connect to the OpenOCD server (running on port 333 by default).

$ arm-none-eabi-gdb -ex "target remote :3333" \
  out/stm32f429i_disc1_debug/obj/pw_assert/test/assert_facade_test.elf

In this case the assert facade test is debugged, but substitute your own ELF file. This should produce output similar to the following:

GNU gdb (GNU Arm Embedded Toolchain 9-2020-q2-update) 8.3.1.20191211-git
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from out/stm32f429i_disc1_debug/obj/pw_assert//test/assert_facade_test.elf...
Remote debugging using :3333
pw_BootEntry () at ../pw_boot_cortex_m/core_init.c:117
117     }

Step 3: Flash, run, and debug#

Pigweed AI summary: This section provides instructions on how to flash, run, and debug a device using GDB. To flash, the command "load" is used, which produces output indicating the loading of different sections. To reset the device and halt on the first instruction, the command "mon reset run" is used, which also produces output. Once the device is ready for debugging, breakpoints can be placed and the device can be started with the "continue" command.

Now that the GDB instance is connected to the device, you can flash, run, and debug.

To flash

(gdb) load

This will produce output similar to:

(gdb) load
Loading section .vector_table, size 0x10 lma 0x8000000
Loading section .code, size 0xdb8c lma 0x8000200
Loading section .ARM, size 0x8 lma 0x800dd90
Loading section .static_init_ram, size 0x1d0 lma 0x800dd98
Start address 0x8007c48, load size 56692
Transfer rate: 25 KB/sec, 8098 bytes/write.

To reset the device and halt on the first instruction (before main):

(gdb) mon reset run

This will produce output similar to:

(gdb) mon reset run
Unable to match requested speed 2000 kHz, using 1800 kHz
Unable to match requested speed 2000 kHz, using 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08007930 msp: 0x20030000
Unable to match requested speed 8000 kHz, using 4000 kHz
Unable to match requested speed 8000 kHz, using 4000 kHz

The device is now ready for debugging. You can place breakpoints and start the device with continue.