File syn_datalog.c¶
File List > log > syn_datalog.c
Go to the documentation of this file
#if __has_include("syn_config.h")
#include "syn_config.h"
#endif
#if !defined(SYN_USE_DATALOG) || SYN_USE_DATALOG
#include "../util/syn_assert.h"
#include "syn_datalog.h"
void syn_datalog_init(SYN_DataLog *log, uint8_t *buf, size_t size)
{
SYN_ASSERT(log != NULL);
SYN_ASSERT(buf != NULL);
SYN_ASSERT(size > sizeof(SYN_DataLogHeader));
if (log == NULL || buf == NULL || size <= sizeof(SYN_DataLogHeader)) {
return;
}
syn_ringbuf_init(&log->rb, buf, size);
log->dropped_frames = 0;
}
bool syn_datalog_write(SYN_DataLog *log, uint16_t id, const void *data, uint16_t len)
{
SYN_ASSERT(log != NULL);
SYN_ASSERT(data != NULL || len == 0);
if (log == NULL || (data == NULL && len > 0)) {
return false;
}
size_t required = sizeof(SYN_DataLogHeader) + len;
// Check if we have enough space
if (syn_ringbuf_free(&log->rb) < required) {
log->dropped_frames++;
return false; // Not enough space, drop the frame atomically
}
// Write header
SYN_DataLogHeader header = {.id = id, .len = len};
syn_ringbuf_write(&log->rb, (const uint8_t *)&header, sizeof(header));
// Write payload
if (len > 0) {
syn_ringbuf_write(&log->rb, (const uint8_t *)data, len);
}
return true;
}
size_t syn_datalog_read(SYN_DataLog *log, uint16_t *out_id, void *out_data, size_t max_len)
{
SYN_ASSERT(log != NULL);
SYN_ASSERT(out_id != NULL);
SYN_ASSERT(out_data != NULL);
if (log == NULL || out_id == NULL || out_data == NULL) {
return 0;
}
if (syn_ringbuf_count(&log->rb) < sizeof(SYN_DataLogHeader)) {
return 0; /* empty or incomplete header */
}
/*
* Peek the header without consuming it. This lets us inspect the
* payload length before committing to a read, so if max_len is too
* small the frame is left intact in the buffer and the caller can
* retry with a larger buffer.
*/
SYN_DataLogHeader header;
if (syn_ringbuf_peek_n(&log->rb, (uint8_t *)&header, sizeof(header)) < sizeof(header)) {
return 0; /* should not happen if count check above passed */
}
/* Verify that full frame (header + payload) is available in ringbuffer */
if (syn_ringbuf_count(&log->rb) < sizeof(header) + (size_t)header.len) {
return 0;
}
*out_id = header.id;
if (header.len > max_len) {
/*
* Buffer too small — leave the frame in place so the caller can
* retry. Do NOT increment dropped_frames; this is not a data loss
* event, just a sizing mismatch.
*/
return 0;
}
/* Now consume the header and payload together */
syn_ringbuf_read(&log->rb, (uint8_t *)&header, sizeof(header));
if (header.len > 0) {
syn_ringbuf_read(&log->rb, (uint8_t *)out_data, header.len);
}
return header.len;
}
#endif /* SYN_USE_DATALOG */