Fix standalone mkII flows on OCDEN-unprogrammed targets - #118
Open
wexi wants to merge 3 commits into
Open
Conversation
…ures doSimpleJtagCommand() re-sent the command whenever the ICE answered RSP_FAILED, exhausting MAX_JTAG_COMM_ATTEMPS and converting the real response code into a generic "JTAG communication failed". A definitive answer means the link works; re-asking cannot change the ICE's mind. This surfaced on every programming-only flow (--read-fuses, --erase, --program) against a part with the OCDEN fuse unprogrammed: the mkII couples CMND_LEAVE_PROGMODE with re-attaching on-chip debugging and answers RSP_FAILED when it cannot, although all memory operations completed. Catch that case in disableProgramming() and release the target with CMND_RESET; bench-verified on an AT90CAN128, fuse reads now complete with the target left running. The faster failure path also reaches the destructor's CMND_SIGN_OFF, which ran outside any try block; guard it so a failing sign-off during exception unwinding cannot call std::terminate(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Mh2GBGBjSKBTr3Lrxo2fa
main() caught jtag_exception and exited 1 without a word, leaving only misleading secondary noise (a USB teardown message from the reader thread) as the visible symptom. Print e.what() so the primary failure is the one the user sees. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Mh2GBGBjSKBTr3Lrxo2fa
Normal shutdown closes the USB device from the main thread while the reader thread is blocked in usb_bulk_read(), which then fails with EBADF/ENODEV and printed "USB bulk read error" on every clean exit. Treat those codes as the shutdown signal they are. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Mh2GBGBjSKBTr3Lrxo2fa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Standalone programming-only flows (
--read-fuses,--erase,--program) against a JTAGICE mkII fail on any part whose OCDEN fuse is unprogrammed — the required state of every shipped product. The failure is confusing to diagnose because three separate defects stack:CMND_LEAVE_PROGMODEwith re-attaching on-chip debugging; with OCDEN unprogrammed that attach cannot succeed and the ICE answersRSP_FAILED, although every memory operation completed.doSimpleJtagCommand()treated that definitive refusal like a lost frame and re-sent the same command untilMAX_JTAG_COMM_ATTEMPS, converting the real response code into a generic "JTAG communication failed" exception. (Isolated on an AT90CAN128: identical command frames, only the stored OCDEN fuse value decides OK vs FAILED; lock bits ruled out.)main()caughtjtag_exceptionsilently, so the only visible symptom was secondary noise: the USB reader thread's "USB bulk read error: Bad file descriptor (-9)" when cleanup closed the device under it — and, timing-dependent, an fd_set fortify abort out of the same shutdown race.~jtag2()sentCMND_SIGN_OFFoutside any try block, so a failing sign-off during exception unwinding calledstd::terminate()(SIGABRT).The three commits address these bottom-up:
doSimpleJtagCommand()now throwsjtag_io_exceptionwith the real response code on a definitive failure answer instead of retrying;disableProgramming()catches the leave-progmode case and releases the target withCMND_RESET(flag 0x01), which the ICE accepts and which leaves the target running. The destructor's sign-off is guarded.main()reports the exception'swhat()before exiting.Bench result on the AT90CAN128 with OCDEN unprogrammed:
avarice --jtag usb --mkII --part at90can128 --read-fuseswent from always failing (silently, or with the abort) to printing all three fuse bytes and exiting 0, repeatably; with OCDEN programmed the behavior is unchanged.🤖 Generated with Claude Code
https://claude.ai/code/session_012Mh2GBGBjSKBTr3Lrxo2fa