1.Ringbuff结构体
struct ring_buffer_t {
volatile uint8_t *buffer; /* block of memory or array of data */
unsigned element_size; /* how many bytes for each chunk */
unsigned element_count; /* number of chunks of data */
volatile unsigned head; /* where the writes go */
volatile unsigned tail; /* where the reads come from */
};
typedef struct ring_buffer_t RING_BUFFER;
2.Ringbuff分配及初始化
/****************************************************************************
* DESCRIPTION: Reserves and gets the next data portion of the buffer.
* RETURN: pointer to the data, or NULL if the list is full
*****************************************************************************/
volatile uint8_t *Ringbuf_Alloc(
RING_BUFFER * b)
{
volatile uint8_t *ring_data = NULL; /* used to help point ring data */
if (b) {
/* limit the amount of elements that we accept */
if (!Ringbuf_Full(b)) {
ring_data = b->buffer;
ring_data += ((b->head % b->element_count) * b->element_size);
b->head++;
}
}
return ring_data;
}
/****************************************************************************
* DESCRIPTION: Configures the ring buffer
* NOTES:
* element_count must be a power of two
*****************************************************************************/
void Ringbuf_Init(
RING_BUFFER * b, /* ring buffer structure */
volatile uint8_t * buffer, /* data block or array of data */
unsigned element_size, /* size of one element in the data block */
unsigned element_count)
{ /* number of elements in the data block */
if (b) {
b->head = 0;
b->tail = 0;
b->buffer = buffer;
b->element_size = element_size;
b->element_count = element_count;
}
return;
}
3. 判断Ringbuff是否为空、为满
/****************************************************************************
* DESCRIPTION: Returns the empty/full status of the ring buffer
* RETURN: true if the ring buffer is empty, false if it is not.
*****************************************************************************/
bool Ringbuf_Empty(
RING_BUFFER const *b)
{
return (b ? (Ringbuf_Count(b) == 0) : true);
}
/****************************************************************************
* DESCRIPTION: Returns the number of elements in the ring buffer
* RETURN: Number of elements in the ring buffer
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
unsigned Ringbuf_Count(
RING_BUFFER const *b)
{
unsigned head, tail; /* used to avoid volatile decision */
if (b) {
head = b->head;
tail = b->tail;
return head - tail;
}
return 0;
/****************************************************************************
* DESCRIPTION: Returns the empty/full status of the ring buffer
* RETURN: true if the ring buffer is full, false if it is not.
*****************************************************************************/
bool Ringbuf_Full(
RING_BUFFER const *b)
{
return (b ? (Ringbuf_Count(b) == b->element_count) : true);
}
}
4. 从Ringbuff中取出数据
/****************************************************************************
* DESCRIPTION: Gets the data from the front of the list, and removes it
* RETURN: pointer to the data, or NULL if nothing in the list
*****************************************************************************/
volatile uint8_t *Ringbuf_Pop_Front(
RING_BUFFER * b)
{
volatile uint8_t *data_element = NULL;
if (!Ringbuf_Empty(b)) {
data_element = b->buffer;
data_element += ((b->tail % b->element_count) * b->element_size);
b->tail++;
}
return data_element;
}
5.往Ringbuff中添加数据
/****************************************************************************
* DESCRIPTION: Adds an element of data to the ring buffer
* RETURN: true on succesful add, false if not added
*****************************************************************************/
bool Ringbuf_Put(
RING_BUFFER * b, /* ring buffer structure */
volatile uint8_t * data_element)
{ /* one element to add to the ring */
bool status = false; /* return value */
volatile uint8_t *ring_data = NULL; /* used to help point ring data */
unsigned i; /* loop counter */
if (b && data_element) {
/* limit the amount of elements that we accept */
if (!Ringbuf_Full(b)) {
ring_data = b->buffer;
ring_data += ((b->head % b->element_count) * b->element_size);
for (i = 0; i < b->element_size; i++) {
ring_data[i] = data_element[i];
}
b->head++;
status = true;
}
}
return status;
}