Skip to content

x3utils GUI v2.1.6-BETA

Pre-release
Pre-release

Choose a tag to compare

@ztakis ztakis released this 05 Sep 22:33
· 26 commits to main since this release

Fixes an intermittent flash corruption on the swdart backend that could leave
an MCU half-written.

The bug

Flashing an MCU with the Dart SWD backend failed roughly half the time with:

[flash] failed: verify FAILED at 0x080007A8: wrote 0x18, read 0x7d

A failed verify can leave the controller with a partly written image, which the
scooter reports as Controller Communication Error. Restoring the backup
brought it back.

Cause

The reset-before-flash used the ST-Link's nRST pin reset. A pin reset also
resets the debug block, wiping the "halt at the first instruction" arm — so the
controller firmware got to boot before the halt caught it, and started its ADC
DMA. DMA keeps running while the CPU is halted, so it overwrote part of every
8 KB block the flasher staged in RAM, and those samples were programmed into
flash instead of your firmware.

The fix

Three independent layers:

  1. Reset via SYSRESETREQ instead of the pin reset, so the core now stops
    before the firmware runs at all.
  2. All DMA channels are stopped after halting, in case the firmware did run.
  3. The staged block is read back and compared before every write, so any
    corruption is caught instead of silently programmed.

Scope

  • Affects the swdart (Dart SWD) backend on every platform. OpenOCD was
    never affected, and neither was the non-loader direct-write path.
  • The APK is swdart-only — there is no OpenOCD fallback on Android, so
    Android users had no unaffected path. Updating matters most there.
  • On Windows/Linux/macOS, OpenOCD is still the default backend; only users who
    switched to swdart were exposed.
  • Observed on the ZT3 MCU (AT32F415RBT7). The VCU was tested and was not
    corrupting — its DMA buffers sit outside the staging area — but the fix is
    generic and applies to both.

Verification

7 consecutive clean runs across Flash Only, SHU Compatible and Backup + Flash
on both MCU and VCU. Each fallback layer was then proven separately by
deliberately re-introducing the fault.

Note

Flashing is ~25% slower (about 4.3s → 5.4s for a full image). That is the
read-back check from layer 3, and it is deliberate.

If a flash ever fails to verify

x3utils shows a Recovery screen naming the backup it took before the
attempt, and blocks SHU Compatible until you've restored a known-good full
image with Flash Only. Follow it — don't re-run SHU Compatible against a chip
whose flash didn't verify.

Testing

Hardware verification was done on Windows with an ST-Link/V2. The SWD engine is
shared across all platforms, so Linux, macOS and Android get the same fix, but
they have not been separately re-tested against this bug.

2.1.4 and 2.1.5 BETA have been removed — both contain the flash corruption
fixed here. Use 2.1.6.