Files
luban-lite/packages/third-party/cherryusb/third_party/cherryrb/README_zh.md

200 lines
5.0 KiB
Markdown
Raw Normal View History

2025-04-23 17:54:31 +08:00
# CherryRingBuffer
[English](./README.md)
CherryRingBuffer 是一个的高效、易用的环形缓冲区其原理与kfifo一致。
## 简介
### 1.创建并初始化一个RingBuffer
```c
chry_ringbuffer_t rb;
uint8_t mempool[1024];
int main(void)
{
/**
* 需要注意的点是init 函数第三个参数是内存池的大小(字节为单位)
* 也是ringbuffer的深度必须为 2 的幂次!!!。
* 例如 4、16、32、64、128、1024、8192、65536等
*/
if(0 == chry_ringbuffer_init(&rb, mempool, 1024)){
printf("success\r\n");
}else{
printf("error\r\n");
}
return 0;
}
```
### 2.生产者消费者模型的无锁使用
读和写的API除了overwrite外如果满足ringbuffer只在一个线程里进行读并且只在一个线程里面写那么无须加锁因为读和写操作只单独操作读或者写指针。
```c
void thread_producer(void* param)
{
char *data = "hello world";
while(1){
uint32_t len = chry_ringbuffer_write(&rb, data, 11);
if(11 == len){
printf("[P] write success\r\n");
}else{
printf("[P] write faild, only write %d byte\r\n", len);
}
vTaskDelay(100);
}
}
void thread_consumer(void* param)
{
char data[1024];
while(1){
uint32_t len =chry_ringbuffer_read(&rb, data, 11);
if (len){
printf("[C] read success, read %d byte\r\n",len);
data[11]='\0';
printf("%s\r\n",data);
}else{
printf("[C] read faild, no data in ringbuffer\r\n");
}
vTaskDelay(100);
}
}
```
### 3. API简介
```c
/**
* 用于清空,同时操作读写指针,多线程需要加锁
*/
chry_ringbuffer_reset(&rb);
/**
* 用于清空,只操作读指针,在唯一的读线程调用无须加锁
*/
chry_ringbuffer_reset_read(&rb);
/**
* 获取ringbuffer总大小字节
*/
uint32_t size = chry_ringbuffer_get_size(&rb);
/**
* 获取ringbuffer使用大小字节
*/
uint32_t used = chry_ringbuffer_get_used(&rb);
/**
* 获取ringbuffer空闲大小字节
*/
uint32_t free = chry_ringbuffer_get_free(&rb);
/**
* 检查ringbuffer是否为满满返回true
*/
bool is_full = chry_ringbuffer_check_full(&rb);
/**
* 检查ringbuffer是否为空空返回true
*/
bool is_empty = chry_ringbuffer_check_empty(&rb);
uint8_t data = 0x55;
/**
* 写一字节
* 在唯一的写线程调用无须加锁
* 写成功返回true满返回false
*/
chry_ringbuffer_write_byte(&rb, data);
/**
* 覆盖写一字节当ringbuffer满的时候会覆盖最早的数据
* 非满情况与 chry_ringbuffer_write_byte 一致。
* 此API可能会同时操作读写指针所以多线程需要加锁
* 始终返回true
*/
chry_ringbuffer_overwrite_byte(&rb, data);
/**
* 从ringbuffer中复制出来一字节
* 数据仍然保留在ringbuffer中
* 在唯一的读线程调用无须加锁
* 成功返回true空返回false
*/
chry_ringbuffer_peek_byte(&rb, &data);
/**
* 从ringbuffer中读取出来一字节
* 数据从ringbuffer中取出
* 在唯一的读线程调用无须加锁
* 成功返回true空返回false
*/
chry_ringbuffer_read_byte(&rb, &data);
/**
* 丢弃ringbuffer中一字节
* 数据从ringbuffer中取出
* 在唯一的读线程调用无须加锁
* 成功返回true空返回false
*/
chry_ringbuffer_drop_byte(&rb);
/**
* 写多字节,其他与单字节写相同
* 返回实际写入的长度
*/
chry_ringbuffer_write(&rb, data, 1);
/**
* 覆盖写多字节,其他与单字节覆盖写相同
* 返回实际写入的长度
*/
chry_ringbuffer_overwrite(&rb, data, 1);
/**
* 复制多字节,其他与单字节复制相同
* 返回实际复制的长度
*/
chry_ringbuffer_peek(&rb, data, 1);
/**
* 读取多字节,其他与单字节读取相同
* 返回实际读取的长度
*/
chry_ringbuffer_read(&rb, data, 1);
/**
* 丢弃多字节,其他与单字节丢弃相同
* 返回实际丢弃的长度
*/
chry_ringbuffer_drop(&rb, 1);
void *pdata;
uint32_t size;
/**
* 用于启动DMA获取读取起始内存地址和最大线性可读取长度
*/
pdata = chry_ringbuffer_linear_read_setup(&rb, &size);
/**
* 用于DMA完成增加读指针
* 返回实际增加长度
*/
size = chry_ringbuffer_linear_read_done(&rb, 512);
/**
* 用于启动DMA获取写入起始内存地址和最大线性可写入长度
*/
pdata = chry_ringbuffer_linear_write_setup(&rb, &size);
/**
* 用于DMA完成增加写指针
* 返回实际增加长度
*/
size = chry_ringbuffer_linear_write_done(&rb, 512);
```