RioSerialLink: type-aware resolution closes the straggler-reply hole
Bench round 3 (testlogs/riomash-patched-62500-sw): lamp glitches persisted because reply-resolution was type-blind — an analog reply still crossing USB from the previous poll could falsely confirm the NEXT command (usually a lamp write) before the board judged it. Now a reply resolves only its MATCHING pending request (analog/version/ check); ACK/NAK stay type-blind, which is safe because the board's TX ISR prioritizes ACK/NAK ahead of reply data, so a command's ACK cannot trail into its successor's window. Budget-exhausted drops settle 10ms before releasing the gate so late stragglers land on an empty pending. New test: a stray AnalogReply must not resolve a pending lamp command. 283 green; selftest regression unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -276,6 +276,33 @@ public class RioSerialLinkTests
|
||||
await run;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AnalogReply_DoesNotResolve_PendingLampCommand()
|
||||
{
|
||||
var fake = new FakeTransport();
|
||||
var link = new RioSerialLink(fake, StopAndWait(limit: 1, timeoutMs: 250));
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
Task run = link.RunAsync(cts.Token);
|
||||
|
||||
// Lamp command in flight; a straggler analog reply (from an earlier
|
||||
// poll) arrives. It must NOT confirm the lamp — the lamp keeps waiting
|
||||
// and is resolved only by its own ACK.
|
||||
Task send = link.SendAsync(PacketBuilder.LampRequest(0x05, 0x02));
|
||||
await fake.NextWriteAsync();
|
||||
fake.Enqueue(PacketBuilder.Build(RioCommand.AnalogReply, new byte[10]));
|
||||
|
||||
await Task.Delay(100);
|
||||
Assert.False(send.IsCompleted, "stray analog reply must not resolve a lamp command");
|
||||
|
||||
fake.Enqueue((byte)RioControl.Ack);
|
||||
await send.WaitAsync(Timeout);
|
||||
Assert.Equal(0, link.Retransmits);
|
||||
|
||||
cts.Cancel();
|
||||
await run;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UnsolicitedNak_WithNothingPending_IsIgnored()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user