作者:继续微笑丶保持硪的骄傲_195 | 来源:互联网 | 2023-08-06 11:37
项目地址:ring buffer
documentation:LwRB latest-develop documentation
Features
- Written in ANSI C99, compatible with
size_t
for size data types - Platform independent, no architecture specific code
- FIFO (First In First Out) buffer implementation
- No dynamic memory allocation, data is static array
- Uses optimized memory copy instead of loops to read/write data from/to memory
- Thread safe when used as pipe with single write and single read entries
- Interrupt safe when used as pipe with single write and single read entries
- Suitable for DMA transfers from and to memory with zero-copy overhead between buffer and application memory
- Supports data peek, skip for read and advance for write
- Implements support for event notifications
- User friendly MIT license
该库其实只依赖两个文件:lwrb.c 和 lwrb.h (之前文件名是ringbuff.c和ringbuff.h,不知道为什么又改了文件名和函数名)
我们只需要将这两个文件添加到我们的项目中即可。不过注意要改一下lwrb.c中的头文件包含
#include "lwrb/lwrb.h" 改成 #include "lwrb.h"
因为CLion使用cmake来管理的,我们还要在CMakeLists.txt中添加lwrb.c
cmake_minimum_required(VERSION 3.21)
project(ringbuffer_clion C)set(CMAKE_C_STANDARD 99)add_executable(ringbuffer_clion main.c lwrb.c)
项目文件目录如下
![image-20210730191407449](https://img4.php1.cn/3cdc5/6633/5a0/2cd697de8eb4462f.png)
实例代码
首先我们用帮助文档中的Example code来测试一下是否可以正常使用,修改main.c
#include
#include "lwrb.h"int main() {/* Declare rb instance & raw data */lwrb_t buff;uint8_t buff_data[8];/* Application variables */uint8_t data[2];size_t len;/* Application code ... */lwrb_init(&buff, buff_data, sizeof(buff_data)); /* Initialize buffer *//* Write 4 bytes of data */lwrb_write(&buff, "0123", 4);/* Try to read buffer *//* len holds number of bytes read *//* Read until len == 0, when buffer is empty */while ((len = lwrb_read(&buff, data, sizeof(data))) > 0) {printf("Successfully read %d bytes\r\n", (int)len);}
}
![image-20210730191431168](https://img4.php1.cn/3cdc5/6633/5a0/17a53550ab581660.png)
发现是可以正常编译运行的,说明我们可以使用这个开源库了。
在这个环形缓冲库中存在一个单元测试模块,单元测试使用的是Unity测试框架。
Unity测试框架GitHub地址:Unity
Unity学习教程:Unity单元测试框架、C单元测试Unity
Unity是一个单元测试框架,Unity设计者团队的目标是让它保持小型化和功能性。核心的Unity测试框架只有三个文件:单个C文件和两个头文件。Unity提供了函数和宏,使得单元测试更加容易。
Unity被设计成跨平台,它努力坚持C标准,同时仍然支持许多违法规则的嵌入式C编译器。Unity可以在许多编译器环境中使用,比如GCC,IAR,Clang,Green Hills,Microchip, MS Visual Studio。适配Unity在一个新的目标平台协同工作并不需要很多工作量。
我们将Unity单元测试框架的三个文件加入到我们的项目中
![image-20210730224842908](https://img4.php1.cn/3cdc5/6633/5a0/c3acef132465e231.png)
将main.c函数修改成test.c中的内容
/*** @file test.c** Unit tests for the lwrb library** @author Tofik Sonono (tofik@sonono.me)**//*======= Includes ==========================================================*/#include
#include
#include "unity.h"
#include "lwrb.h"/*======= Local Macro DefinitiOns===========================================*/
/*======= Local function prototypes =========================================*/void basic_read_and_write(lwrb_t *buff, uint8_t *data_to_write, size_t data_size);/*======= Local variable declaratiOns=======================================*/
/*======= Global function implementatiOns===================================*//* Requires a definition for Unity to compile */void setUp(void) { }void tearDown(void) { }/*======= Tests ==============================================================*/void testNullInputToInit_should_fail(void) {uint8_t ret;lwrb_t buff = { 0 };uint8_t buff_data[1];ret = lwrb_init(NULL, buff_data, sizeof(buff_data));TEST_ASSERT_EQUAL(0, ret);ret = lwrb_init(&buff, NULL, sizeof(buff_data));TEST_ASSERT_EQUAL(0, ret);ret = lwrb_init(&buff, buff_data, 0);TEST_ASSERT_EQUAL(0, ret);ret = lwrb_is_ready(&buff);TEST_ASSERT_EQUAL(0, ret);
}void testNormalInputToInit_should_succeed(void) {uint8_t ret;lwrb_t buff = { 0 };uint8_t buff_data[1];ret = lwrb_init(&buff, buff_data, sizeof(buff_data));TEST_ASSERT_EQUAL(1, ret);ret = lwrb_is_ready(&buff);TEST_ASSERT_EQUAL(1, ret);
}void testAddElementsToQueueAndRead_should_succeed(void) {uint8_t data_to_write[] = {0, 1, 2, 3, 4, 5, 6, 7};lwrb_t buff = { 0 };basic_read_and_write(&buff, data_to_write, sizeof(data_to_write));
}void testAddElementsToQueueAndReadAndVerifyEmpty_should_succeed(void) {uint8_t data_to_write[] = {0, 1, 2, 3, 4, 5, 6, 7};lwrb_t buff = { 0 };basic_read_and_write(&buff, data_to_write, sizeof(data_to_write));size_t n_free_bytes = lwrb_get_free(&buff);TEST_ASSERT_EQUAL(sizeof(data_to_write), n_free_bytes);
}void testAddElementsToQueueAndReadTooSmallBuffer_should_fail(void) {uint8_t data_to_write[] = {0, 1, 2, 3, 4, 5, 6, 7};lwrb_t buff = { 0 };uint8_t ret;uint8_t buff_data[sizeof(data_to_write)];ret = lwrb_init(&buff, buff_data, sizeof(buff_data));TEST_ASSERT_EQUAL(1, ret);ret = lwrb_is_ready(&buff);TEST_ASSERT_EQUAL(1, ret);size_t n_written = lwrb_write(&buff, data_to_write, sizeof(data_to_write));TEST_ASSERT_EQUAL(sizeof(data_to_write) - 1, n_written);
}/*======= Main ===============================================================*/int main (void) {UNITY_BEGIN();RUN_TEST(testNullInputToInit_should_fail);RUN_TEST(testNormalInputToInit_should_succeed);RUN_TEST(testAddElementsToQueueAndRead_should_succeed);RUN_TEST(testAddElementsToQueueAndReadAndVerifyEmpty_should_succeed);RUN_TEST(testAddElementsToQueueAndReadTooSmallBuffer_should_fail);return UNITY_END();
}/*======= Local function implementatiOns=====================================*/void basic_read_and_write(lwrb_t *buff, uint8_t *data_to_write, size_t data_size) {uint8_t ret;size_t buffer_size = (sizeof(uint8_t) * data_size) + 1;uint8_t *buff_data = malloc(buffer_size);ret = lwrb_init(buff, buff_data, buffer_size);TEST_ASSERT_EQUAL(1, ret);ret = lwrb_is_ready(buff);TEST_ASSERT_EQUAL(1, ret);size_t n_written = lwrb_write(buff, data_to_write, sizeof(data_to_write));TEST_ASSERT_EQUAL(sizeof(data_to_write), n_written);size_t n_bytes_in_queue = lwrb_get_full(buff);TEST_ASSERT_EQUAL(n_written, n_bytes_in_queue);uint8_t read_buffer[sizeof(data_to_write)];size_t n_read = lwrb_read(buff, read_buffer, n_bytes_in_queue);TEST_ASSERT_EQUAL(n_bytes_in_queue, n_read);TEST_ASSERT_EQUAL_UINT8_ARRAY(data_to_write, read_buffer, sizeof(data_to_write));free(buff_data);
}
运行之后
![image-20210730225027192](https://img4.php1.cn/3cdc5/6633/5a0/a42e492666d40e88.png)
可以看到,我们测试的函数都通过了。