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 o