專案地址:ring buffer
documentation:LwRB latest-develop documentation
Features
- Written in ANSI C99, compatible with
size_tfor 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)
專案檔案目錄如下

實體代碼
首先我們用幫助檔案中的Example code來測驗一下是否可以正常使用,修改main.c
#include <stdio.h>
#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);
}
}

發現是可以正常編譯運行的,說明我們可以使用這個開源庫了,
在這個環形緩沖庫中存在一個單元測驗模塊,單元測驗使用的是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單元測驗框架的三個檔案加入到我們的專案中

將main.c函式修改成test.c中的內容
/**
* @file test.c
*
* Unit tests for the lwrb library
*
* @author Tofik Sonono (tofik@sonono.me)
*
*/
/*======= Includes ==========================================================*/
#include <stdint.h>
#include <stdlib.h>
#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);
}
運行之后

可以看到,我們測驗的函式都通過了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291573.html
標籤:其他
下一篇:Unity協程——簡單應用
