mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
So far, we use a uint8_t ring buffer as "FIFO" between USART Rx interrupt and main context. That's fine for expressing the bytes we receive. However, if we also want to report USART errors synchronously in that stream, we actually need more bits to express those. Reporting USART errors via the ring buffer is the only way how the sniffer code can know in which TPDU the error occurred. Reporting them any other way (global variable, ...) would loose the timing relationship where in the received stream the error occurred. This change just changes the ringbuffer from 1024-entry 8bit to 512-entry 16bit and doesn't add any error reporting. Change-Id: Ifde054fbfe7f753b61e7d3409c56eca6e0faeb4b
152 lines
3.0 KiB
C
152 lines
3.0 KiB
C
/* Ring buffer
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
#include "ringbuffer.h"
|
|
#include "trace.h"
|
|
#include "utils.h"
|
|
|
|
/* WARNING: 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;
|
|
|
|
local_irq_save(state);
|
|
rb->ird = 0;
|
|
rb->iwr = 0;
|
|
local_irq_restore(state);
|
|
}
|
|
|
|
void rbuf16_reset(volatile ringbuf16 * 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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
uint16_t rbuf16_read(volatile ringbuf16 * rb)
|
|
{
|
|
unsigned long state;
|
|
uint16_t val;
|
|
|
|
local_irq_save(state);
|
|
val = rb->buf[rb->ird];
|
|
rb->ird = (rb->ird + 1) % RING16_BUFLEN;
|
|
local_irq_restore(state);
|
|
|
|
return val;
|
|
}
|
|
|
|
uint8_t rbuf_peek(volatile ringbuf * rb)
|
|
{
|
|
return rb->buf[rb->ird];
|
|
}
|
|
|
|
uint16_t rbuf16_peek(volatile ringbuf16 * rb)
|
|
{
|
|
return rb->buf[rb->ird];
|
|
}
|
|
|
|
bool rbuf_is_empty(volatile ringbuf * rb)
|
|
{
|
|
return rb->ird == rb->iwr;
|
|
}
|
|
|
|
bool rbuf16_is_empty(volatile ringbuf16 * rb)
|
|
{
|
|
return rb->ird == rb->iwr;
|
|
}
|
|
|
|
static bool __rbuf_is_full(volatile ringbuf * rb)
|
|
{
|
|
return rb->ird == (rb->iwr + 1) % RING_BUFLEN;
|
|
}
|
|
|
|
static bool __rbuf16_is_full(volatile ringbuf16 * rb)
|
|
{
|
|
return rb->ird == (rb->iwr + 1) % RING16_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;
|
|
}
|
|
|
|
bool rbuf16_is_full(volatile ringbuf16 * rb)
|
|
{
|
|
unsigned long state;
|
|
bool rc;
|
|
|
|
local_irq_save(state);
|
|
rc = rb->ird == (rb->iwr + 1) % RING16_BUFLEN;
|
|
local_irq_restore(state);
|
|
|
|
return rc;
|
|
}
|
|
|
|
int rbuf_write(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);
|
|
return 0;
|
|
} else {
|
|
local_irq_restore(state);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int rbuf16_write(volatile ringbuf16 * rb, uint16_t item)
|
|
{
|
|
unsigned long state;
|
|
|
|
local_irq_save(state);
|
|
if (!__rbuf16_is_full(rb)) {
|
|
rb->buf[rb->iwr] = item;
|
|
rb->iwr = (rb->iwr + 1) % RING16_BUFLEN;
|
|
local_irq_restore(state);
|
|
return 0;
|
|
} else {
|
|
local_irq_restore(state);
|
|
return -1;
|
|
}
|
|
}
|