Тема: ring buffer
Всім привіт.
Ніяк не можу розібратись.
Оголошую дефайни, структуру, функції, буфер:
#define BUFFER_SIZE 8
#define BUFFER_MASK BUFFER_SIZE - 1
typedef struct {
size_t first;
size_t last;
uint8_t data[BUFFER_SIZE];
} CircularBuffer;
void ClearBuf(CircularBuffer* pBuf)
{
pBuf->first = 0;
pBuf->last = 0;
}
bool IsEmpty(CircularBuffer* pBuf)
{
return (pBuf->first == pBuf->last);
}
bool IsFull(CircularBuffer* pBuf)
{
return (((pBuf->last + 1) & (BUFFER_MASK)) == pBuf->first);
}
bool WriteByte(CircularBuffer* pBuf, uint8_t value)
{
size_t next = (pBuf->last + 1) & (BUFFER_SIZE - 1);
if (next == pBuf->first)
return false;
pBuf->data[pBuf->last] = value;
pBuf->last = next;
return true;
}
size_t GetByteBuffer(CircularBuffer* pBuf)
{
return ((pBuf->last - pBuf->first) & (BUFFER_MASK));
}
void PrintBuffer(CircularBuffer* pBuf)
{
if (pBuf->first == pBuf->last)
printf(" Empty");
size_t pos;
for (pos = pBuf->first; pos != pBuf->last; pos = (pos + 1) & (BUFFER_SIZE - 1))
printf(" %02x", pBuf->data[pos]);
printf("\r\n");
}
CircularBuffer bufferA;
Роблю тестову перевірку:
ClearBuf(&bufferA);
int var = 0;
while(!IsFull(&bufferA))
{
if(IsEmpty(&bufferA))
printf("buffer is empty\r\n");
else
printf("buffer is not empty\r\n");
WriteByte(&bufferA, var);
printf("write %i byte, number byte in buffer: %i\r\n", var, (int) GetByteBuffer(&bufferA));
if(IsFull(&bufferA))
printf("buffer is full\r\n");
else
printf("buffer is not full\r\n");
var++;
}
printf("BufferA after write:");
PrintBuffer(&bufferA);
Результат:
buffer is empty
write 0 byte, number byte in buffer: 1
buffer is not full
buffer is not empty
write 1 byte, number byte in buffer: 2
buffer is not full
buffer is not empty
write 2 byte, number byte in buffer: 3
buffer is not full
buffer is not empty
write 3 byte, number byte in buffer: 4
buffer is not full
buffer is not empty
write 4 byte, number byte in buffer: 5
buffer is not full
buffer is not empty
write 5 byte, number byte in buffer: 6
buffer is not full
buffer is not empty
write 6 byte, number byte in buffer: 7
buffer is full
BufferA after write: 00 01 02 03 04 05 06
Неначе і все вірно, але де 8 байт буферу? Чого після 6 байту вважається що вже повний? Чи це нормально, що кільцевий буфер має розмір на один байт менше, щоб не було переповнення? Накладок хвоста на голову?
Пробував і так:
for (int var = 0; var < BUFFER_SIZE; var++)
{
if(IsEmpty(&bufferA))
printf("buffer is empty\r\n");
else
printf("buffer is not empty\r\n");
WriteByte(&bufferA, var);
printf("write %i byte, number byte in buffer: %i\r\n", var, (int) GetByteBuffer(&bufferA));
if(IsFull(&bufferA))
printf("buffer is full\r\n");
else
printf("buffer is not full\r\n");
}
printf("BufferA after write:");
PrintBuffer(&bufferA);
Результат дещо інший. На 6 і 7 байті вважається що буфер повний і кількість байт записано 7 і 7, хоча очукую 7 і 8:
buffer is empty
write 0 byte, number byte in buffer: 1
buffer is not full
buffer is not empty
write 1 byte, number byte in buffer: 2
buffer is not full
buffer is not empty
write 2 byte, number byte in buffer: 3
buffer is not full
buffer is not empty
write 3 byte, number byte in buffer: 4
buffer is not full
buffer is not empty
write 4 byte, number byte in buffer: 5
buffer is not full
buffer is not empty
write 5 byte, number byte in buffer: 6
buffer is not full
buffer is not empty
write 6 byte, number byte in buffer: 7
buffer is full
buffer is not empty
write 7 byte, number byte in buffer: 7
buffer is full
BufferA after write: 00 01 02 03 04 05 06
Якщо не морочитись і записати 5 байт, наприклад, то все ОК.
UART1 transmit is normal.
buffer is empty
write 0 byte, number byte in buffer: 1
buffer is not full
buffer is not empty
write 1 byte, number byte in buffer: 2
buffer is not full
buffer is not empty
write 2 byte, number byte in buffer: 3
buffer is not full
buffer is not empty
write 3 byte, number byte in buffer: 4
buffer is not full
buffer is not empty
write 4 byte, number byte in buffer: 5
buffer is not full
BufferA after write: 00 01 02 03 04