CherryRingBuffer 是一个的高效、易用的环形缓冲区,其原理与kfifo一致。
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;
}
读和写的API除了overwrite外,如果满足ringbuffer只在一个线程里进行读,并且只在一个线程里面写,那么无须加锁,因为读和写操作只单独操作读或者写指针。
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);
}
}
/**
* 用于清空,同时操作读写指针,多线程需要加锁
*/
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);