Skip to content

Commit 2482aa2

Browse files
widgetiiclaude
andauthored
Remove per-packet backpressure: streaming 3x faster (#35)
With COBS trailing zero bug fixed + D-cache enabled, per-packet ACK is no longer needed. Pure streaming at 921600 baud: Before (per-packet ACK): 16MB in 9 min (30 KB/s) After (streaming): 16MB in 3.5 min (77 KB/s) Selfupdate also switched to streaming mode. Verified: 16MB CRC32 match on hi3516ev300. Co-authored-by: Dmitry Ilyin <widgetii@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 49226c4 commit 2482aa2

2 files changed

Lines changed: 8 additions & 22 deletions

File tree

agent/main.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ static void handle_write(const uint8_t *data, uint32_t len) {
227227
uint32_t chunk = pkt_len - 2;
228228
for (uint32_t i = 0; i < chunk && received < size; i++)
229229
dest[received++] = pkt[2 + i];
230-
/* Backpressure: COBS-framed ACK after each DATA packet.
231-
* Host waits for this before sending next packet. */
232-
proto_send_ack(ACK_OK);
230+
/* No per-packet ACK — streaming mode. COBS CRC32 per packet
231+
* catches any corruption. D-cache makes processing fast
232+
* enough to keep up with 921600 baud. */
233233
} else if (cmd == 0) {
234234
uint8_t err[5];
235235
err[0] = ACK_FLASH_ERROR;
@@ -333,8 +333,6 @@ static void handle_flash_write(const uint8_t *data, uint32_t len) {
333333
uint32_t chunk = pkt_len - 2;
334334
for (uint32_t i = 0; i < chunk && received < size; i++)
335335
staging[received++] = pkt[2 + i];
336-
/* Backpressure ACK */
337-
proto_send_ack(ACK_OK);
338336
} else if (cmd == 0) {
339337
uint8_t err[5];
340338
err[0] = ACK_FLASH_ERROR;
@@ -540,8 +538,7 @@ static void handle_selfupdate(const uint8_t *data, uint32_t len) {
540538
uint32_t chunk = pkt_len - 2;
541539
for (uint32_t i = 0; i < chunk && received < size; i++)
542540
dest[received++] = pkt[2 + i];
543-
/* Backpressure ACK — host must wait before sending next */
544-
proto_send_ack(ACK_OK);
541+
/* Streaming mode — no per-packet ACK */
545542
} else if (cmd == 0) {
546543
proto_send_ack(ACK_FLASH_ERROR);
547544
return;

src/defib/agent/client.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,9 @@ async def _write_block(self, addr: int, data: bytes) -> bool:
323323
if cmd != RSP_ACK or resp[0] != ACK_OK:
324324
return False
325325

326-
# Send data packets with backpressure: agent sends a COBS-framed
327-
# ACK after each DATA packet. Host waits for it before sending
328-
# next. Guarantees zero data loss at any speed.
326+
# Stream all DATA packets without per-packet ACK.
327+
# With COBS bug fixed + D-cache, the agent processes fast
328+
# enough to keep up at 921600 baud.
329329
offset = 0
330330
seq = 0
331331
while offset < len(data):
@@ -335,11 +335,6 @@ async def _write_block(self, addr: int, data: bytes) -> bool:
335335
offset += chunk
336336
seq += 1
337337

338-
# Wait for per-packet ACK
339-
cmd, resp = await recv_response(self._transport, timeout=10.0)
340-
if cmd != RSP_ACK or resp[0] != ACK_OK:
341-
return False
342-
343338
# Final CRC verification ACK — may take seconds for large transfers
344339
crc_timeout = max(60.0, len(data) / 50000) # ~20µs/byte for CRC32
345340
cmd, resp = await recv_response(self._transport, timeout=crc_timeout)
@@ -603,7 +598,7 @@ async def selfupdate(
603598
if cmd != RSP_ACK or resp[0] != ACK_OK:
604599
return False
605600

606-
# Send data with per-packet backpressure
601+
# Stream all data packets
607602
offset = 0
608603
seq = 0
609604
while offset < len(firmware):
@@ -613,12 +608,6 @@ async def selfupdate(
613608
offset += chunk
614609
seq += 1
615610

616-
# Wait for per-packet ACK
617-
cmd, resp = await recv_response(self._transport, timeout=10.0)
618-
if cmd != RSP_ACK or resp[0] != ACK_OK:
619-
logger.error("Selfupdate packet %d failed: 0x%02x", seq, resp[0])
620-
return False
621-
622611
# Wait for CRC verification ACK (agent verifies before jumping)
623612
cmd, resp = await recv_response(self._transport, timeout=30.0)
624613
if cmd != RSP_ACK or resp[0] != ACK_OK:

0 commit comments

Comments
 (0)