Starting Point

This commit is contained in:
Hannes
2025-10-26 15:21:48 +01:00
parent 788ca8b1c0
commit 532c3fc295
21 changed files with 631 additions and 0 deletions

1
include/lib/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
# empty gitignore

110
include/lib/list.h Normal file
View File

@@ -0,0 +1,110 @@
#ifndef LIB_LIST_H_
#define LIB_LIST_H_
/*
* \file list.h
* \brief Doppelt verkettete List Datenstruktur
*
* Diese Datei ist eine Hilfestellung für Aufgabe 3.
* Sie erspart euch den Aufwand, selber eine doppelt verkettete Liste zu implementieren.
*/
// List Node struct
typedef struct list_node {
struct list_node *next;
struct list_node *prev;
} list_node;
// Makro zum initialisieren einer Liste
#define list_create(N) \
static list_node head__##N = { &(head__##N), &(head__##N) }; \
static list_node *N = &(head__##N)
//checks if list is empty
[[nodiscard]] static inline bool list_is_empty(list_node *head)
{
return head == head->next;
}
// Gibt das erste Elemnt der Liste zurück
[[nodiscard, maybe_unused]] static inline list_node *list_get_first(list_node *head)
{
if (list_is_empty(head)) {
return nullptr;
}
return head->next;
}
// Gibt das letzte Element der Liste zurück
[[nodiscard, maybe_unused]] static inline list_node *list_get_last(list_node *head)
{
if (list_is_empty(head)) {
return nullptr;
}
return head->prev;
}
// Füge Elemente hinzu (Hilfsfunktion)
static inline void list_add_(list_node *node, list_node *prev)
{
node->prev = prev;
node->next = prev->next;
prev->next->prev = node;
prev->next = node;
}
// Füge Element am Anfang der Liste hinzu
[[maybe_unused]] static inline void list_add_first(list_node *head, list_node *new)
{
list_add_(new, head);
}
// Füge Element am Ende der Liste hinzu
[[maybe_unused]] static inline void list_add_last(list_node *head, list_node *new)
{
list_add_(new, head->prev);
}
// Entferne Element (Hilfsfunktion)
static inline void list_remove_(list_node *node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
// Entfernt das erste Element aus der Liste und gibt es zurück
[[maybe_unused]] static inline list_node *list_remove_first(list_node *head)
{
if (list_is_empty(head)) {
return nullptr;
}
list_node *del = head->next;
list_remove_(del);
return del;
}
// Entferne das letzte Element aus der Liste und gibt es zurück
[[maybe_unused]] static inline list_node *list_remove_last(list_node *head)
{
if (list_is_empty(head)) {
return nullptr;
}
list_node *del = head->prev;
list_remove_(del);
return del;
}
// Entfernt das spezielle Element aus der Liste
[[maybe_unused]] static inline list_node *list_remove(list_node *head, list_node *rem)
{
list_node *curr;
for (curr = head->next; curr != head; curr = curr->next) {
if (curr == rem) {
list_remove_(curr);
return curr;
}
}
return nullptr;
}
#endif // LIB_LIST_H_

89
include/lib/ringbuffer.h Normal file
View 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