From 05cc7f653137d7ddee7572eb946c8ee7f881cbff Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 4 Jul 2018 04:39:40 +0200 Subject: [PATCH] ringbuffer: Don't print/TRAC from ringbuffer In commit eac1bec4285a48b466e9fd09b0513b3c49d393b3 we start to use the ringbuffer inside the console printing code. As a result, we must not use TRACE_*() or printf() from within ringbuffer.c code to avoid infinite recursion. Instead, let rbuf_write() return a negative return value in case the ring buffer overflows. This way, the callers (outside the console/stdout code) can print an error message themselves. Change-Id: Ib009f013be119dbad22fa2b7d60ec8dee59baee5 --- firmware/libcommon/include/ringbuffer.h | 2 +- firmware/libcommon/source/mode_cardemu.c | 3 ++- firmware/libcommon/source/ringbuffer.c | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/firmware/libcommon/include/ringbuffer.h b/firmware/libcommon/include/ringbuffer.h index 1d297604..efc557cb 100644 --- a/firmware/libcommon/include/ringbuffer.h +++ b/firmware/libcommon/include/ringbuffer.h @@ -16,7 +16,7 @@ typedef struct ringbuf { void rbuf_reset(volatile ringbuf * rb); uint8_t rbuf_read(volatile ringbuf * rb); uint8_t rbuf_peek(volatile ringbuf * rb); -void rbuf_write(volatile ringbuf * rb, uint8_t item); +int rbuf_write(volatile ringbuf * rb, uint8_t item); bool rbuf_is_empty(volatile ringbuf * rb); bool rbuf_is_full(volatile ringbuf * rb); diff --git a/firmware/libcommon/source/mode_cardemu.c b/firmware/libcommon/source/mode_cardemu.c index 7de67dfc..2d9af994 100644 --- a/firmware/libcommon/source/mode_cardemu.c +++ b/firmware/libcommon/source/mode_cardemu.c @@ -186,7 +186,8 @@ static void usart_irq_rx(uint8_t inst_num) if (csr & US_CSR_RXRDY) { byte = (usart->US_RHR) & 0xFF; - rbuf_write(&ci->rb, byte); + if (rbuf_write(&ci->rb, byte) < 0) + TRACE_ERROR("rbuf overrun\r\n"); } if (csr & US_CSR_TXRDY) { diff --git a/firmware/libcommon/source/ringbuffer.c b/firmware/libcommon/source/ringbuffer.c index 4d980d77..b8cd5c6c 100644 --- a/firmware/libcommon/source/ringbuffer.c +++ b/firmware/libcommon/source/ringbuffer.c @@ -2,6 +2,10 @@ #include "trace.h" #include "utils.h" +/* WARNINGI: Since console output is internally using this ringbuffer to implement + * buffered writes, we cannot use any TRACE_*() or printf() style functions here, + * as it would create infinite recursion! */ + void rbuf_reset(volatile ringbuf * rb) { unsigned long state; @@ -52,7 +56,7 @@ bool rbuf_is_full(volatile ringbuf * rb) return rc; } -void rbuf_write(volatile ringbuf * rb, uint8_t item) +int rbuf_write(volatile ringbuf * rb, uint8_t item) { unsigned long state; @@ -61,9 +65,10 @@ void rbuf_write(volatile ringbuf * rb, uint8_t item) rb->buf[rb->iwr] = item; rb->iwr = (rb->iwr + 1) % RING_BUFLEN; local_irq_restore(state); + return 0; } else { local_irq_restore(state); - TRACE_ERROR("Ringbuffer full, losing bytes!"); + return -1; } }