// 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__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 */ #ifndef _PCIRCULARBUFFER_H_ #define _PCIRCULARBUFFER_H_ #include #include 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; #if PB_CB_DOUBLE typedef struct p_cb_double { double *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_double *cbuffer, double value); PB_CB_STATUS (*empty)(struct p_cb_double *cbuffer); } p_cb_double; PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t max_length); #endif #endif