-------------------------------------------------------------------------------------------------------------------------------------
最近学习一个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");