ether2ser 0.1.0
Ethernet <-> synchronous V.24 bridge firmware for RP2040 + W5500
Loading...
Searching...
No Matches
ringbuffer.c
Go to the documentation of this file.
1/*
2 * ether2ser - Ethernet <-> synchronous V.24 (RS-232/V.28) bridge
3 *
4 * File: src/system/ringbuffer.c
5 * Purpose: Generic ring buffer implementation.
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Copyright (c) 2026 Florian <f.leuze@outlook.de>
10 */
11
12// Related headers
13#include "ringbuffer.h"
14
15// Standard library headers
16#include <stdint.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21// Project Headers
22
23// Generated headers
24
25// Project Headers
26
27int RbInit(Ringbuffer* bufferStruct, void* bufferPointer, size_t capacity, size_t itemSizeInByte)
28{
29 bufferStruct->buffer = bufferPointer;
30 if (bufferStruct->buffer == NULL)
31 {
32 return -1;
33 }
34 bufferStruct->bufferEnd = (uint8_t*)bufferStruct->buffer + capacity * itemSizeInByte;
35 bufferStruct->capacity = capacity;
36 bufferStruct->count = 0U;
37 bufferStruct->itemSizeInByte = itemSizeInByte;
38 bufferStruct->head = bufferStruct->buffer;
39 bufferStruct->tail = bufferStruct->buffer;
40 memset(bufferStruct->buffer, 0U, capacity * itemSizeInByte);
41 return 0;
42}
43
44int RbPushBack(Ringbuffer* bufferStruct, const void* element)
45{
46 if (bufferStruct->count == bufferStruct->capacity)
47 {
48 return -1;
49 }
50 memcpy(bufferStruct->head, element, bufferStruct->itemSizeInByte);
51 bufferStruct->head = (uint8_t*)bufferStruct->head + bufferStruct->itemSizeInByte;
52 if (bufferStruct->head == bufferStruct->bufferEnd)
53 {
54 bufferStruct->head = bufferStruct->buffer;
55 }
56 ++bufferStruct->count;
57 return 0;
58}
59
60int RbPopFront(Ringbuffer* bufferStruct, void* element)
61{
62 if (bufferStruct->count == 0U)
63 {
64 return -1;
65 }
66 memcpy(element, bufferStruct->tail, bufferStruct->itemSizeInByte);
67 bufferStruct->tail = (uint8_t*)bufferStruct->tail + bufferStruct->itemSizeInByte;
68 if (bufferStruct->tail == bufferStruct->bufferEnd)
69 {
70 bufferStruct->tail = bufferStruct->buffer;
71 }
72 --bufferStruct->count;
73 return 0;
74}
75
76void RbPushBackWrap(Ringbuffer* bufferStruct, const void* element)
77{
78 if (bufferStruct->count == bufferStruct->capacity)
79 {
80 // Buffer is full, overwrite the oldest element
81 bufferStruct->tail = (uint8_t*)bufferStruct->tail + bufferStruct->itemSizeInByte;
82 if (bufferStruct->tail == bufferStruct->bufferEnd)
83 {
84 bufferStruct->tail = bufferStruct->buffer; // Wrap around
85 }
86 }
87 else
88 {
89 // Increment count only if the buffer was not full
90 ++bufferStruct->count;
91 }
92
93 // Add the new element at the head position
94 memcpy(bufferStruct->head, element, bufferStruct->itemSizeInByte);
95 bufferStruct->head = (uint8_t*)bufferStruct->head + bufferStruct->itemSizeInByte;
96 if (bufferStruct->head == bufferStruct->bufferEnd)
97 {
98 bufferStruct->head = bufferStruct->buffer; // Wrap around
99 }
100}
int RbInit(Ringbuffer *bufferStruct, void *bufferPointer, size_t capacity, size_t itemSizeInByte)
Initialize ring buffer instance.
Definition ringbuffer.c:27
void RbPushBackWrap(Ringbuffer *bufferStruct, const void *element)
Push one element and overwrite oldest entry when full.
Definition ringbuffer.c:76
int RbPopFront(Ringbuffer *bufferStruct, void *element)
Pop one element from front.
Definition ringbuffer.c:60
int RbPushBack(Ringbuffer *bufferStruct, const void *element)
Push one element at tail/head end.
Definition ringbuffer.c:44
Generic fixed-size ring buffer state.
Definition ringbuffer.h:28
void * bufferEnd
Definition ringbuffer.h:32
void * buffer
Definition ringbuffer.h:30
size_t capacity
Definition ringbuffer.h:34
void * head
Definition ringbuffer.h:40
size_t itemSizeInByte
Definition ringbuffer.h:38
size_t count
Definition ringbuffer.h:36
void * tail
Definition ringbuffer.h:42