From 75f870994722cf2340d8bc39c0600ca592dadc7a Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 24 May 2018 13:30:24 -0400 Subject: [PATCH] command: Wait to send ack until after processing commands Send the ack after processing commands - this gives the host code more information on serial buffer utilization. Signed-off-by: Kevin O'Connor --- klippy/chelper/serialqueue.c | 14 +++++++++----- src/command.c | 12 ++++++++++-- src/command.h | 1 + src/generic/serial_irq.c | 5 ++++- src/pru/pru0.c | 4 +++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/klippy/chelper/serialqueue.c b/klippy/chelper/serialqueue.c index ab55d176..06ee0ee0 100644 --- a/klippy/chelper/serialqueue.c +++ b/klippy/chelper/serialqueue.c @@ -363,7 +363,7 @@ struct serialqueue { double last_receive_sent_time; // Retransmit support uint64_t send_seq, receive_seq; - uint64_t ignore_nak_seq, retransmit_seq, rtt_sample_seq; + uint64_t ignore_nak_seq, last_ack_seq, retransmit_seq, rtt_sample_seq; struct list_head sent_queue; double srtt, rttvar, rto; // Pending transmission message queues @@ -509,10 +509,14 @@ handle_message(struct serialqueue *sq, double eventtime, int len) if (rseq != sq->receive_seq) // New sequence number update_receive_seq(sq, eventtime, rseq); - else if (len == MESSAGE_MIN && rseq > sq->ignore_nak_seq - && !list_empty(&sq->sent_queue)) - // Duplicate sequence number in an empty message is a nak - pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW); + if (len == MESSAGE_MIN) { + // Ack/nak message + if (sq->last_ack_seq < rseq) + sq->last_ack_seq = rseq; + else if (rseq > sq->ignore_nak_seq && !list_empty(&sq->sent_queue)) + // Duplicate Ack is a Nak - do fast retransmit + pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW); + } if (len > MESSAGE_MIN) { // Add message to receive queue diff --git a/src/command.c b/src/command.c index 2df70d85..b0c7f882 100644 --- a/src/command.c +++ b/src/command.c @@ -257,7 +257,6 @@ command_find_block(uint8_t *buf, uint_fast8_t buf_len, uint_fast8_t *pop_count) goto nak; } next_sequence = ((msgseq + 1) & MESSAGE_SEQ_MASK) | MESSAGE_DEST; - command_sendf(&encode_acknak); return 1; need_more_data: @@ -308,13 +307,22 @@ command_dispatch(uint8_t *buf, uint_fast8_t msglen) } } +// Send an ack message to the host (notifying that it can send more data) +void +command_send_ack(void) +{ + command_sendf(&encode_acknak); +} + // Find a message block and then dispatch all the commands in it int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len , uint_fast8_t *pop_count) { int_fast8_t ret = command_find_block(buf, buf_len, pop_count); - if (ret > 0) + if (ret > 0) { command_dispatch(buf, *pop_count); + command_send_ack(); + } return ret; } diff --git a/src/command.h b/src/command.h index 035d3929..92315f38 100644 --- a/src/command.h +++ b/src/command.h @@ -72,6 +72,7 @@ void command_sendf(const struct command_encoder *ce, ...); int_fast8_t command_find_block(uint8_t *buf, uint_fast8_t buf_len , uint_fast8_t *pop_count); void command_dispatch(uint8_t *buf, uint_fast8_t msglen); +void command_send_ack(void); int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len , uint_fast8_t *pop_count); diff --git a/src/generic/serial_irq.c b/src/generic/serial_irq.c index 6b682a0f..a035364b 100644 --- a/src/generic/serial_irq.c +++ b/src/generic/serial_irq.c @@ -75,8 +75,11 @@ console_task(void) int_fast8_t ret = command_find_block(receive_buf, rpos, &pop_count); if (ret > 0) command_dispatch(receive_buf, pop_count); - if (ret) + if (ret) { console_pop_input(pop_count); + if (ret > 0) + command_send_ack(); + } } DECL_TASK(console_task); diff --git a/src/pru/pru0.c b/src/pru/pru0.c index 2a136e9e..4b60af27 100644 --- a/src/pru/pru0.c +++ b/src/pru/pru0.c @@ -148,8 +148,10 @@ check_can_read(void) int_fast8_t ret = command_find_block(p, msglen, &pop_count); if (!ret) break; - if (ret > 0) + if (ret > 0) { do_dispatch(p, pop_count); + command_send_ack(); + } p += pop_count; len -= pop_count; }