Improved buffer management

Buffers should not be overwritten while they could potentially be read
This commit is contained in:
Sebastian 2016-11-29 19:18:42 +01:00
parent c7dc7763a8
commit f9b5e78556
3 changed files with 20 additions and 16 deletions

View File

@ -81,7 +81,7 @@ Initial value: 0x0
the frame is considered timed out and all received data can be dropped. the frame is considered timed out and all received data can be dropped.
- Incoming messages are stored in a fifo until the application retrieves them. - Incoming messages are stored in a fifo until the application retrieves them.
- The receive fifo has a size of at least 2 messages. - The receive fifo has a size of at least 2 messages.
- If the fifo is full new messages will override the older ones. - If the fifo is full all new messages will be dropped until messages are retrieved from the fifo.
It is up to the application to retrieve message in time. It is up to the application to retrieve message in time.
- Even if sending was successful, there is still a chance that the receiver could not - Even if sending was successful, there is still a chance that the receiver could not
receive the frame due to missing buffer space or not enough processing time to react. receive the frame due to missing buffer space or not enough processing time to react.

View File

@ -4,9 +4,9 @@
volatile enum sss7State sss7_state; volatile enum sss7State sss7_state;
uint8_t sss7_rx_buffer[SSS7_RX_BUFFER_COUNT][SSS7_PAYLOAD_SIZE]; uint8_t sss7_rx_buffer[SSS7_RX_BUFFER_SIZE][SSS7_PAYLOAD_SIZE];
uint8_t sss7_rx_active_buffer; uint8_t sss7_rx_buffer_write;
uint8_t sss7_rx_oldest_buffer; uint8_t sss7_rx_buffer_read;
uint8_t sss7_rx_pos; uint8_t sss7_rx_pos;
uint8_t sss7_tx_buffer[SSS7_PAYLOAD_SIZE]; uint8_t sss7_tx_buffer[SSS7_PAYLOAD_SIZE];
@ -23,8 +23,8 @@ void sss7_init(void) {
sss7_state = SSS7_IDLE; sss7_state = SSS7_IDLE;
sss7_rx_pos = 0; sss7_rx_pos = 0;
sss7_rx_oldest_buffer = 0; sss7_rx_buffer_read = 0;
sss7_rx_active_buffer = 0; sss7_rx_buffer_write = 0;
sss7_tx_pos = 0; sss7_tx_pos = 0;
sss7_tx_crc = 0; sss7_tx_crc = 0;
@ -82,6 +82,7 @@ void sss7_send(uint8_t msg[SSS7_PAYLOAD_SIZE]) {
void sss7_process_rx(void) { void sss7_process_rx(void) {
uint8_t byte = uart_get_byte(); uint8_t byte = uart_get_byte();
uint8_t crc = 0; uint8_t crc = 0;
uint8_t next_buffer_write = 0;
sss7_timeout_counter = 0; sss7_timeout_counter = 0;
switch(sss7_state) { switch(sss7_state) {
@ -105,7 +106,7 @@ void sss7_process_rx(void) {
break; break;
case SSS7_RX_PAYLOAD: case SSS7_RX_PAYLOAD:
sss7_rx_buffer[sss7_rx_active_buffer][sss7_rx_pos] = byte; sss7_rx_buffer[sss7_rx_buffer_write][sss7_rx_pos] = byte;
sss7_rx_pos++; sss7_rx_pos++;
if(sss7_rx_pos >= SSS7_PAYLOAD_SIZE) { if(sss7_rx_pos >= SSS7_PAYLOAD_SIZE) {
sss7_state = SSS7_RX_CRC; sss7_state = SSS7_RX_CRC;
@ -113,9 +114,12 @@ void sss7_process_rx(void) {
break; break;
case SSS7_RX_CRC: case SSS7_RX_CRC:
crc = sss7_payload_crc(sss7_rx_buffer[sss7_rx_active_buffer]); crc = sss7_payload_crc(sss7_rx_buffer[sss7_rx_buffer_write]);
if(byte == crc) {
sss7_rx_active_buffer = (sss7_rx_active_buffer + 1) % SSS7_RX_BUFFER_COUNT; next_buffer_write = (sss7_rx_buffer_write + 1) % SSS7_RX_BUFFER_SIZE;
// Ensure CRC is okay and we don't overwrite other frames
if(byte == crc && next_buffer_write != sss7_rx_buffer_read) {
sss7_rx_buffer_write = next_buffer_write;
} }
sss7_state = SSS7_IDLE; sss7_state = SSS7_IDLE;
break; break;
@ -189,7 +193,7 @@ void sss7_process_ticks(uint16_t ticks) {
void sss7_get_received(uint8_t msg[SSS7_PAYLOAD_SIZE]) { void sss7_get_received(uint8_t msg[SSS7_PAYLOAD_SIZE]) {
if(sss7_has_received()) { if(sss7_has_received()) {
memcpy(msg, sss7_rx_buffer[sss7_rx_oldest_buffer], SSS7_PAYLOAD_SIZE); memcpy(msg, sss7_rx_buffer[sss7_rx_buffer_read], SSS7_PAYLOAD_SIZE);
sss7_rx_oldest_buffer = (sss7_rx_oldest_buffer + 1) % SSS7_RX_BUFFER_COUNT; sss7_rx_buffer_read = (sss7_rx_buffer_read + 1) % SSS7_RX_BUFFER_SIZE;
}; };
} }

View File

@ -24,13 +24,13 @@ const static uint16_t sss7_timeout = 50;
const static uint16_t sss7_timeout_increment = 1; const static uint16_t sss7_timeout_increment = 1;
#define SSS7_PAYLOAD_SIZE 16 #define SSS7_PAYLOAD_SIZE 16
#define SSS7_RX_BUFFER_COUNT 2 #define SSS7_RX_BUFFER_SIZE 2
extern volatile enum sss7State sss7_state; extern volatile enum sss7State sss7_state;
extern volatile uint8_t sss7_tx_failed; extern volatile uint8_t sss7_tx_failed;
extern uint8_t sss7_rx_active_buffer; extern uint8_t sss7_rx_buffer_write;
extern uint8_t sss7_rx_oldest_buffer; extern uint8_t sss7_rx_buffer_read;
void sss7_process_rx(void); void sss7_process_rx(void);
void sss7_process_tx(void); void sss7_process_tx(void);
@ -53,7 +53,7 @@ static inline uint8_t sss7_send_failed(void) {
} }
static inline uint8_t sss7_has_received(void) { static inline uint8_t sss7_has_received(void) {
return sss7_rx_oldest_buffer != sss7_rx_active_buffer; return sss7_rx_buffer_read != sss7_rx_buffer_write;
} }
void sss7_get_received(uint8_t msg[SSS7_PAYLOAD_SIZE]); void sss7_get_received(uint8_t msg[SSS7_PAYLOAD_SIZE]);