Starting Point
This commit is contained in:
89
include/lib/ringbuffer.h
Normal file
89
include/lib/ringbuffer.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef RINGBUFFER_H_
|
||||
#define RINGBUFFER_H_
|
||||
|
||||
/**
|
||||
* \brief Ringbuffer Datenstruktur
|
||||
* \file ringbuffer.h
|
||||
*
|
||||
* Diese Datei ist eine Hilfestellung für Aufgabe 2.
|
||||
* Sie erspart euch den Aufwand, selber einen Ringbuffer zu implementieren.
|
||||
*/
|
||||
|
||||
struct ring_buff {
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
unsigned int size;
|
||||
unsigned int mask;
|
||||
char *buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Überprüft ob eine positive Zahl eine Zweierpotenz ist
|
||||
*
|
||||
* Beispiel: (0b100 & 0b011) == 0b000.
|
||||
*/
|
||||
#define is_power_of_two(val) (((val) & ((val) - 1)) == 0)
|
||||
|
||||
/**
|
||||
* \brief Macro um einen Ringbuffer zu erstellen
|
||||
* \param name Bezeichnung des Buffers
|
||||
* \param size Größe des Buffers
|
||||
*
|
||||
*/
|
||||
#define create_ringbuffer(name, size) \
|
||||
static_assert((size) >= 1, "Size of Ringbuffer has to be at least 1"); \
|
||||
static_assert(is_power_of_two(size), "Size of Ringbuffer has to be a power of 2"); \
|
||||
static char _b_##name[size]; \
|
||||
static struct ring_buff _##name = { 0, 0, (size), (size) - 1, _b_##name }; \
|
||||
static volatile struct ring_buff *name = &_##name
|
||||
|
||||
[[nodiscard]] static bool buff_is_empty(volatile struct ring_buff *b)
|
||||
{
|
||||
return b->head == b->tail;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool buff_is_full(volatile struct ring_buff *b)
|
||||
{
|
||||
return ((b->tail & b->mask) == (b->head & b->mask)) && !buff_is_empty(b);
|
||||
}
|
||||
|
||||
static bool buff_putc(volatile struct ring_buff *b, char c)
|
||||
{
|
||||
if (buff_is_full(b)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
b->buffer[b->head & b->mask] = c;
|
||||
b->head++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static char buff_getc(volatile struct ring_buff *b)
|
||||
{
|
||||
while (buff_is_empty(b)) {
|
||||
}
|
||||
|
||||
char c = b->buffer[b->tail & b->mask];
|
||||
b->tail++;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
[[nodiscard, maybe_unused]] static char buff_peekc(volatile struct ring_buff *b)
|
||||
{
|
||||
while (buff_is_empty(b)) {
|
||||
}
|
||||
|
||||
return b->buffer[b->tail & b->mask];
|
||||
}
|
||||
|
||||
[[nodiscard, maybe_unused]] static char buff_peekc_last(volatile struct ring_buff *b)
|
||||
{
|
||||
while (buff_is_empty(b)) {
|
||||
}
|
||||
|
||||
return b->buffer[(b->head - 1) & b->mask];
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user