环形缓冲区FIFO

发布时间 2023-11-30 09:49:38作者: zyl4444

-------------------------------------------------------------------------------------------------------------------------------------

 

最近学习一个LwRB开源环形缓冲区FIFO设计,即先入先出缓冲区。LwRB 是一个开源、通用环形缓冲区库。
    1、只有单个任务写和单个任务读时,线程是安全的
    2、只有单个中断写和单个中断读时,中断是安全的
    3、支持内存间的 DMA 操作,实现缓冲区和应用程序内存之间零拷贝
    4、对于读数据,提供 peek(窥读,读数据但不改变读指针) 、skip (跳读,向前移动读指针,将指定长度的数据标记为已读)函数,
    5、对于写数据,提供 advance (跳写,向前移动写指针,比如 DMA 硬件向环形缓冲区写入了 10 字节,应用程序需要调用此函数更新写指针)函数。
    6、支持事件通知

具体的设计思路和原理图,可以观看这篇转载的博客:https://blog.csdn.net/zhzht19861011/article/details/126524101?spm=1001.2014.3001.5506

这里通过一些程序,简单介绍这个环形缓冲区的具体使用过程:

 

 

// 写入数据到循环缓冲区
            size_t writeBytes = lwrb_write(&KEY_buff, "0123456789", 10);  //向循环缓冲区 KEY_buff 写入字符串 “0123456789” 数据
            printf("写入数据大小:%d\r\n", (int)writeBytes);

            // 获取缓冲区中已存储的数据大小
            size_t full_data = lwrb_get_full(&KEY_buff);
            printf("已存储数据大小: %d\r\n", (int)full_data); //打印已经存储缓冲区中的大小

            //lwrb_read 函数读取数据后会移动读指针,也就是读取数据后,环形缓冲区会将这些数据移除掉
            uint8_t readData[BUFFER_SIZE];
            size_t readBytes = lwrb_read(&KEY_buff, readData, 5);  //从缓冲区中读取的字节数为5
            printf("读取数据大小:%d\r\n", (int)readBytes);
            printf("read_data: ");
            for (int i = 0; i < readBytes; i++)
            {
                printf("%c", readData[i]); //打印读出的数据
            }
            printf("\n");

            // lwrb_peek() 函数用于查看循环缓冲区 KEY_buff 中的数据,不改变缓冲区中的数据位置
            uint8_t peekData[BUFFER_SIZE];
            size_t peekBytes = lwrb_peek(&KEY_buff, 2, peekData, BUFFER_SIZE); //在BUFFER_SIZE缓冲区中从索引2开始查看
            printf("查看数据大小:%d\r\n", (int)peekBytes);
            printf("Peek_data: ");
            for (int i = 0; i < peekBytes; i++)
            {
                printf("%c", peekData[i]);
            }
            printf("\n");

            //lwrb_skip() 函数用于跳过循环缓冲区 KEY_buff 中的数据
            size_t skipBytes = lwrb_skip(&KEY_buff, 4); // 跳过 4 个字节
            printf("跳过数据data:%d\r\n", (int)skipBytes);

            // 获取缓冲区中已存储的数据大小
            full_data = lwrb_get_full(&KEY_buff);
            printf("再一次已存储数据大小: %d\r\n", (int)full_data);

            // 再次读取数据
            size_t readBytes2 = lwrb_read(&KEY_buff, readData, BUFFER_SIZE);
            printf("再一次读取数据大小:%d\r\n", (int)readBytes2);
            printf("data2: ");
            for (int i = 0; i < readBytes2; i++)
            {
                printf("%c", readData[i]);  //打印读出缓冲区中跳过4个字节后的数据
            }
            printf("\n");