ringbuffer: Make ring buffer access irq-save
We have to temporarily disable nterrupts when performing rinbuffer
operations, as the ring buffer is used both from IRQ as well as process
context.
diff --git a/firmware/src_simtrace/ringbuffer.c b/firmware/src_simtrace/ringbuffer.c
index 1669fdc..71fe4ed 100644
--- a/firmware/src_simtrace/ringbuffer.c
+++ b/firmware/src_simtrace/ringbuffer.c
@@ -1,16 +1,27 @@
#include "ringbuffer.h"
#include "trace.h"
+#include "utils.h"
void rbuf_reset(volatile ringbuf * rb)
{
+ unsigned long state;
+
+ local_irq_save(state);
rb->ird = 0;
rb->iwr = 0;
+ local_irq_restore(state);
}
uint8_t rbuf_read(volatile ringbuf * rb)
{
- uint8_t val = rb->buf[rb->ird];
+ unsigned long state;
+ uint8_t val;
+
+ local_irq_save(state);
+ val = rb->buf[rb->ird];
rb->ird = (rb->ird + 1) % RING_BUFLEN;
+ local_irq_restore(state);
+
return val;
}
@@ -19,22 +30,41 @@
return rb->buf[rb->ird];
}
-void rbuf_write(volatile volatile ringbuf * rb, uint8_t item)
-{
- if (!rbuf_is_full(rb)) {
- rb->buf[rb->iwr] = item;
- rb->iwr = (rb->iwr + 1) % RING_BUFLEN;
- } else {
- TRACE_ERROR("Ringbuffer full, losing bytes!");
- }
-}
-
bool rbuf_is_empty(volatile ringbuf * rb)
{
return rb->ird == rb->iwr;
}
-bool rbuf_is_full(volatile ringbuf * rb)
+static bool __rbuf_is_full(volatile ringbuf * rb)
{
return rb->ird == (rb->iwr + 1) % RING_BUFLEN;
}
+
+bool rbuf_is_full(volatile ringbuf * rb)
+{
+ unsigned long state;
+ bool rc;
+
+ local_irq_save(state);
+ rc = rb->ird == (rb->iwr + 1) % RING_BUFLEN;
+ local_irq_restore(state);
+
+ return rc;
+}
+
+void rbuf_write(volatile volatile ringbuf * rb, uint8_t item)
+{
+ unsigned long state;
+
+ local_irq_save(state);
+ if (!__rbuf_is_full(rb)) {
+ rb->buf[rb->iwr] = item;
+ rb->iwr = (rb->iwr + 1) % RING_BUFLEN;
+ local_irq_restore(state);
+ } else {
+ local_irq_restore(state);
+ TRACE_ERROR("Ringbuffer full, losing bytes!");
+ }
+}
+
+