lwrb是一款通用FIFO环形缓冲区实现的开源库,并遵循 MIT 开源许可协议。

优点:

  • 使用C99语法编写,并且没有平台相关代码;
  • 没有动态内存分配;
  • 使用更优的内存复制而不是循环从内存读取数据/向内存写入数据;

 lwRB.c 文件

/**
 * \file            lwrb.c
 * \brief           Lightweight ring buffer
 */

/*
 * Copyright (c) 2020 Tilen MAJERLE
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * This file is part of LwRB - Lightweight ring buffer library.
 *
 * Author:          Tilen MAJERLE <tilen@majerle.eu>
 * Version:         v2.0.1
 * 
 * GitHub         :https://github.com/MaJerle/lwrb
 * 使用文档       : https://docs.majerle.eu/projects/lwrb/en/latest/index.html
 * DMA传输例子    : https://docs.majerle.eu/projects/lwrb/en/latest/user-manual/hw-dma-usage.html
 * DMA例子示例工程: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
 * 
 */
#include "lwrb.h"

/* Memory set and copy functions */
#define BUF_MEMSET                      memset
#define BUF_MEMCPY                      memcpy

#define BUF_MAGIC1                      (0xDEADBEEF)
#define BUF_MAGIC2                      (~0xDEADBEEF)

#if LWRB_USE_MAGIC
#define BUF_IS_VALID(b)                 ((b) != NULL && (b)->magic1 == BUF_MAGIC1 && (b)->magic2 == BUF_MAGIC2 && (b)->buff != NULL && (b)->size > 0)
#else
#define BUF_IS_VALID(b)                 ((b) != NULL && (b)->buff != NULL && (b)->size > 0)
#endif /* LWRB_USE_MAGIC */
#define BUF_MIN(x, y)                   ((x) < (y) ? (x) : (y))
#define BUF_MAX(x, y)                   ((x) > (y) ? (x) : (y))
#define BUF_SEND_EVT(b, type, bp)       do { if ((b)->evt_fn != NULL) { (b)->evt_fn((b), (type), (bp)); } } while (0)

/**
 * \brief           Initialize buffer handle to default values with size and buffer data array
 * \param[in]       buff: Buffer handle
 * \param[in]       buffdata: Pointer to memory to use as buffer data
 * \param[in]       size: Size of `buffdata` in units of bytes
 *                      Maximum number of bytes buffer can hold is `size - 1`
 * \return          `1` on success, `0` otherwise
 */
uint8_t
lwrb_init(LWRB_VOLATILE lwrb_t* buff, void* buffdata, size_t size) {
    if (buff == NULL || buffdata == NULL || size == 0) {
        return 0;
    }

    BUF_MEMSET((void*)buff, 0x00, sizeof(*buff));

    buff->size = size;
    buff->buff = buffdata;

#if LWRB_USE_MAGIC
    buff->magic1 = BUF_MAGIC1;
    buff->magic2 = BUF_MAGIC2;
#endif /* LWRB_USE_MAGIC */

    return 1;
}

/**
 * \brief           Check if buff is initialized and ready to use
 * \param[in]       buff: Buffer handle
 * \return          `1` if ready, `0` otherwise
 */
uint8_t
lwrb_is_ready(LWRB_VOLATILE lwrb_t* buff) {
    return BUF_IS_VALID(buff);
}

/**
 * \brief           Free buffer memory 空闲缓冲内存
 * \note            Since implementation does not use dynamic allocation,
 *                  it just sets buffer handle to `NULL`
 * \param[in]       buff: Buffer handle
 */
void
lwrb_free(LWRB_VOLATILE lwrb_t* buff) {
    if (BUF_IS_VALID(buff)) {
        buff->buff = NULL;
    }
}

/**
 * \brief           Set event function callback for different buffer operations
 * \                为不同的缓冲区操作设置事件函数回调
 * \param[in]       buff: Buffer handle
 * \param[in]       evt_fn: Callback function
 */
void
lwrb_set_evt_fn(LWRB_VOLATILE lwrb_t* buff, lwrb_evt_fn evt_fn) {
    if (BUF_IS_VALID(buff)) {
        buff->evt_fn = evt_fn;
    }
}

/**
 * \brief           Write data to buffer. 将数据写入缓冲区。
 * Copies data from `data` array to buffer and marks buffer as full for maximum `btw` number of bytes
 * 将数据从`data`数组复制到缓冲区,并将缓冲区标记为最大`btw`字节数已满
 *
 * \param[in]       buff: Buffer handle
 * \param[in]       data: Pointer to data to write into buffer
 * \param[in]       btw: Number of bytes to write
 * \return          Number of bytes written to buffer.
 *                      When returned value is less than `btw`, there was no enough memory available
 *                      to copy full data array
 */
size_t
lwrb_write(LWRB_VOLATILE lwrb_t* buff, const void* data, size_t btw) {
    size_t tocopy, free;
    const uint8_t* d = data;

    if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) {
        return 0;
    }

    /* Calculate maximum number of bytes available to write */
    free = lwrb_get_free(buff);
    btw = BUF_MIN(free, btw);
    if (btw == 0) {
        return 0;
    }

    /* Step 1: Write data to linear part of buffer */
    tocopy = BUF_MIN(buff->size - buff->w, btw);
    BUF_MEMCPY(&buff->buff[buff->w], d, tocopy);
    buff->w += tocopy;
    btw -= tocopy;

    /* Step 2: Write data to beginning of buffer (overflow part) */
    if (btw > 0) {
        BUF_MEMCPY(buff->buff, &d[tocopy], btw);
        buff->w = btw;
    }

    /* Step 3: Check end of buffer */
    if (buff->w >= buff->size) {
        buff->w = 0;
    }
    BUF_SEND_EVT(buff, LWRB_EVT_WRITE, tocopy + btw);
    return tocopy + btw;
}

/**
 * \brief           Read data from buffer. 从缓冲区读取数据
 * Copies data from buffer to `data` array and marks buffer as free for maximum `btr` number of bytes
 * 将数据从缓冲区复制到`data`数组,并将缓冲区标记为空闲,以达到最大的`btr`字节数
 *
 * \param[in]       buff: Buffer handle
 * \param[out]      data: Pointer to output memory to copy buffer data to
 * \param[in]       btr: Number of bytes to read
 * \return          Number of bytes read and copied to data array
 */
size_t
lwrb_read(LWRB_VOLATILE lwrb_t* buff, void* data, size_t btr) {
    size_t tocopy, full;
    uint8_t* d = data;

    if (!BUF_IS_VALID(buff) || data == NULL || btr == 0) {
        return 0;
    }

    /* Calculate maximum number of bytes available to read */
    full = lwrb_get_full(buff);
    btr = BUF_MIN(full, btr);
    if (btr == 0) {
        return 0;
    }

    /* Step 1: Read data from linear part of buffer */
    tocopy = BUF_MIN(buff->size - buff->r, btr);
    BUF_MEMCPY(d, &buff->buff[buff->r], tocopy);
    buff->r += tocopy;
    btr -= tocopy;

    /* Step 2: Read data from beginning of buffer (overflow part) */
    if (btr > 0) {
        BUF_MEMCPY(&d[tocopy], buff->buff, btr);
        buff->r = btr;
    }

    /* Step 3: Check end of buffer */
    if (buff->r >= buff->size) {
        buff->r = 0;
    }
    BUF_SEND_EVT(buff, LWRB_EVT_READ, tocopy + btr);
    return tocopy + btr;
}

/**
 * \brief           Read from buffer without changing read pointer (peek only)
 * \               在不更改读取指针的情况下从缓冲区读取(仅限窥视)
 * \param[in]       buff: Buffer handle
 * \param[in]       skip_count: Number of bytes to skip before reading data
 * \param[out]      data: Pointer to output memory to copy buffer data to
 * \param[in]       btp: Number of bytes to peek
 * \return          Number of bytes peeked and written to output array
 */
size_t
lwrb_peek(LWRB_VOLATILE lwrb_t* buff, size_t skip_count, void* data, size_t btp) {
    size_t full, tocopy, r;
    uint8_t* d = data;

    if (!BUF_IS_VALID(buff) || data == NULL || btp == 0) {
        return 0;
    }

    r = buff->r;

    /* Calculate maximum number of bytes available to read */
    full = lwrb_get_full(buff);

    /* Skip beginning of buffer */
    if (skip_count >= full) {
        return 0;
    }
    r += skip_count;
    full -= skip_count;
    if (r >= buff->size) {
        r -= buff->size;
    }

    /* Check maximum number of bytes available to read after skip */
    btp = BUF_MIN(full, btp);
    if (btp == 0) {
        return 0;
    }

    /* Step 1: Read data from linear part of buffer */
    tocopy = BUF_MIN(buff->size - r, btp);
    BUF_MEMCPY(d, &buff->buff[r], tocopy);
    btp -= tocopy;

    /* Step 2: Read data from beginning of buffer (overflow part) */
    if (btp > 0) {
        BUF_MEMCPY(&d[tocopy], buff->buff, btp);
    }
    return tocopy + btp;
}

/**
 * \brief           Get available size in buffer for write operation 
 * \                获取缓冲区中可用于写入操作的大小
 * \param[in]       buff: Buffer handle
 * \return          Number of free bytes in memory
 */
size_t
lwrb_get_free(LWRB_VOLATILE lwrb_t* buff) {
    size_t size, w, r;

    if (!BUF_IS_VALID(buff)) {
        return 0;
    }

    /* Use temporary values in case they are changed during operations 
       如果临时值在操作过程中发生更改,请使用临时值*/
    w = buff->w;
    r = buff->r;
    if (w == r) {
        size = buff->size;
    } else if (r > w) {
        size = r - w;
    } else {
        size = buff->size - (w - r);
    }

    /* Buffer free size is always 1 less than actual size
       可用缓冲区大小始终比实际大小小1*/
    return size - 1;
}

/**
 * \brief           Get number of bytes currently available in buffer 
 * \                获取缓冲区中当前可用的字节数
 * \param[in]       buff: Buffer handle
 * \return          Number of bytes ready to be read
 */
size_t
lwrb_get_full(LWRB_VOLATILE lwrb_t* buff) {
    size_t w, r, size;

    if (!BUF_IS_VALID(buff)) {
        return 0;
    }

    /* Use temporary values in case they are changed during operations */
    w = buff->w;
    r = buff->r;
    if (w == r) {
        size = 0;
    } else if (w > r) {
        size = w - r;
    } else {
        size = buff->size - (r - w);
    }
    return size;
}

/**
 * \brief           Resets buffer to default values. Buffer size is not modified
 * \                将缓冲区重置为默认值。不修改缓冲区大小
 * \param[in]       buff: Buffer handle
 */
void
lwrb_reset(LWRB_VOLATILE lwrb_t* buff) {
    if (BUF_IS_VALID(buff)) {
        buff->w = 0;
        buff->r = 0;
        BUF_SEND_EVT(buff, LWRB_EVT_RESET, 0);
    }
}

/**
 * \brief           Get linear address for buffer for fast read 
 * \                获取用于快速读取的缓冲区的线性地址
 * \                 配合 lwrb_get_linear_block_read_length 使用
 * \param[in]       buff: Buffer handle
 * \return          Linear buffer start address
 */
void*
lwrb_get_linear_block_read_address(LWRB_VOLATILE lwrb_t* buff) {
    if (!BUF_IS_VALID(buff)) {
        return NULL;
    }
    return &buff->buff[buff->r];
}

/**
 * \brief           Get length of linear block address before it overflows for read operation
 * \                获取线性块地址在其溢出以进行读取操作之前的长度
 * \param[in]       buff: Buffer handle
 * \return          Linear buffer size in units of bytes for read operation
 */
size_t
lwrb_get_linear_block_read_length(LWRB_VOLATILE lwrb_t* buff) {
    size_t w, r, len;

    if (!BUF_IS_VALID(buff)) {
        return 0;
    }

    /* Use temporary values in case they are changed during operations */
    w = buff->w;
    r = buff->r;
    if (w > r) {
        len = w - r;
    } else if (r > w) {
        len = buff->size - r;
    } else {
        len = 0;
    }
    return len;
}

/**
 * \brief           Skip (ignore; advance read pointer) buffer data 
 * \                跳过(忽略;超前读取指针)缓冲区数据
 * Marks data as read in the buffer and increases free memory for up to `len` bytes
 * 将数据标记为已在缓冲区中读取,并将可用内存增加到最多“len`”字节
 *
 * \note            Useful at the end of streaming transfer such as DMA
 * \param[in]       buff: Buffer handle
 * \param[in]       len: Number of bytes to skip and mark as read
 * \return          Number of bytes skipped
 */
size_t
lwrb_skip(LWRB_VOLATILE lwrb_t* buff, size_t len) {
    size_t full;

    if (!BUF_IS_VALID(buff) || len == 0) {
        return 0;
    }

    full = lwrb_get_full(buff);
    len = BUF_MIN(len, full);
    buff->r += len;
    if (buff->r >= buff->size) {
        buff->r -= buff->size;
    }
    BUF_SEND_EVT(buff, LWRB_EVT_READ, len);
    return len;
}

/**
 * \brief           Get linear address for buffer for fast write
 * \                获取用于快速读取的缓冲区的线性地址
 * \
 * \param[in]       buff: Buffer handle
 * \return          Linear buffer start address
 */
void*
lwrb_get_linear_block_write_address(LWRB_VOLATILE lwrb_t* buff) {
    if (!BUF_IS_VALID(buff)) {
        return NULL;
    }
    return &buff->buff[buff->w];
}

/**
 * \brief           Get length of linear block address before it overflows for write operation
 * \                在写入操作溢出之前获取线性块地址的长度 (线性溢出前可写入得数据大小)
 * \
 * \param[in]       buff: Buffer handle
 * \return          Linear buffer size in units of bytes for write operation
 */
size_t
lwrb_get_linear_block_write_length(LWRB_VOLATILE lwrb_t* buff) {
    size_t w, r, len;

    if (!BUF_IS_VALID(buff)) {
        return 0;
    }

    /* Use temporary values in case they are changed during operations */
    w = buff->w;
    r = buff->r;
    if (w >= r) {
        len = buff->size - w;
        /*
         * When read pointer is 0,
         * maximal length is one less as if too many bytes
         * are written, buffer would be considered empty again (r == w)
         */
        if (r == 0) {
            /*
             * Cannot overflow:
             * - If r is not 0, statement does not get called
             * - buff->size cannot be 0 and if r is 0, len is greater 0
             */
            --len;
        }
    } else {
        len = r - w - 1;
    }
    return len;
}

/**
 * \brief           Advance write pointer in the buffer. 缓冲区中的高级写入指针
 * Similar to skip function but modifies write pointer instead of read
 * 类似于跳过函数,但修改的是写指针而不是读指针
 *
 * \note            Useful when hardware is writing to buffer and 当硬件正在写入缓冲区时非常有用,并且
 *                  application needs to increase number of bytes written to buffer by hardware
 *                  应用程序需要增加硬件写入缓冲区的字节数
 * \param[in]       buff: Buffer handle
 * \param[in]       len: Number of bytes to advance
 * \return          Number of bytes advanced for write operation
 */
size_t
lwrb_advance(LWRB_VOLATILE lwrb_t* buff, size_t len) {
    size_t free;

    if (!BUF_IS_VALID(buff) || len == 0) {
        return 0;
    }

    free = lwrb_get_free(buff);
    len = BUF_MIN(len, free);
    buff->w += len;
    if (buff->w >= buff->size) {
        buff->w -= buff->size;
    }
    BUF_SEND_EVT(buff, LWRB_EVT_WRITE, len);
    return len;
}

LwRB.h 文件

/**
 * \file            lwrb.h
 * \brief           LwRB - Lightweight ring buffer
 */

/*
 * Copyright (c) 2020 Tilen MAJERLE
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * This file is part of LwRB - Lightweight ring buffer library.
 *
 * Author:          Tilen MAJERLE <tilen@majerle.eu>
 * Version:         v2.0.1
 * 
 * GitHub         :https://github.com/MaJerle/lwrb
 * 使用文档       : https://docs.majerle.eu/projects/lwrb/en/latest/index.html
 * DMA传输例子    : https://docs.majerle.eu/projects/lwrb/en/latest/user-manual/hw-dma-usage.html
 * DMA例子示例工程: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
 */
#ifndef LWRB_HDR_H
#define LWRB_HDR_H

#include <string.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * \defgroup        LWRB Lightweight ring buffer manager
 * \brief           Lightweight ring buffer manager
 * \{
 */

/**
 * \brief           Enable buffer structure pointer parameter as volatile  (是否使用关键字volatile)
 * To use this feature, uncomment keyword below
 */
#define LWRB_VOLATILE                           /* volatile */

/**
 * \brief           Adds 2 magic words to make sure if memory is corrupted   添加2个魔术字以确保内存是否损坏   
 *                  application can detect wrong data pointer and maximum size
 *                  应用程序可以检测错误的数据指针和最大大小
 */
#define LWRB_USE_MAGIC                      1

/**
 * \brief           Event type for buffer operations
 */
typedef enum {
    LWRB_EVT_READ,                              /*!< Read event */
    LWRB_EVT_WRITE,                             /*!< Write event */
    LWRB_EVT_RESET,                             /*!< Reset event */
} lwrb_evt_type_t;

/**
 * \brief           Buffer structure forward declaration
 */
struct lwrb;

/**
 * \brief           Event callback function type 事件回调函数类型
 * \param[in]       buff: Buffer handle for event
 * \param[in]       evt: Event type
 * \param[in]       bp: Number of bytes written or read (when used), depends on event type
 */
typedef void (*lwrb_evt_fn)(LWRB_VOLATILE struct lwrb* buff, lwrb_evt_type_t evt, size_t bp);

/**
 * \brief           Buffer structure
 */
typedef struct lwrb {
#if LWRB_USE_MAGIC
    uint32_t magic1;                            /*!< Magic 1 word */
#endif /* LWRB_USE_MAGIC */
    uint8_t* buff;                              /*!< Pointer to buffer data.
                                                    Buffer is considered initialized when `buff != NULL` and `size > 0` */
    size_t size;                                /*!< Size of buffer data. Size of actual buffer is `1` byte less than value holds */
    size_t r;                                   /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
    size_t w;                                   /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
    lwrb_evt_fn evt_fn;                         /*!< Pointer to event callback function */
#if LWRB_USE_MAGIC
    uint32_t magic2;                            /*!< Magic 2 word */
#endif /* LWRB_USE_MAGIC */
} lwrb_t;

uint8_t     lwrb_init(LWRB_VOLATILE lwrb_t* buff, void* buffdata, size_t size);
uint8_t     lwrb_is_ready(LWRB_VOLATILE lwrb_t* buff);
void        lwrb_free(LWRB_VOLATILE lwrb_t* buff);
void        lwrb_reset(LWRB_VOLATILE lwrb_t* buff);
void        lwrb_set_evt_fn(LWRB_VOLATILE lwrb_t* buff, lwrb_evt_fn fn);

/* Read/Write functions     读/写功能*/
size_t      lwrb_write(LWRB_VOLATILE lwrb_t* buff, const void* data, size_t btw);
size_t      lwrb_read(LWRB_VOLATILE lwrb_t* buff, void* data, size_t btr);
size_t      lwrb_peek(LWRB_VOLATILE lwrb_t* buff, size_t skip_count, void* data, size_t btp);

/* Buffer size information 缓冲区大小信息 */
size_t      lwrb_get_free(LWRB_VOLATILE lwrb_t* buff);
size_t      lwrb_get_full(LWRB_VOLATILE lwrb_t* buff);

/* Read data block management  读数据块管理*/
void*       lwrb_get_linear_block_read_address(LWRB_VOLATILE lwrb_t* buff);
size_t      lwrb_get_linear_block_read_length(LWRB_VOLATILE lwrb_t* buff);
size_t      lwrb_skip(LWRB_VOLATILE lwrb_t* buff, size_t len);

/* Write data block management 写数据块管理*/
void*       lwrb_get_linear_block_write_address(LWRB_VOLATILE lwrb_t* buff);
size_t      lwrb_get_linear_block_write_length(LWRB_VOLATILE lwrb_t* buff);
size_t      lwrb_advance(LWRB_VOLATILE lwrb_t* buff, size_t len);

/**
 * \}
 */

#ifdef __cplusplus
}
#endif /* __cplusplus */
/**
 *          例程Demo
 *        uint8_t lwrb_data[8 + 1];   //缓存数组
 *        lwrb_t buff;                //句柄
 *        uint8_t tmp[8];             //读缓存
 * 
 *        //Log显示反馈
 *        void my_buff_evt_fn(lwrb_t* buff, lwrb_evt_type_t type, size_t len) {
 *           switch (type) {
 *               case LWRB_EVT_RESET:
 *                   printf("[EVT] Buffer reset event!\r\n");
 *                   break;
 *               case LWRB_EVT_READ:
 *                   printf("[EVT] Buffer read event: %d byte(s)!\r\n", (int)len);
 *                   break;
 *               case LWRB_EVT_WRITE:
 *                   printf("[EVT] Buffer write event: %d byte(s)!\r\n", (int)len);
 *                   break;
 *               default: break;
 *           }
 *       }
 * 
 *       //测试的主程序
 *       int  main() {
 *           size_t len;
 *
 *           // Init buffer
 *           lwrb_init(&buff, lwrb_data, sizeof(lwrb_data)); //初始化,buff头, 实际数组 lwrb_data 数组大小
 *           lwrb_set_evt_fn(&buff, my_buff_evt_fn);         //事件反馈实体
 *
 *           lwrb_write(&buff, "abc", 3);
 *           lwrb_write(&buff, "abc", 3);
 *           lwrb_write(&buff, "abc", 3);    //写入9个数据
 *           len = lwrb_read(&buff, tmp, 9); //读取9个数据
 *
 *           buff.r = 0; //复位,读写位置
 *           buff.w = 0;
 *           memset(lwrb_get_linear_block_write_address(&buff), 'A', lwrb_get_linear_block_write_length(&buff)); //r=0 w=0 线性溢出前为空闲的位置 ,可写入 8字节
 *           lwrb_advance(&buff, lwrb_get_linear_block_write_length(&buff)); //写指针直接跳过8个位置
 *
 *           buff.r = 2;
 *           buff.w = 0;
 *           memset(lwrb_get_linear_block_write_address(&buff), 'B', lwrb_get_linear_block_write_length(&buff)); //r=2 w=0 线性溢出前为空闲的位置 ,可写入 1字节
 *           lwrb_advance(&buff, lwrb_get_linear_block_write_length(&buff)); //写指针直接跳过1个位置
 *
 *           buff.r = 3;
 *           buff.w = 3;
 *           memset(lwrb_get_linear_block_write_address(&buff), 'C', lwrb_get_linear_block_write_length(&buff));//r=3 w=3 线性溢出前为空闲的位置 ,可写入 6字节
 *           lwrb_advance(&buff, lwrb_get_linear_block_write_length(&buff)); //写指针直接跳过1个位置
 *
 *           lwrb_reset(&buff);
 *
 *           //for (size_t r = 0; r < sizeof(lwrb_data); ++r) {
 *           //    void* ptr;
 *           //    for (size_t w = 0; w < sizeof(lwrb_data); ++w) {
 *           //        buff.r = r;
 *           //        buff.w = w;
 *           //        ptr = lwrb_get_linear_block_write_address(&buff);
 *           //        len = lwrb_get_linear_block_write_length(&buff);
 *           //        printf("W: %3d, R: %3d, LEN: %3d\r\n", (int)w, (int)r, (int)len);
 *           //    }
 *           //}
 *
 *           return 0;
 *       }
 * 
 *     =========================================================
 *     debug 显示信息
 *     =========================================================
 *     [EVT] Buffer write event: 3 byte(s)!
 *     [EVT] Buffer write event: 3 byte(s)!
 *     [EVT] Buffer write event: 2 byte(s)!
 *     [EVT] Buffer read event: 8 byte(s)!
 *     [EVT] Buffer write event: 8 byte(s)!
 *     [EVT] Buffer write event: 1 byte(s)!
 *     [EVT] Buffer write event: 6 byte(s)!
 *     [EVT] Buffer reset event!
 *     =========================================================
 */
#endif /* LWRB_HDR_H */

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐