现在的位置: 首页 > 综合 > 正文

BACnet协议栈中一个Ringbuff编程范例

2012年08月30日 ⁄ 综合 ⁄ 共 4229字 ⁄ 字号 评论关闭

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;
}

 

 

 

抱歉!评论已关闭.