RioSerialLink: NAK-driven retransmit of the last command packet
The board ACK/NAKs every inbound packet; we were fire-and-forget, so any corrupt arrival became a permanent state error (stuck-bright / missed lamps at 62500, where ~6.5% of 4-byte lamp commands lose bytes to RX-ISR overrun). Now a NAK control byte triggers a resend of the most recent command packet, bounded by NakRetransmitLimit (default 2; 0 restores fire-and-forget). Design notes: the wire has no sequence numbers, but every PC->RIO command is idempotent (lamp state, analog request, reset), so resending the latest command is safe even in the rare race where the NAK belonged to an earlier packet. Single control-byte replies (our ACKs) never participate. NakRetransmits counter surfaced in the mash summary. 6 new tests (retransmit, limit, budget reset, ACK no-op, control-byte exclusion, disable switch); 281 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -319,7 +319,7 @@ internal static class MashTest
|
||||
Raw($"firmware : {(version is null ? "(no reply)" : version.ToString())}");
|
||||
Raw($"presses/releases : {presses} / {releases} ({presses / mins:F0} presses/min)");
|
||||
Raw($"analog replies : {analogReplies} (~{expectedPolls} poll slots; {100.0 * analogReplies / Math.Max(1, expectedPolls):F1}%), sentinels {sentinels}");
|
||||
Raw($"framing / NAK : {framing} / {naks}");
|
||||
Raw($"framing / NAK : {framing} / {naks} (NAK-triggered resends: {link.NakRetransmits})");
|
||||
Raw("gap histogram : " + string.Join(" ", bucketNames.Select((n, i) => $"{n}:{buckets[i]}")));
|
||||
Raw("longest gaps : " + (longestGaps.Count == 0
|
||||
? "(none)"
|
||||
|
||||
Reference in New Issue
Block a user