其他
杰杰带你解读【机智云】环形缓冲区源码
前言
大家晚上好,我是杰杰,上个星期,研究了一下机智云的源码,也不能说是研究吧,就是看了看,人家既然能拿来做商业用,还是有很厉害的地方的,如果还不知道什么叫环形缓冲区(环形队列)的同学,请看——STM32进阶之串口环形缓冲区实现
好啦。多余的话不多说,看看他们的东西比我写的好在哪吧,原理都是一样的,但是效率会比我的搞,可能应用的地方也不一样,所以,先看看吧。
ringbuffer.h
先看看头文件:ringbuffer.h。
主要是用宏实现了一个求最小值的函数。
还有就是定义了一个环形缓冲区的结构体。
typedef struct {
size_t rbCapacity;
uint8_t *rbHead;
uint8_t *rbTail;
uint8_t *rbBuff;
}rb_t;
看英文就能知道意思了,rb是ringbuff的缩写,意思就是环形缓冲区,
结构体中rbCapacity是缓冲区的容量,也就是大小。
结构体中rbHead是缓冲区的头指针,
rbTail是缓冲区的尾指针,
而rBuff是缓冲区的首地址,在创建的时候就用到。
ringbuffer.c
环形缓冲区的创建
下面来看看源文件:
int8_t ICACHE_FLASH_ATTR rbCreate(rb_t* rb)
{
if(NULL == rb)
{
return -1;
}
rb->rbHead = rb->rbBuff;
rb->rbTail = rb->rbBuff;
return 0;
}
环形缓冲区的删除
int8_t ICACHE_FLASH_ATTR rbDelete(rb_t* rb)
{
if(NULL == rb)
{
return -1;
}
rb->rbBuff = NULL;
rb->rbHead = NULL;
rb->rbTail = NULL;
rb->rbCapacity = 0;
return 0;
}
int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb)
{
if(NULL == rb)
{
return -1;
}
return rb->rbCapacity;
}
获取环形缓冲区的容量
int32_t ICACHE_FLASH_ATTR rbCapacity(rb_t *rb)
{
if(NULL == rb)
{
return -1;
}
return rb->rbCapacity;
}
环形缓冲区可读数据大小
int32_t ICACHE_FLASH_ATTR rbCanRead(rb_t *rb)
{
if(NULL == rb)
{
return -1;
}
if (rb->rbHead == rb->rbTail)
{
return 0;
}
if (rb->rbHead < rb->rbTail)
{
return rb->rbTail - rb->rbHead;
}
return rbCapacity(rb) - (rb->rbHead - rb->rbTail);
}
获取环形缓冲区可写数据大小
int32_t ICACHE_FLASH_ATTR rbCanWrite(rb_t *rb)
{
if(NULL == rb)
{
return -1;
}
return rbCapacity(rb) - rbCanRead(rb);
}
环形缓冲区读数据
int32_t ICACHE_FLASH_ATTR rbRead(rb_t *rb, void *data, size_t count)
{
int32_t copySz = 0;
if(NULL == rb)
{
return -1;
}
if(NULL == data)
{
return -1;
}
if (rb->rbHead < rb->rbTail)
{
copySz = min(count, rbCanRead(rb));
memcpy(data, rb->rbHead, copySz);
rb->rbHead += copySz;
return copySz;
}
else
{
if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))
{
copySz = count;
memcpy(data, rb->rbHead, copySz);
rb->rbHead += copySz;
return copySz;
}
else
{
copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);
memcpy(data, rb->rbHead, copySz);
rb->rbHead = rb->rbBuff;
copySz += rbRead(rb, (char*)data+copySz, count-copySz);
return copySz;
}
}
}
copySz = count;
memcpy(data, rb->rbHead, copySz);
rb->rbHead += copySz;
copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);
memcpy(data, rb->rbHead, copySz);
rb->rbHead = rb->rbBuff;
copySz += rbRead(rb, (char*)data+copySz, count-copySz);
环形缓冲区写数据
int32_t ICACHE_FLASH_ATTR rbWrite(rb_t *rb, const void *data, size_t count)
{
int32_t tailAvailSz = 0;
if((NULL == rb)||(NULL == data))
{
return -1;
}
if (count >= rbCanWrite(rb))
{
return -2;
}
if (rb->rbHead <= rb->rbTail)
{
tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);
if (count <= tailAvailSz)
{
memcpy(rb->rbTail, data, count);
rb->rbTail += count;
if (rb->rbTail == rb->rbBuff+rbCapacity(rb))
{
rb->rbTail = rb->rbBuff;
}
return count;
}
else
{
memcpy(rb->rbTail, data, tailAvailSz);
rb->rbTail = rb->rbBuff;
return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
}
}
else
{
memcpy(rb->rbTail, data, count);
rb->rbTail += count;
return count;
}
}
else
{
memcpy(rb->rbTail, data, count);
rb->rbTail += count;
return count;
}
memcpy(rb->rbTail, data, count);
rb->rbTail += count;
if (rb->rbTail == rb->rbBuff+rbCapacity(rb))
{
rb->rbTail = rb->rbBuff;
}
memcpy(rb->rbTail, data, tailAvailSz);
rb->rbTail = rb->rbBuff;
return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
END
【连载】从单片机到操作系统⑤——FreeRTOS列表&列表项的源码解读
【连载】从单片机到操作系统⑥——FreeRTOS任务切换机制详解
欢迎大家一起来讨论操作系统的知识
我们的群号是:783234154
杰杰:
创客飞梦空间是开源公众号
如果喜欢我的文章,那就关注我吧
也欢迎大家投稿