ringbuffer
- buffer_ptr 是指向缓冲区的指针,buffer_size 是缓冲区的大小,read_index 是读索引,write_index 是写索引,而 read_mirror 和 write_mirror 可以理解为一种镜像值,每次向缓冲区写入数据,碰到缓冲区末尾时,切换到另一个镜像的缓冲区头部写入剩余数据。这种镜像操作可用于判断缓冲区内数据是满还是空。
等于是把缓冲区回绕了看做为另一个缓冲区,通过镜像值来判断缓冲区的状态,当前读写指针是否进入到另一个缓冲区中;
- 当 write_index == read_index 且 read_mirror == write_mirror 时,缓冲区内数据为空。
- 当 write_index == read_index 且 read_mirror != write_mirror 时,缓冲区内数据已满。
- 若是没有上述镜像值,我们就没有办法区分缓冲区空和缓冲区满这两种情况。
- 注意:RT-Thread 的 ringbuffer 组件并未提供线程阻塞的功能,因此 ringbuffer 本质上是一个全局共享的对象,多线程使用时注意使用互斥锁保护。
写入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
if (rb->buffer_size - rb->write_index > length)
{
rt_memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
rb->write_index += length;
return length;
}
rt_memcpy(&rb->buffer_ptr[rb->write_index],
&ptr[0],
rb->buffer_size - rb->write_index);
rt_memcpy(&rb->buffer_ptr[0],
&ptr[rb->buffer_size - rb->write_index],
length - (rb->buffer_size - rb->write_index));
rb->write_mirror = ~rb->write_mirror;
rb->write_index = length - (rb->buffer_size - rb->write_index);
|
读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
if (rb->buffer_size - rb->read_index > length)
{
rt_memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
rb->read_index += length;
return length;
}
rt_memcpy(&ptr[0],
&rb->buffer_ptr[rb->read_index],
rb->buffer_size - rb->read_index);
rt_memcpy(&ptr[rb->buffer_size - rb->read_index],
&rb->buffer_ptr[0],
length - (rb->buffer_size - rb->read_index));
rb->read_mirror = ~rb->read_mirror;
rb->read_index = length - (rb->buffer_size - rb->read_index);
|
判断数据长度及状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| rt_size_trt_ringbuffer_data_len(struct rt_ringbuffer *rb)
{
switch (rt_ringbuffer_status(rb))
{
case RT_RINGBUFFER_EMPTY:
return0;
case RT_RINGBUFFER_FULL:
returnrb->buffer_size;
case RT_RINGBUFFER_HALFFULL:
default:
{
rt_size_t wi = rb->write_index, ri = rb->read_index;
if (wi > ri)
return wi - ri;
else
returnrb->buffer_size - (ri - wi);
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| rt_inline enum rt_ringbuffer_state rt_ringbuffer_status(struct rt_ringbuffer *rb)
{
if (rb->read_index == rb->write_index)
{
if (rb->read_mirror == rb->write_mirror)
return RT_RINGBUFFER_EMPTY;
else
return RT_RINGBUFFER_FULL;
}
return RT_RINGBUFFER_HALFFULL;
}
|