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 <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2018-05-24 13:30:24 -04:00
parent 528f9f7604
commit 75f8709947
5 changed files with 27 additions and 9 deletions

View File

@ -363,7 +363,7 @@ struct serialqueue {
double last_receive_sent_time; double last_receive_sent_time;
// Retransmit support // Retransmit support
uint64_t send_seq, receive_seq; 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; struct list_head sent_queue;
double srtt, rttvar, rto; double srtt, rttvar, rto;
// Pending transmission message queues // Pending transmission message queues
@ -509,10 +509,14 @@ handle_message(struct serialqueue *sq, double eventtime, int len)
if (rseq != sq->receive_seq) if (rseq != sq->receive_seq)
// New sequence number // New sequence number
update_receive_seq(sq, eventtime, rseq); update_receive_seq(sq, eventtime, rseq);
else if (len == MESSAGE_MIN && rseq > sq->ignore_nak_seq if (len == MESSAGE_MIN) {
&& !list_empty(&sq->sent_queue)) // Ack/nak message
// Duplicate sequence number in an empty message is a nak 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); pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW);
}
if (len > MESSAGE_MIN) { if (len > MESSAGE_MIN) {
// Add message to receive queue // Add message to receive queue

View File

@ -257,7 +257,6 @@ command_find_block(uint8_t *buf, uint_fast8_t buf_len, uint_fast8_t *pop_count)
goto nak; goto nak;
} }
next_sequence = ((msgseq + 1) & MESSAGE_SEQ_MASK) | MESSAGE_DEST; next_sequence = ((msgseq + 1) & MESSAGE_SEQ_MASK) | MESSAGE_DEST;
command_sendf(&encode_acknak);
return 1; return 1;
need_more_data: 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 // Find a message block and then dispatch all the commands in it
int_fast8_t int_fast8_t
command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len
, uint_fast8_t *pop_count) , uint_fast8_t *pop_count)
{ {
int_fast8_t ret = command_find_block(buf, buf_len, 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_dispatch(buf, *pop_count);
command_send_ack();
}
return ret; return ret;
} }

View File

@ -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 int_fast8_t command_find_block(uint8_t *buf, uint_fast8_t buf_len
, uint_fast8_t *pop_count); , uint_fast8_t *pop_count);
void command_dispatch(uint8_t *buf, uint_fast8_t msglen); 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 int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len
, uint_fast8_t *pop_count); , uint_fast8_t *pop_count);

View File

@ -75,8 +75,11 @@ console_task(void)
int_fast8_t ret = command_find_block(receive_buf, rpos, &pop_count); int_fast8_t ret = command_find_block(receive_buf, rpos, &pop_count);
if (ret > 0) if (ret > 0)
command_dispatch(receive_buf, pop_count); command_dispatch(receive_buf, pop_count);
if (ret) if (ret) {
console_pop_input(pop_count); console_pop_input(pop_count);
if (ret > 0)
command_send_ack();
}
} }
DECL_TASK(console_task); DECL_TASK(console_task);

View File

@ -148,8 +148,10 @@ check_can_read(void)
int_fast8_t ret = command_find_block(p, msglen, &pop_count); int_fast8_t ret = command_find_block(p, msglen, &pop_count);
if (!ret) if (!ret)
break; break;
if (ret > 0) if (ret > 0) {
do_dispatch(p, pop_count); do_dispatch(p, pop_count);
command_send_ack();
}
p += pop_count; p += pop_count;
len -= pop_count; len -= pop_count;
} }