diff options
| -rw-r--r-- | stm32f091/backlog.c | 34 | ||||
| -rw-r--r-- | stm32f091/backlog.h | 57 | 
2 files changed, 91 insertions, 0 deletions
| diff --git a/stm32f091/backlog.c b/stm32f091/backlog.c new file mode 100644 index 0000000..3f21924 --- /dev/null +++ b/stm32f091/backlog.c @@ -0,0 +1,34 @@ +#include <stdlib.h> + +#include "backlog.h" + +ws_s_backlog_database* WS_G_BACKLOG_DATABASE = NULL; + +void ws_backlog_alloc(uint16_t record_amt) { +	WS_G_BACKLOG_DATABASE = malloc(sizeof(ws_s_backlog_database) + sizeof(ws_s_backlog_record) * record_amt); +	WS_G_BACKLOG_DATABASE->buffer_size = record_amt; +	WS_G_BACKLOG_DATABASE->buffer_start = 0; +	WS_G_BACKLOG_DATABASE->buffer_end = 0; +} + +void ws_backlog_add_record(ws_s_backlog_record record) { +	static uint16_t id = 0; + +	WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].id = id++; +	WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_atm_pressure = record.sens_atm_pressure; +	WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_humidity = record.sens_humidity; +	WS_G_BACKLOG_DATABASE->records[WS_G_BACKLOG_DATABASE->buffer_end].sens_temperature = record.sens_temperature; + +	// shift buffer start/end +	WS_G_BACKLOG_DATABASE->buffer_end = (WS_G_BACKLOG_DATABASE->buffer_end + 1) % WS_G_BACKLOG_DATABASE->buffer_size; +	if (WS_G_BACKLOG_DATABASE->buffer_end == WS_G_BACKLOG_DATABASE->buffer_start) +		WS_G_BACKLOG_DATABASE->buffer_start = (WS_G_BACKLOG_DATABASE->buffer_start + 1) % WS_G_BACKLOG_DATABASE->buffer_size; +} + +ws_s_backlog_record* ws_backlog_get_record(uint16_t record_index) { +	return &WS_G_BACKLOG_DATABASE->records[record_index]; +} + +ws_s_backlog_record* ws_backlog_get_last_record(uint16_t record_offset) { +	return ws_backlog_get_record((WS_G_BACKLOG_DATABASE->buffer_end - record_offset - 1) % WS_G_BACKLOG_DATABASE->buffer_size); +} diff --git a/stm32f091/backlog.h b/stm32f091/backlog.h new file mode 100644 index 0000000..465b3c0 --- /dev/null +++ b/stm32f091/backlog.h @@ -0,0 +1,57 @@ +#pragma once + +#include <stdint.h> + +/** + * @brief allocate backlog buffer and set global backlog pointer + * @param record_amt amount of records to keep before overwriting oldest record + */ +void ws_backlog_alloc(uint16_t record_amt); + +// enable struct packing +#pragma pack(push, 1) + +/** @brief backlog record */ +typedef struct { +	uint16_t id; /**< unique record identifier, numbered sequentially */ +	uint8_t sens_temperature; /**< temperature reading */ +	uint8_t sens_humidity; /**< humidity reading */ +	uint8_t sens_atm_pressure; /**< atmospheric pressure reading */ +} ws_s_backlog_record; + +typedef struct { +	uint16_t buffer_size; /**< buffer size (amount of records) */ +	uint16_t buffer_start; /** first record index */ +	uint16_t buffer_end; /** last record index */ +	ws_s_backlog_record records[]; /** record array */ +} ws_s_backlog_database; + +// disable struct packing +#pragma pack(pop) + +/** @brief global record backlog database pointer */ +extern ws_s_backlog_database* WS_G_BACKLOG_DATABASE; + +/** + * @brief add record to database + * + * automatically sets record.id, pushes buffer_end forwards and overwrites the + * last record if the buffer is full + */ +void ws_backlog_add_record(ws_s_backlog_record record); + +/** + * there's intentionally no function to retrieve multiple records as an array, + * as this would either require + * (a) copying the selection which is not possible with the current memory + * constraints, or + * (b) giving a direct pointer, but this would cause undefined behavior at the + * ring buffer seam + */ + +/** @brief get pointer to record with index `record_index` from the database */ +ws_s_backlog_record* ws_backlog_get_record(uint16_t record_index); + +/** @brief get pointer to last record with offset `record_offset` from the database */ +ws_s_backlog_record* ws_backlog_get_last_record(uint16_t record_offset); + |