查看: 928|回复: 0

[技术交流] Alios之环形缓冲池

[复制链接]

74

主题

169

帖子

573

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
573
发表于 2020-8-3 15:49:33 | 显示全部楼层 |阅读模式
1、前言
ring buffer是一种固定尺寸、头尾相连的缓冲池的数据结构,适合缓存数据流。环形缓冲池多用于两个任务之间传递数据,是标准的先入先出模型。
一般来说,若多个任务之间共享数据需要使用互斥机制来进行同步,以保证共享数据不会发生不可预测的修改与读取,然而互斥机制的使用也会带来额外的系统开销。环形缓冲池的引入就是为了有效解决这个问题,以提高系统资源利用率。
2、初始化与重置
(1)ring buffer初始化
函数原型:kstart_t krhino_ringbuf_init(k_ringbuf_t  *p_ringbuf, void  *buf,  size_t  len,size_t  type,  size_t  block_size)
ring buffer初始化需配置ringbuf的长度、类型、存储元素长度及在内存中实际的存储位置。其中,管理结构体k_ringbuf_t的主要数据成员包括:
buf:ring buffer在内存中的实际开始位置;
end:ring buffer在内存中的实际结束位置;
head:存储在缓冲池中的有效数据的开始位置,即读指针;
tail:存储在缓冲池中的有效数据结尾位置,即写指针;
freesize:标示缓冲池当前剩余可用空间大小;
type:标示缓冲池的内型,“固定长度(RINGBUF_TYPE_FIX)或是可变长度(RINGBUF_TYPE_DYN)”。
block_size:标示存储在缓冲池中的单个数据块长度,只针对RINGBUF_TYPE_FIX有效。
(2)ring buffer重置
函数原型:kstart_t krhino_ring.buf_reset(k_ringbuf_t *p_ringbuf)
ring buffer重置会清除缓冲池中的数据块,并重置ring buffer的读/写指针、剩余可用空间大小。
3、环形缓冲池的写入与读取
(1)ring buffer的写入
函数原型:kstart_t krhino_ringbuf_push(k_ringbuf_t *p_ringbuf, void *data,size_t len)
ring buffer写入的步骤主要包括:
①判断缓冲池是否已满,若已满,则返回RHINO_RINGBUF_FULL错误。
②判断缓冲池的剩余空间能否写入数据块,若不能,则返回RHINO_RINGBUF_FULL错误。
③重新校准缓冲池的写指针及剩余空间大小。
④压入数据块。
ring buffer写入流程如下图所示:
(2)ring buffer的读取
函数原型:kstat_t krhino_ringbuf_pop(k_ringbuf_t   *p_ringbuf,  void  *pdata,  size_t  *plen)
ring buffer读取的步骤包括:
①判断缓冲池是否为空,若为空,则返回RHINO_RINGBUF_EMPTY错误;
②读取数据块;
③校准缓冲池读指针及剩余空间大小。
ring buffer 读取流程如下图所示:
4、环形缓冲池的容量判断
(1)判断ring buffer是否为空
函数原型:uint8_t  krhino_ringbuf_is_empty(k_ringbuf_t  *p_ringbuf)
若缓冲池的剩余空间大小与预设的环形缓冲池长度一致,会判断此时缓冲池为空。
(2)判断ring buffer是否已满
函数原型:uint8_t  krhino_ringbuf_is_full(k_ringbuf_t  *p_ringbuf)
对于RINGBUF_TYPE_FIX类型,若环形缓冲池的剩余空间小于预设的固定数据块长度,则判定缓存池已满。对于RINGBUF_TYPE_DYN类型,若环形缓存区的剩余空间小于8字节,则判定缓存池已满。





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表