This document describes how to attach a debugger with SWD in order to debug the FPMCU with gdb or to flash the FPMCU.
SWD (Single Wire Debug) was introduced by ARM with the Cortex-M family to reduce the pin count required by JTAG. JTAG requires 5 pins, but SWD can be done with only 3 pins. Furthermore, one of the freed up pins can be repurposed for tracing.
See CoreSight Connectors for details on the three standard types of connectors used for JTAG and SWD for ARM devices.
gdbserver. This document will assume CLion (Googlers see CLion for ChromeOS) and was tested with JLink v8.10a. Alternatively, you can use Ozone, a standalone debugger from Segger.Install the JLink software in the chroot with the following command:
(chroot) $ sudo emerge jlink
The connector for SWD is J5 on Dragonclaw v4. It is labeled as CoreSight20.
SW5 on the edge of Dragonclaw must be set to C-SGHT.| Dragonclaw v4 with 20-pin SWD (0.05" / 1.27mm) on J5 |
|---|
The connector for SWD is labeled with CORESIGHT20 DB CONN on Icetower v3.
JTAG on Icetower must be set to CORESIGHT (not SERVO).
Icetower v3 with 20-pin SWD (0.05" / 1.27mm) on CORESIGHT20 DB CONN. |
|---|
The connector for SWD is J4. It is labeled with CORESIGHT20.
SW2 on the edge of Quincy must be set to C-SGHT, the JEN# switch (SW7) must be set low, and CONFIG_ENABLE_JTAG_SELECTION must be enabled for the board. If the board has not been reworked, you must reset or toggle the power to the board after starting servod to work around http://b/372308953. You can press SW10 (next to the servo connector) to reset.Quincy v3 with 20-pin SWD (0.05" / 1.27mm) on J4. |
|---|
Servo Micro can provide both the 3.3V for the MCU and 1.8V for the sensor.
Run the following to start servod, which will enable power to these rails by default:
(chroot) $ sudo servod --board=<BOARD>
where <BOARD> is the board you are working with (dartmonkey, bloonchipper, or helipilot).
Theoretically, it's also possible to power through J-Trace, though the power pin on J-Trace only outputs 5V, whereas the MCU runs at 3.3V and the sensor runs at 1.8V. The pin is also not connected on the current designs.
(chroot) $ cd ~/trunk/src/platform/ec
# JLinkRemoteServerCLExe will listen on port 19020 (among others) by default. # This can be overridden with the -Port argument. (chroot) $ sudo JLinkRemoteServerCLExe -select USB
You should see the following:
SEGGER J-Link Remote Server V8.10a Compiled Oct 2 2024 14:20:10 'q' to quit '?' for help 2024-09-13 18:07:20 - Remote Server started 2024-09-13 18:07:20 - Connected to J-Link with S/N 123456 2024-09-13 18:07:20 - Waiting for client connections...
(chroot) $ cd ~/trunk/src/platform/ec
(chroot) $ make BOARD=<BOARD> -j
replacing <BOARD> with bloonchipper, dartmonkey, or helipilot.
flash_jlink.py script:(chroot) $ ~/trunk/src/platform/ec/util/flash_jlink.py --board <BOARD> --image ./build/<BOARD>/ec.bin
replacing <BOARD> with bloonchipper, dartmonkey, or helipilot.
Start the JLink gdbserver for the appropriate MCU type and interface speed:
STM32F412CGSTM32H743ZINPCX998FDragonclaw:
(chroot) $ JLinkGDBServerCLExe -select USB -device STM32F412CG -endian little -if SWD -speed auto -noir -noLocalhostOnly
Icetower:
(chroot) $ JLinkGDBServerCLExe -select USB -device STM32H743ZI -endian little -if SWD -speed auto -noir -noLocalhostOnly
Quincy:
CONFIG_ENABLE_JTAG_SELECTION is enabled for the board (Example).(chroot) $ JLinkGDBServerCLExe -select USB -device NPCX998F -endian little -if SWD -speed 4000 -noir -noLocalhostOnly
You should see the port that gdbserver is running on in the output:
Connecting to J-Link... J-Link is connected. Firmware: J-Trace PRO V2 Cortex-M compiled Feb 5 2021 14:50:19 Hardware: V2.00 S/N: XXXXX Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB Checking target voltage... Target voltage: 3.30 V Listening on TCP/IP port 2331 <--- gdbserver port Connecting to target... Connected to target Waiting for GDB connection...
Configure your editor to use this .gdbinit, taking care to set the correct environment variables for the BOARD and GDBSERVER being used. For CLion, if you want to use a .gdbinit outside of your HOME directory, you'll need to configure ~/.gdbinit.
In your editor, specify the IP address and port for gdbserver:
127.0.0.1:2331
You will also want to provide the symbol files:
build/<board>/RW/ec.RW.elfbuild/<board>/RO/ec.RO.elfAlso, since we‘re compiling the firmware in the chroot, but your editor is running outside of the chroot, you’ll want to remap the source code path to account for this:
/home/<username>/trunk/src/platform/ec${HOME}/chromiumos/src/platform/ecTo debug with CLion, you will create a new GDB Remote Debug Configuration called EC Debug, with:
'target remote' args (gdbserver IP and port from above): 127.0.0.1:2331Symbol file (RW or RO ELF): /path/to/build/<board>/RW/ec.RW.elfPath mapping: Add remote to local source path mapping as described above.After configuring this if you select the EC Debug target in CLion and click the debug icon, CLion and JLink will handle automatically flashing the ELF file and stepping through breakpoints in the code. Even if not debugging, this may help with your iterative development flow since the JLink tool can flash very quickly since it performs a differential flash. Note that you still need to recompile after making changes to the source code before launching the debugger.
Ozone is a free standalone debugger provided by Segger that works with the J-Trace. You may want to use it if you need more powerful debug features than gdbserver can provide. For example, Ozone has a register mapping for the MCUs we use, so you can easily inspect CPU registers. It can also be automated with a scripting language and show code coverage when used with a J-Trace that is connected to the trace pins on a board. Note that the Dragonclaw v4 uses an STM32F412 package that does not have the synchronous trace pins, but the Nucleo STM32F412ZG does have the trace pins.