Hello Nordic Support Team,
I am trying to implement a ring buffer of structs.
Even though my consumer runs much more frequently than my producer, the buffer becomes full just a few moments after starting my code.
I suspect the issue might be related to data alignment, but I am unable to identify the problem.
Could someone please help me with this issue?
Thank you in advance.
typedef struct
{
uint16_t addr;
uint8_t valid_addr;
filterSrvSensorType_t analyzing_type;
emaFilterContext_t ema_context;
temaFilterContext_t tema_context;
kalmanFilterContext_t kalman_context;
filterSrvSensorContext_t ble_sensor_context;
filterSrvSensorContext_t lora_sensor_context;
} filterSrvContext_t;
#define FILTER_SRV_REFRESH_INTERVAL 50
#define FILTER_SRV_RING_BUFFER_AMOUNT 64 // Number of filterSrvContext_t
#define FILTER_SRV_BUFFER_SIZE_BYTES (FILTER_SRV_RING_BUFFER_AMOUNT * ((sizeof(filterSrvContext_t) + 3) / 4))
struct ring_buf filterSrvRingBuffer;
static uint8_t filterSrvBufferStorage[FILTER_SRV_BUFFER_SIZE_BYTES];
filterSrvContext_t filterSrvContext[FILTER_SRV_MAX_CONTEXTS];
uint8_t filterSrvMsg[I2C_SRV_TX_BUF_LEN - 5] = {0};
uint8_t filterSrvMsgSize = 0;
uint8_t filterSrvProducerItem(filterSrvContext_t *filter_context)
{
__aligned(4) static uint32_t tmp_buf_static[(sizeof(filterSrvContext_t) + 3) / 4];
memcpy(tmp_buf_static, filter_context, sizeof(filterSrvContext_t));
int ret = ring_buf_item_put(&filterSrvRingBuffer,
filter_context->analyzing_type,
0,
tmp_buf_static,
(sizeof(filterSrvContext_t) + 3) / 4);
LOG_INF("Producing %s Distance: %.2f",
(filter_context->analyzing_type == FILTER_SRV_SENSOR_TYPE_BLE) ? "BLE " : "LORA",
(filter_context->analyzing_type == FILTER_SRV_SENSOR_TYPE_BLE) ? filter_context->ble_sensor_context.distance_value
: filter_context->lora_sensor_context.distance_value);
if (ret != 0)
{
LOG_ERR("Ring buffer is full");
return FILTER_SRV_RING_IS_FULL;
}
else
{
return FILTER_SRV_RING_IS_NOT_FULL;
}
}
uint8_t filterSrvConsumerItem(filterSrvContext_t *filter_context)
{
uint16_t type;
uint8_t value;
uint8_t size32 = (sizeof(filterSrvContext_t) + 3) / 4;
uint32_t tmp_buf[size32];
int ret = ring_buf_item_get(&filterSrvRingBuffer,
&type,
&value,
tmp_buf,
&size32);
if (ret == 0)
{
memcpy(filter_context, tmp_buf, sizeof(filterSrvContext_t));
LOG_INF("Consuming %s Distance: %.2f",
(filter_context->analyzing_type == FILTER_SRV_SENSOR_TYPE_BLE) ? "BLE " : "LORA",
(filter_context->analyzing_type == FILTER_SRV_SENSOR_TYPE_BLE) ? filter_context->ble_sensor_context.distance_value
: filter_context->lora_sensor_context.distance_value);
return FILTER_SRV_RING_IS_NOT_EMPTY;
}
else
{
return FILTER_SRV_RING_IS_EMPTY;
}
}
void filterSrvThread(void)
{
while (1)
{
filterSrvContext_t aux = {0};
while (filterSrvConsumerItem(&aux) != FILTER_SRV_RING_IS_EMPTY)
{
filterSrvAddSensorData(&aux);
}
k_sleep(K_MSEC(FILTER_SRV_REFRESH_INTERVAL));
}
}