请选择 进入手机版 | 继续访问电脑版
查看: 927|回复: 0

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

[复制链接]

74

主题

169

帖子

573

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
573
发表于 2019-12-23 09:31:45 | 显示全部楼层 |阅读模式
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字节,则判定缓存池已满。





回复

使用道具 举报

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

本版积分规则

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