added penguinbuffers submodule
parent
9f0877c746
commit
1ee7e71711
@ -0,0 +1,3 @@
|
||||
[submodule "PenguinBuffer"]
|
||||
path = PenguinBuffer
|
||||
url = git@git.epenguin.net:penguin/PenguinBuffer.git
|
@ -0,0 +1 @@
|
||||
Subproject commit 9804c4b906262b873e7f72e3aab3bf899db34b64
|
@ -1,194 +0,0 @@
|
||||
#include "putil.h"
|
||||
#include <PCircularBuffer.h>
|
||||
|
||||
// Error handler used for debugging only
|
||||
#ifdef PB_CB_DEBUG
|
||||
#include <stdio.h>
|
||||
static void handle_status(const char *func, PB_CB_STATUS status_code)
|
||||
{
|
||||
if (status_code != PB_CB_GOOD)
|
||||
{
|
||||
PDEBUG("%s failed: error code: %d\r\n", func, status_code);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Circular Buffer Prototypes -- uint8_t
|
||||
static PB_CB_STATUS p_cb_u8_push(p_cb_u8 *cbuffer, uint8_t value);
|
||||
static PB_CB_STATUS p_cb_u8_empty(p_cb_u8 *cbuffer);
|
||||
|
||||
// serial_pkt
|
||||
static PB_CB_STATUS p_cb_serial_pkt_push(p_cb_serial_pkt_t *cbuffer, serial_pkt_t value);
|
||||
static PB_CB_STATUS p_cb_serial_pkt_empty(p_cb_serial_pkt_t *cbuffer);
|
||||
|
||||
// Circular Buffer Definitions -- uint8_t
|
||||
PB_CB_STATUS p_cb_u8_init(p_cb_u8 *circ_buffer, uint8_t *buff, uint32_t max_length)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
do
|
||||
{
|
||||
// Make sure the buffer isn't bad (null)
|
||||
if (!buff)
|
||||
{
|
||||
ret = PB_CB_NULL_BUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure the max buffer is a useable size
|
||||
if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0)
|
||||
{
|
||||
ret = PB_CB_BAD_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PB_CB_STATUS p_cb_u8_push(p_cb_u8 *cbuffer, uint8_t value)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
|
||||
if (!cbuffer)
|
||||
{
|
||||
ret = PB_CB_NULL_CBUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuffer->buffer[cbuffer->head] = value;
|
||||
cbuffer->head = (cbuffer->head + 1) % cbuffer->max_len;
|
||||
}
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PB_CB_STATUS p_cb_u8_empty(p_cb_u8 *cbuffer)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
|
||||
do
|
||||
{
|
||||
if (!cbuffer)
|
||||
{
|
||||
ret = PB_CB_NULL_CBUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cbuffer->buffer)
|
||||
{
|
||||
ret = PB_CB_NULL_BUFFER;
|
||||
break;
|
||||
}
|
||||
memset(cbuffer->buffer, 0, cbuffer->max_len);
|
||||
cbuffer->head = 0;
|
||||
cbuffer->b_empty = true;
|
||||
cbuffer->b_filled = false;
|
||||
} while (0);
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Circular Buffer Definitions -- uint8_t
|
||||
PB_CB_STATUS p_cb_serial_pkt_init(p_cb_serial_pkt_t *inst, serial_pkt_t *buff, uint32_t max_length)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
do
|
||||
{
|
||||
if (!buff)
|
||||
{
|
||||
ret = PB_CB_NULL_BUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0)
|
||||
{
|
||||
ret = PB_CB_BAD_BUFFER_SIZE;
|
||||
break;
|
||||
}
|
||||
for (int ind = 0; ind < max_length; ind++)
|
||||
{
|
||||
memset(inst->buffer[ind].frame_data, 0, 256);
|
||||
}
|
||||
inst->buffer = buff;
|
||||
inst->max_len = (uint16_t)max_length;
|
||||
inst->head = 0;
|
||||
inst->push = p_cb_serial_pkt_push;
|
||||
inst->empty = p_cb_serial_pkt_empty;
|
||||
inst->empty(inst);
|
||||
} while (0);
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PB_CB_STATUS p_cb_serial_pkt_push(p_cb_serial_pkt_t *cbuffer, serial_pkt_t value)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
|
||||
if (!cbuffer)
|
||||
{
|
||||
ret = PB_CB_NULL_CBUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuffer->buffer[cbuffer->head] = value;
|
||||
cbuffer->head = (cbuffer->head + 1) % cbuffer->max_len;
|
||||
}
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PB_CB_STATUS p_cb_serial_pkt_empty(p_cb_serial_pkt_t *cbuffer)
|
||||
{
|
||||
PB_CB_STATUS ret = PB_CB_GOOD;
|
||||
|
||||
do
|
||||
{
|
||||
if (!cbuffer)
|
||||
{
|
||||
ret = PB_CB_NULL_CBUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cbuffer->buffer)
|
||||
{
|
||||
ret = PB_CB_NULL_BUFFER;
|
||||
break;
|
||||
}
|
||||
memset(cbuffer->buffer, 0, sizeof(serial_pkt_t) * cbuffer->max_len);
|
||||
cbuffer->head = 0;
|
||||
cbuffer->b_empty = true;
|
||||
cbuffer->b_filled = false;
|
||||
} while (0);
|
||||
|
||||
// Debugging
|
||||
#ifdef PB_CB_DEBUG
|
||||
handle_status(__func__, ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
// Resource/Inspiration: https://embedjournal.com/implementing-circular-buffer-embedded-c/
|
||||
|
||||
/*
|
||||
Penguin's Circular Buffer -- a simple floating queue designed for low memory usage (mainly for embedded)
|
||||
|
||||
This is a ring buffer with limited capabilities. It is meant as a container for moving data.
|
||||
Normally included features such as checks to see if the buffer is full or empty have been omitted
|
||||
because this type of buffer is being implemented mainly for sensor data usage. Data is almost never read
|
||||
individually, and even if it is, it isn't meant to be cleared on read. It is a simple moving buffer that
|
||||
automatically writes over old data for the purpose of keeping track of the most up to date data.
|
||||
|
||||
Notes:
|
||||
- Initialization is mandatory using p_cb_<type>_init.
|
||||
- If a circular buffer is not initialized, you will run into a LOT of hard-to-debug problems. Just initialize it.
|
||||
- By default, all cb types should be defined as disabled. This is to save on size. Enable the ones you want to use.
|
||||
|
||||
Behavior:
|
||||
- Oldest data is overwritten
|
||||
- popping of data isn't implemented. If this feature is required, use a ring buffer.
|
||||
|
||||
Acronyms:
|
||||
- p: penguin
|
||||
- pb: penguin buffer
|
||||
- cb: circular buffer
|
||||
- uX, where X is bit size: unsigned X bit integer
|
||||
- iX, where X is bit size: signed X bit integer
|
||||
|
||||
Note: I wrote this like 3 years ago or something. I hope it works.
|
||||
*/
|
||||
|
||||
#ifndef _PCIRCULARBUFFER_H_
|
||||
#define _PCIRCULARBUFFER_H_
|
||||
|
||||
#include "p_serial_mgr.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define PC_CB_DEBUG
|
||||
#endif
|
||||
|
||||
// Max size is 65535 (2^16 - 1) so variables can be safely set 16 bits (unsigned)
|
||||
// If you want to change this, you'll need to change the sizes of all heads and max lengths
|
||||
#define PB_CB_MAX_BUFFER_SIZE (65535)
|
||||
|
||||
typedef enum PB_CB_STATUS
|
||||
{
|
||||
PB_CB_GOOD = 0,
|
||||
PB_CB_BAD = 1,
|
||||
PB_CB_BAD_BUFFER_SIZE = 2,
|
||||
PB_CB_NULL_BUFFER = 3,
|
||||
PB_CB_NULL_CBUFFER = 4
|
||||
} PB_CB_STATUS;
|
||||
|
||||
typedef struct p_cb_u8
|
||||
{
|
||||
uint8_t *buffer;
|
||||
uint16_t head;
|
||||
uint16_t max_len;
|
||||
// Signifies the buffer being filled at least once.
|
||||
// Useful for initializing sensor data
|
||||
bool b_filled;
|
||||
// Signifies the buffer being empty
|
||||
// Useful for knowing if data is being received
|
||||
bool b_empty;
|
||||
|
||||
PB_CB_STATUS (*push)(struct p_cb_u8 *cbuffer, uint8_t value);
|
||||
PB_CB_STATUS (*empty)(struct p_cb_u8 *cbuffer);
|
||||
} p_cb_u8;
|
||||
|
||||
PB_CB_STATUS p_cb_u8_init(p_cb_u8 *circ_buffer, uint8_t *buff, uint32_t max_length);
|
||||
|
||||
typedef struct p_cb_serial_pkt_t
|
||||
{
|
||||
serial_pkt_t *buffer;
|
||||
uint16_t head;
|
||||
uint16_t max_len;
|
||||
bool b_filled;
|
||||
// Signifies the buffer being empty
|
||||
// Useful for knowing if data is being received
|
||||
bool b_empty;
|
||||
|
||||
PB_CB_STATUS (*push)(struct p_cb_serial_pkt_t *cbuffer, serial_pkt_t value);
|
||||
PB_CB_STATUS (*empty)(struct p_cb_serial_pkt_t *cbuffer);
|
||||
} p_cb_serial_pkt_t;
|
||||
|
||||
PB_CB_STATUS p_cb_serial_pkt_init(p_cb_serial_pkt_t *inst, serial_pkt_t *buff, uint32_t max_length);
|
||||
#endif
|
Loading…
Reference in New Issue