Skip to content

Instantly share code, notes, and snippets.

@dreamcat4
Last active December 15, 2023 19:53
Show Gist options
  • Save dreamcat4/9022f7efd0e73f411b677fe0ad8b2708 to your computer and use it in GitHub Desktop.
Save dreamcat4/9022f7efd0e73f411b677fe0ad8b2708 to your computer and use it in GitHub Desktop.
openocd stlinkv2 - connecting to aixun t3a swd debugging port

Connect aixun 3ta over SWD pins / stlinkv2

This instructions covers how to connect via openocd on linux platform. And assuming you have the STLINKv2 hardware dongle. And that you have wired it up correctly, to the aixun t3a's debugging port.

NOTE:

  • Case 1) The swd debugging port should normally only be connected up between your PC and the soldering station. When the target device (the aixun t3a) is fully powered off, and it's mains cable unplugged from the outlet. To avoid having dual powering (both connected), or to avoid grounding / reference issues.
  • Case 2) However for live debugging scenarios, or working on firmwares etc. Then you typically would instead disconnect the +3v3 power pin from the SWD port on the STLINKv2. And just tie the GNDs together. To keep the ground reference only. Then have the target DUT (the mcu in the aixun) being powered independantly by itself. Just being aware that this is more risky or delicate situation than when passively powering from the STLINKv2 in the safer offline fashion, with the t3a powered off, all excpt it's mcu.
  • However whether or not passively powering the target mcu from the PC (case 1, passive powering the target mcu alone), or having the aixun instead actively switched on and fully powering itself with +3v3 swd port pin disconnected (case 2, live debugging), the below steps all remains the same:

Compile openocd from git master (to avoid gd32 bug with libusb 1.24+)

As of 11-Oct-2022, there is a bug in openocd. It causes segfault when trying to connect to these GD32 mcus over libusb >= v1.0.24. However a fix for that bug has already been committed into git master branch of openocd. As was first found here, and here and then finally here.

However in future versions of openocd, then that bug fix will have been included. Then it will no longer be necessary to compile from git anymore. Just depends whether or not you are seeing openocd program segfaulting (or not!) when it's connecting. Anyhow in the meantime... here's how to compile from git:

mkdir ~/.builds/embedded
cd ~/.builds/embedded
git clone https://github.com/openocd-org/openocd.git
cd openocd
./bootstrap
./configure
make

If build was successful, then:

  • openocd executable binary should appear located at ./src/openocd
  • ./tcl folder containing scripts and targets various config files etc.

Run openocd

Assuming you are in the openocd git repo downloaded folder (in above example was ~/.builds/embedded/openocd). And assuming the build was successful then:

# navigate into scripts / config files subtree. (or use `-s` flag to specify directory path)
cd ./tcl

# run git master compiled openocd binary, and override the cpu_id for these GD32 clone chip (exact chip on the aixun t3a was GD32F303RCT6, with 512kb flash)
# use debug flag `-d4` to help debug any issues...
../src/openocd -d4 -f interface/stlink.cfg -c "set CPUTAPID 0x2ba01477" -f target/stm32f1x.cfg -c "init; reset halt"

if successful connection, then run the same cmdline again but without the -d4 debug flah. And command log output should say waiting for connections:

../src/openocd -f interface/stlink.cfg -c "set CPUTAPID 0x2ba01477" -f target/stm32f1x.cfg -c "init; reset halt"
Open On-Chip Debugger 0.12.0-rc1+dev-00943-gdc6cad855 (2022-10-11-21:37)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
0x2ba01477
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 1000 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.154375
Info : [stm32f1x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections
[stm32f1x.cpu] halted due to breakpoint, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000148 msp: 0x200013b8
[stm32f1x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000148 msp: 0x200013b8
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

Connect over telnet

At this point, you need to leave the openocd program running in the background. Leave the 1st terminal open and running. Then open up a 2nd new terminal, to connect to the openocd server (over telnet protocol typically, otherwise gdb dor debugging)

# Connect to openocd over telnet, for issuing manual commands
telnet 127.0.0.1 4444

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
> 

Now it's possible to query help and run commands, for example:

# Query help for managing the target device's flash memory
flash help

# Get an overview of the flash banks
flash list

# Get a memory map layout for flash bank 0
flash info 0

# Read flash bank 0, and dump it all into a file on your PC
flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.512k.dump.bin

Flash Area and Device Binning

It is recommend to dump the full 512kb flash area. And then manually check on which half of the address range is actually written the firmware code.

Explanation:

The cpu id of 0x2ba01477 does seem to match the chip label markings GD32F303RCT6. The flash memory size in the specs is listed as being 256kb in those published product marketing materials. However openocd program is having trouble to successfully detect and identify the flash size. Perhaps because it's a clone STM32 device, which is slightly different.

> flash list
{name stm32f1x.flash driver stm32f1x base 134217728 size 0 bus_width 0 chip_width 0 target stm32f1x.cpu}
> flash info 0
device id = 0x21040414
STM32 flash size failed, probe inaccurate - assuming 512k flash
flash size = 512 KiB
#0 : stm32f1x at 0x08000000, size 0x00080000, buswidth 0, chipwidth 0
	#  0: 0x00000000 (0x1000 4kB) not protected
	#  1: 0x00001000 (0x1000 4kB) not protected

The default flash dump command with no extra arguments (as above, in previous section). Will dump the entire 512kb readable address area. Which is common to all such family of similar devices (which shares this same similar silicon die). They are just branded and afterwards selected or binned to be different part numbers. Depending on either quality checks or product segmentation etc.

Therefore this model (id) of chip is only officially certified to be tested (and assured as fully working) for a smaller 256kb flash area within this total full 512kb flash are of these same silicon die. The remainder of the rest of the full extended 512kb flash are might be good or bad (it is not known). And might vary from sample to sample. Depending on the quality and nature of those product binning process (again not known).

Dumping Flash

It is recommend to dump the full 512kb flash area. And then manually check on which half of the address range is actually written the firmware code.

When the full accessible 512kb are of the whole flash area was dumped. We checked the contents of the whole 512kb area. And found that:

  • Only the 1st half, up to 256kb addressable area contained any real data or program code for these aizun t3a device.

  • This is seen in the hex editor as the hex range from 0000:0000 to 0003:FFFF

  • The 2nd half remainder was all 0xFF left unused.

  • This is seen in the hex editor as the hex range from 0004:0000 to 0007:FFFF

That all agrees with the official spec of the device (being only a 256kb flash). However if might be the case that other individual chip samples have in fact a bad flash in the first half of the region instead. Then in that case the program code should be moved over to the 2nd region / offset to become the "good area".

Just we did not observe this in this device here. And it is also it's possible that a fully matured silicon fab process will end up having 0 flash errors. That would be the case if the chips are being artificially binned down. To meed market segmentation / product differentiation criteria. Depending on that fact we recommend to read the full 512kb flash area. And then manually double check which half has the firmware code.

Openocd command to read the 1st half (256kb) region of flash only:

flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.first.256k.dump.bin 0 262144

Openocd command to read the 2nd half (256kb) region of flash only:

flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.last.256k.dump.bin 262144 262144

Openocd command to read the entire flash region fully. Just remove last 2 arguments for bytes offset and bytes length:

flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.last.256k.dump.bin

Other tools

  • For GDB server, that isn't covered here. But normally is setup in vscode IDE, under PlatformIO extension project environment. So then requires some custom target configruations within vscode / platformio such as platformio.ini file. etc. Then to run the vscode IDE integrated debugger.
  • Another method of program static analysis is to use a decompiler / dissassembler such as Ghidra.
  • Binwalk did not seem work here. But is another popular method for examining firmware binaries.
  • Other tutorial for STM32 firmware https://medium.com/techmaker/reverse-engineering-stm32-firmware-578d53e79b3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment