# End-to-end dual-J-Link programming and source-debug proof

Status: complete
Type: evidence
Date: 2026-07-20

Parent: work/wp/completed/wp-headless-rpi-firmware-development-environment.md
Canonical Truth: E:/dev/high_point/7520553_SMI_FW/docs/headless-development-environment.md

## Result

The generic `srv-rpi00` connector is proven end to end with both directly
connected probes. Windows supplied the firmware image, MCU settings, SEGGER
client, ELF symbols, source tree, and GDB. The Pi supplied only a serial-bound
J-Link Remote Server endpoint through an authenticated SSH tunnel.

| Controller | Hub endpoint | J-Link serial | Hardware variant | Program/verify | Source debug |
| --- | --- | --- | --- | --- | --- |
| A / Setup A | `19120` | `69664082` | `0` | pass | pass |
| B / Setup B | `19121` | `69660123` | `1` | pass | pass |

Both CPUs were independently confirmed running after the final detach. Both
serial-bound Pi services and the firewall service remained active. No test SSH
tunnel, Commander, or GDB-server process was left running.

## Approved artifact

- Image: `Debug/7520553_SMI_FW.srec`
- SHA-256: `8A3B43AF3BC35922655DB5216F4ED7C93AA829E03ACC2FEC65961B9232CDAA80`
- Symbols: `Debug/7520553_SMI_FW.elf`
- Target: `R7FS7G27H`, SWD, 4000 kHz
- Windows SEGGER client: V9.58
- Windows GDB: GNU Arm Embedded 10.3-2021.10

## Programming proof

An initial B attempt exposed a launcher defect: Commander reached the endpoint
before the SSH tunnel was ready, failed `loadfile`, then accepted later reset/go
commands and returned zero. No image was downloaded by that attempt. The
launcher was hardened to wait for the actual local listening socket, issue an
explicit target `connect`, capture output, reject failure text, and require a
`Downloading file ... O.K.` success sequence.

With the corrected launcher, B and then A each reported:

- 131,072 code-flash bytes processed in three ranges;
- Program & Verify completed with `O.K.`;
- data-flash bank 0 at `0x40120040` already matched and was skipped; and
- reset/go completed after verification.

Commit `f438692f83d1c611874424de137f69d2e570d585` contains the hardened
program and debug startup behavior. Commit
`9600ade4a17c95e000486666e9f6ac8dd2f3bef3` makes the proven source-prefix
mapping part of the normal debug launcher and records qualification in the
canonical operating guide. The two incremental bundle SHA-256 values are
`1E75FB6CD3D0F43FC2848C9801BD301C209671102A2203426A06A5CAE441867D` and
`B10C2AF64126B1C8D766FA037AA893FAE55E680019EC2DFA3AB387C01BB5801A`.
The Windows and Pi checkouts were synchronized to `9600ade4`.

## Source-level debug proof

For each endpoint, Windows `JLinkGDBServerCL.exe` connected through the SSH
forward with `-noreset -nohalt`, and Windows Arm GDB opened the Debug ELF.
GDB remapped the build staging prefix to the live checkout at
`E:/dev/high_point/7520553_SMI_FW`, displayed local source lines 1283-1292,
and installed a hardware breakpoint at `Thread_Com485_entry.c:1291`.

Both controllers stopped at:

```text
Breakpoint 1, Thread_Com485_entry () at ../src/Thread_Com485_entry.c:1291
1291            tx_thread_sleep(1);
```

The symbolized backtrace included `Thread_Com485_entry`,
`Thread_Com485_func`, and `_tx_thread_shell_entry`. GDB reported PC
`0x574d0`, single-stepped to `0x574d2`, removed the breakpoint, detached, and
returned zero for both probes.

SEGGER logged a transport error while closing each `-singlerun` session after
`Starting target CPU...`. Immediate independent Commander sessions resolved
the correct serials and reported `CPU is not halted` on both controllers, so
the message is a remote-server disconnect cleanup quirk rather than a halted
or failed target.

## Service 474 and final state

The owner stopped service 474 on A before the A debug operation. B was already
stopped. Final live and persisted reads show state `3` (Stopped) on both:

- A: run `86275`, elapsed `5513`, records `5432`, reset count `6`, all dropped,
  mirror, I/O, and failure counters zero.
- B: run `35709`, elapsed/records `5240`, reset count `0`, all dropped, mirror,
  I/O, and failure counters zero.

The final reads matched their pre-debug persisted records. Programming and
debugging did not restart service 474 or cross-select the other controller.

## Final operational checks

- `jlink-remote@jlink-69664082.service`: active
- `jlink-remote@jlink-69660123.service`: active
- `jlink-hub-firewall.service`: active
- Pi listeners: 19120 and 19121 present
- Controller A: serial `69664082`, hardware variant `0`, CPU running
- Controller B: serial `69660123`, hardware variant `1`, CPU running
- Windows worktree: clean at `9600ade4`
- Pi mirror: clean at `9600ade4`

This closes the programming and source-debug acceptance gate. The connector is
ready for normal repository-specific Windows workflows; future firmware repos
need only their own Windows target/artifact configuration.
