CODE
typedef enum CycBuffState {cbsOk = 0, cbsOverwrite = 1, cbsBuffFull = 2, cbsBuffEmpty = 3, cbsError = 4} enCycBuffState;
typedef struct
{
uint32_t MaxBufSize,
HeadIdx,
TailIdx;
enCycBuffState State;
uint8_t *Buffer;
} stRingBuffer;
void RingBuf_Init (stRingBuffer *ring_buf, uint8_t *buf, uint32_t max_size)
{
ring_buf->Buffer = buf;
ring_buf->MaxBufSize = max_size;
ring_buf->HeadIdx = ring_buf->TailIdx = 0;
ring_buf->State = cbsBuffEmpty;
}
enCycBuffState RingBuf_PushByte(stRingBuffer *ring_buf, uint8_t val, uint8_t allow_overwrite)
{
if ((ring_buf->HeadIdx+1) == ring_buf->TailIdx)
{
if (!allow_overwrite)
return cbsBuffFull;
}
ring_buf->Buffer[ring_buf->HeadIdx] = val;
ring_buf->HeadIdx++;
if (ring_buf->HeadIdx >= ring_buf->MaxBufSize)
ring_buf->HeadIdx = 0;
return cbsOk;
}
enCycBuffState RingBuf_PushBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *buf, uint8_t allow_overwrite)
{
uint32_t free_space;
if (ring_buf->HeadIdx == ring_buf->TailIdx)
{
free_space = ring_buf->MaxBufSize;
}
else
{
if (ring_buf->HeadIdx >= ring_buf->TailIdx)
free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
else
free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;
if (free_space < len)
return cbsBuffFull;
}
while (len)
{
RingBuf_PushByte(ring_buf, *buf, allow_overwrite);
buf++;
len--;
}
return cbsOk;
}
enCycBuffState RingBuf_PopByte(stRingBuffer *ring_buf, uint8_t *val)
{
if (ring_buf->HeadIdx == ring_buf->TailIdx)
return cbsError;
*val = ring_buf->Buffer[ring_buf->TailIdx];
ring_buf->Buffer[ring_buf->TailIdx] = 0;
ring_buf->TailIdx++;
if (ring_buf->TailIdx >= ring_buf->MaxBufSize)
ring_buf->TailIdx = 0;
return cbsOk;
}
enCycBuffState RingBuf_PopBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *val)
{
while (len)
{
RingBuf_PopByte(ring_buf, val);
val++;
len--;
}
return cbsOk;
}
typedef struct
{
uint32_t MaxBufSize,
HeadIdx,
TailIdx;
enCycBuffState State;
uint8_t *Buffer;
} stRingBuffer;
void RingBuf_Init (stRingBuffer *ring_buf, uint8_t *buf, uint32_t max_size)
{
ring_buf->Buffer = buf;
ring_buf->MaxBufSize = max_size;
ring_buf->HeadIdx = ring_buf->TailIdx = 0;
ring_buf->State = cbsBuffEmpty;
}
enCycBuffState RingBuf_PushByte(stRingBuffer *ring_buf, uint8_t val, uint8_t allow_overwrite)
{
if ((ring_buf->HeadIdx+1) == ring_buf->TailIdx)
{
if (!allow_overwrite)
return cbsBuffFull;
}
ring_buf->Buffer[ring_buf->HeadIdx] = val;
ring_buf->HeadIdx++;
if (ring_buf->HeadIdx >= ring_buf->MaxBufSize)
ring_buf->HeadIdx = 0;
return cbsOk;
}
enCycBuffState RingBuf_PushBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *buf, uint8_t allow_overwrite)
{
uint32_t free_space;
if (ring_buf->HeadIdx == ring_buf->TailIdx)
{
free_space = ring_buf->MaxBufSize;
}
else
{
if (ring_buf->HeadIdx >= ring_buf->TailIdx)
free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
else
free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;
if (free_space < len)
return cbsBuffFull;
}
while (len)
{
RingBuf_PushByte(ring_buf, *buf, allow_overwrite);
buf++;
len--;
}
return cbsOk;
}
enCycBuffState RingBuf_PopByte(stRingBuffer *ring_buf, uint8_t *val)
{
if (ring_buf->HeadIdx == ring_buf->TailIdx)
return cbsError;
*val = ring_buf->Buffer[ring_buf->TailIdx];
ring_buf->Buffer[ring_buf->TailIdx] = 0;
ring_buf->TailIdx++;
if (ring_buf->TailIdx >= ring_buf->MaxBufSize)
ring_buf->TailIdx = 0;
return cbsOk;
}
enCycBuffState RingBuf_PopBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *val)
{
while (len)
{
RingBuf_PopByte(ring_buf, val);
val++;
len--;
}
return cbsOk;
}
И потом проверяю (в IAR, в симуляторе)
Код
#include <string.h>
#include "ringbuf.h"
stRingBuffer ring_buf;
uint8_t *temp_buff;
uint8_t *test_buff = "Hello World";
uint8_t *read_buff;
int main()
{
RingBuf_Init (&ring_buf, temp_buff, 32);
while (1)
{
RingBuf_PushBytes(&ring_buf, strlen(test_buff), test_buff, 0);
RingBuf_PopBytes(&ring_buf, strlen(test_buff), read_buff);
}
}
#include "ringbuf.h"
stRingBuffer ring_buf;
uint8_t *temp_buff;
uint8_t *test_buff = "Hello World";
uint8_t *read_buff;
int main()
{
RingBuf_Init (&ring_buf, temp_buff, 32);
while (1)
{
RingBuf_PushBytes(&ring_buf, strlen(test_buff), test_buff, 0);
RingBuf_PopBytes(&ring_buf, strlen(test_buff), read_buff);
}
}
Но несмотря на то что я отслеживаю наличие свободного места.
Код
uint32_t free_space;
if (ring_buf->HeadIdx == ring_buf->TailIdx)
{
free_space = ring_buf->MaxBufSize;
}
else
{
if (ring_buf->HeadIdx >= ring_buf->TailIdx)
free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
else
free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;
if (free_space < len)
return cbsBuffFull;
if (ring_buf->HeadIdx == ring_buf->TailIdx)
{
free_space = ring_buf->MaxBufSize;
}
else
{
if (ring_buf->HeadIdx >= ring_buf->TailIdx)
free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
else
free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;
if (free_space < len)
return cbsBuffFull;
В отладчике я вижу перезапись буфера. Что я упустил?