Skip to content

fix: escape SF32LB52 debug markers during flash writes - #56

Open
i4nf0x wants to merge 2 commits into
OpenSiFli:masterfrom
i4nf0x:fix/sf32lb52-safe-flash-transport
Open

fix: escape SF32LB52 debug markers during flash writes#56
i4nf0x wants to merge 2 commits into
OpenSiFli:masterfrom
i4nf0x:fix/sf32lb52-safe-flash-transport

Conversation

@i4nf0x

@i4nf0x i4nf0x commented Aug 12, 2026

Copy link
Copy Markdown

Summary

Related to #55.

This adds an automatic collision-safe flash transport for SF32LB52 firmware containing byte sequences recognized by the chip’s Debug IP:

  • 7e 79 — framed Debug IP request marker
  • 40 72MEMRead
  • 40 77MEMWrite

SF32LB52 Debug IP shares USART1 with the RAM flashing stub. Sending these sequences verbatim as firmware data can activate Debug IP operations and prevent the stub from completing its receive operation.

Implementation

For each affected file, sftool now:

  1. Scans the complete file for hazardous markers, including markers crossing an internal read-buffer boundary.

  2. Uses the normal bulk-write protocol, but substitutes 0xff for the second byte of each hazardous marker.

  3. Restores each substituted byte individually through the existing ASCII-hex stub command:

    burn_write_muti_bytes 1 <address> <hex-byte>
    
  4. Performs verification normally when requested.

Using 0xff as the temporary value is appropriate for NOR flash because it is the erased state. The subsequent single-byte operation only clears the required bits.

The safe path is selected automatically only for affected SF32LB52 files. Files without hazardous markers continue using the existing write path.

Both incremental and erase-all write paths are covered by the implementation.

Why all three markers are escaped

An initial implementation escaped only 7e 79. Hardware testing showed that this was insufficient.

sftool intentionally enables Debug IP while connecting, so a later raw 40 72 sequence could still be interpreted as MEMRead. With only 7e 79 escaped, the canonical reproducer continued to time out during its second write.

Escaping 7e 79, 40 72, and 40 77 prevented both the accidental framed request and subsequent memory-operation payloads from appearing on the raw USART1 stream.

Why the complete file is not sent as ASCII hex

I also tested writing the entire affected file with burn_write_muti_bytes.

That approach was not reliable with the current compiled SF32LB52 stub. Hardware readback showed that some data around 4 KiB boundaries remained erased even though every command returned OK.

The hybrid approach avoids that behavior:

  • normal bulk transfer for almost all data;
  • one-byte ASCII-hex writes only for withheld hazardous bytes.

It is also substantially more efficient than encoding the complete image as ASCII hex.

Hardware validation

Tested on SF32LB52 with NOR flash using the minimized reproducer from #55.

The patched tool performed:

  • a collision-safe 16 KiB predecessor write;
  • restoration of 0x79 at 0x12088af1;
  • a collision-safe 13,169-byte target write;
  • restoration of 0x72 at 0x1208f36a.

Both bulk writes completed without timing out.

Both regions were then read back and compared byte-for-byte with their source files. The comparisons passed, and the SHA-256 hashes matched:

b347e0afb8b07770dc3a301bd36781164cdf2a66bbabc7b824cc6ded01fd0828  predecessor
a88329e1e615c04c2f2df9fe5900215b331e30c05e800ca3e039b14752d944dd  target

The same reproducer times out with the unmodified raw transport.

Automated validation

The following checks pass:

cargo test --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo build --release --workspace
git diff --check

Tests cover:

  • detection of all three hazardous markers;
  • markers crossing scan-buffer boundaries;
  • preservation of the input file position;
  • substitution across transfer-chunk boundaries;
  • correct patch addresses and byte values;
  • use of the raw bulk path followed by one-byte ASCII-hex patches.

Scope and limitations

The SF32LB52 NOR incremental path has been validated end-to-end on hardware.

The equivalent erase-all path is implemented and covered by unit tests but has not yet been hardware-tested. Other memory types have not been tested.

This is a practical workaround for the existing compiled stub. A versioned, encoded bulk-transfer protocol implemented by both the host and stub would remain the more comprehensive long-term solution.

@CLAassistant

CLAassistant commented Aug 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@i4nf0x

i4nf0x commented Aug 13, 2026

Copy link
Copy Markdown
Author

I just re-wrote the commits under my primary identity so that license/cla check passes.

@HalfSweet

Copy link
Copy Markdown
Collaborator

This might not be the most elegant solution—I think we should escape the binary stream data in the payload that’s identical to the UART debug data—but that might require modifying the stub’s firmware…
Anyway, I’ve already left the company, so this is just a suggestion. I’ll let the person in charge of maintaining this part know

@i4nf0x

i4nf0x commented Aug 14, 2026

Copy link
Copy Markdown
Author

This might not be the most elegant solution—I think we should escape the binary stream data in the payload that’s identical to the UART debug data—but that might require modifying the stub’s firmware…

I agree, my solution is not elegant and shouldn't become a permanent fix. However, this issue is serious enough to become a blocker for someone's development (that's what happened to my team). So I believe my solution is an acceptable hot fix - it only affects flashing of binaries that would otherwise fail to flash.

A robust solution requires a substantial change in the transfer protocol itself, which might take time. This should be planned as a follow-up issue. I suggested some possible approaches in the original issue. But sadly, I couldn't find the sources for the stub, so I didn't attempt to implement a more proper solution myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants