diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-07-04 04:39:40 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-07-04 04:42:22 +0200 |
commit | 05cc7f653137d7ddee7572eb946c8ee7f881cbff (patch) | |
tree | e160549a94b5cdd22789d33d415945d25418b342 /firmware/libcommon | |
parent | 46893451deebdeeea3f6dd11c77278eb60f35d5c (diff) |
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
Diffstat (limited to 'firmware/libcommon')
-rw-r--r-- | firmware/libcommon/include/ringbuffer.h | 2 | ||||
-rw-r--r-- | firmware/libcommon/source/mode_cardemu.c | 3 | ||||
-rw-r--r-- | 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 1d29760..efc557c 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 7de67df..2d9af99 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 4d980d7..b8cd5c6 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; } } |