Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yunqingabc
rt-thread
提交
c8d85a5c
R
rt-thread
项目概览
yunqingabc
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c8d85a5c
编写于
5月 08, 2013
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #84 from grissiom/ringbuffer
Ringbuffer
上级
1161e7b3
952bc0d4
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
138 addition
and
72 deletion
+138
-72
components/drivers/include/rtdevice.h
components/drivers/include/rtdevice.h
+53
-5
components/drivers/src/ringbuffer.c
components/drivers/src/ringbuffer.c
+85
-67
未找到文件。
components/drivers/include/rtdevice.h
浏览文件 @
c8d85a5c
...
...
@@ -28,16 +28,64 @@ struct rt_completion
rt_list_t
suspended_list
;
};
#define RT_RINGBUFFER_SIZE(rb) ((rb)->write_index - (rb)->read_index)
#define RT_RINGBUFFER_EMPTY(rb) ((rb)->buffer_size - RT_RINGBUFFER_SIZE(rb))
/* ring buffer */
struct
rt_ringbuffer
{
rt_uint16_t
read_index
,
write_index
;
rt_uint8_t
*
buffer_ptr
;
rt_uint16_t
buffer_size
;
/* use the msb of the {read,write}_index as mirror bit. You can see this as
* if the buffer adds a virtual mirror and the pointers point either to the
* normal or to the mirrored buffer. If the write_index has the same value
* with the read_index, but in differenct mirro, the buffer is full. While
* if the write_index and the read_index are the same and within the same
* mirror, the buffer is empty. The ASCII art of the ringbuffer is:
*
* mirror = 0 mirror = 1
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Full
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* read_idx-^ write_idx-^
*
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* read_idx-^ ^-write_idx
*
* The tradeoff is we could only use 32KiB of buffer for 16 bit of index.
* But it should be enough for most of the cases.
*
* Ref: http://en.wikipedia.org/wiki/Circular_buffer#Mirroring */
rt_uint16_t
read_mirror
:
1
;
rt_uint16_t
read_index
:
15
;
rt_uint16_t
write_mirror
:
1
;
rt_uint16_t
write_index
:
15
;
/* as we use msb of index as mirror bit, the size should be signed and
* could only be positive. */
rt_int16_t
buffer_size
;
};
/** return the size of data in rb */
rt_inline
rt_uint16_t
RT_RINGBUFFER_SIZE
(
struct
rt_ringbuffer
*
rb
)
{
if
(
rb
->
read_index
==
rb
->
write_index
)
{
if
(
rb
->
read_mirror
==
rb
->
write_mirror
)
/* we are in the same side, the ringbuffer is empty. */
return
0
;
else
return
rb
->
buffer_size
;
}
else
{
if
(
rb
->
write_index
>
rb
->
read_index
)
return
rb
->
write_index
-
rb
->
read_index
;
else
return
rb
->
buffer_size
-
(
rb
->
read_index
-
rb
->
write_index
);
}
}
/** return the size of empty space in rb */
#define RT_RINGBUFFER_EMPTY(rb) ((rb)->buffer_size - RT_RINGBUFFER_SIZE(rb))
/* pipe device */
#define PIPE_DEVICE(device) ((struct rt_pipe_device*)(device))
struct
rt_pipe_device
...
...
@@ -95,7 +143,7 @@ void rt_completion_done(struct rt_completion *completion);
*/
void
rt_ringbuffer_init
(
struct
rt_ringbuffer
*
rb
,
rt_uint8_t
*
pool
,
rt_
uint16_t
size
);
rt_
int16_t
size
);
rt_size_t
rt_ringbuffer_put
(
struct
rt_ringbuffer
*
rb
,
const
rt_uint8_t
*
ptr
,
rt_uint16_t
length
);
...
...
components/drivers/src/ringbuffer.c
浏览文件 @
c8d85a5c
...
...
@@ -10,6 +10,7 @@
* Change Logs:
* Date Author Notes
* 2012-09-30 Bernard first version.
* 2013-05-08 Grissiom reimplement
*/
#include <rtthread.h>
...
...
@@ -18,12 +19,14 @@
void
rt_ringbuffer_init
(
struct
rt_ringbuffer
*
rb
,
rt_uint8_t
*
pool
,
rt_
uint16_t
size
)
rt_
int16_t
size
)
{
RT_ASSERT
(
rb
!=
RT_NULL
);
RT_ASSERT
(
size
>
0
)
/* initialize read and write index */
rb
->
read_index
=
rb
->
write_index
=
0
;
rb
->
read_mirror
=
rb
->
read_index
=
0
;
rb
->
write_mirror
=
rb
->
write_index
=
0
;
/* set buffer pool and size */
rb
->
buffer_ptr
=
pool
;
...
...
@@ -36,65 +39,44 @@ rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb,
rt_uint16_t
length
)
{
rt_uint16_t
size
;
rt_uint16_t
mask
;
rt_uint16_t
write_position
;
RT_ASSERT
(
rb
!=
RT_NULL
);
mask
=
rb
->
buffer_size
-
1
;
/* whether has enough space */
size
=
rb
->
buffer_size
-
(
rb
->
write_index
-
rb
->
read_index
);
size
=
RT_RINGBUFFER_EMPTY
(
rb
);
/* no space */
if
(
size
==
0
)
return
0
;
/* drop some data */
if
(
size
<
length
)
length
=
size
;
write_position
=
(
rb
->
write_index
&
mask
);
if
(
rb
->
buffer_size
-
write_position
>
length
)
if
(
rb
->
buffer_size
-
rb
->
write_index
>
length
)
{
/* read_index - write_index = empty space */
memcpy
(
&
rb
->
buffer_ptr
[
write_position
],
ptr
,
length
);
}
else
{
memcpy
(
&
rb
->
buffer_ptr
[
write_position
],
ptr
,
rb
->
buffer_size
-
write_position
);
memcpy
(
&
rb
->
buffer_ptr
[
0
],
&
ptr
[
rb
->
buffer_size
-
write_position
],
length
-
(
rb
->
buffer_size
-
write_position
));
memcpy
(
&
rb
->
buffer_ptr
[
rb
->
write_index
],
ptr
,
length
);
/* this should not cause overflow because there is enough space for
* length of data in current mirror */
rb
->
write_index
+=
length
;
return
length
;
}
rb
->
write_index
+=
length
;
return
length
;
}
RTM_EXPORT
(
rt_ringbuffer_put
);
/**
* put a character into ring buffer
*/
rt_size_t
rt_ringbuffer_putchar
(
struct
rt_ringbuffer
*
rb
,
const
rt_uint8_t
ch
)
{
rt_uint16_t
mask
;
RT_ASSERT
(
rb
!=
RT_NULL
);
/* whether has enough space */
mask
=
rb
->
buffer_size
-
1
;
/* whether has enough space */
if
(
rb
->
write_index
-
rb
->
read_index
==
rb
->
buffer_size
)
return
0
;
memcpy
(
&
rb
->
buffer_ptr
[
rb
->
write_index
],
&
ptr
[
0
],
rb
->
buffer_size
-
rb
->
write_index
);
memcpy
(
&
rb
->
buffer_ptr
[
0
],
&
ptr
[
rb
->
buffer_size
-
rb
->
write_index
],
length
-
(
rb
->
buffer_size
-
rb
->
write_index
));
/*
put characte
r */
rb
->
buffer_ptr
[
rb
->
write_index
&
mask
]
=
ch
;
rb
->
write_index
+=
1
;
/*
we are going into the other side of the mirro
r */
rb
->
write_mirror
=
~
rb
->
write_mirror
;
rb
->
write_index
=
length
-
(
rb
->
buffer_size
-
rb
->
write_index
)
;
return
1
;
return
length
;
}
RTM_EXPORT
(
rt_ringbuffer_put
char
);
RTM_EXPORT
(
rt_ringbuffer_put
);
/**
* get data from ring buffer
...
...
@@ -104,62 +86,98 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
rt_uint16_t
length
)
{
rt_size_t
size
;
rt_uint16_t
mask
;
rt_uint16_t
read_position
;
RT_ASSERT
(
rb
!=
RT_NULL
);
/* whether has enough data */
mask
=
rb
->
buffer_size
-
1
;
size
=
rb
->
write_index
-
rb
->
read_index
;
size
=
RT_RINGBUFFER_SIZE
(
rb
);
/* no data */
if
(
size
==
0
)
return
0
;
/* less data */
if
(
size
<
length
)
length
=
size
;
read_position
=
rb
->
read_index
&
mask
;
if
(
rb
->
buffer_size
-
read_position
>=
length
)
if
(
rb
->
buffer_size
-
rb
->
read_index
>
length
)
{
/* copy all of data */
memcpy
(
ptr
,
&
rb
->
buffer_ptr
[
read_position
],
length
);
memcpy
(
ptr
,
&
rb
->
buffer_ptr
[
rb
->
read_index
],
length
);
/* this should not cause overflow because there is enough space for
* length of data in current mirror */
rb
->
read_index
+=
length
;
return
length
;
}
memcpy
(
&
ptr
[
0
],
&
rb
->
buffer_ptr
[
rb
->
read_index
],
rb
->
buffer_size
-
rb
->
read_index
);
memcpy
(
&
ptr
[
rb
->
buffer_size
-
rb
->
read_index
],
&
rb
->
buffer_ptr
[
0
],
length
-
(
rb
->
buffer_size
-
rb
->
read_index
));
/* we are going into the other side of the mirror */
rb
->
read_mirror
=
~
rb
->
read_mirror
;
rb
->
read_index
=
length
-
(
rb
->
buffer_size
-
rb
->
read_index
);
return
length
;
}
RTM_EXPORT
(
rt_ringbuffer_get
);
/**
* put a character into ring buffer
*/
rt_size_t
rt_ringbuffer_putchar
(
struct
rt_ringbuffer
*
rb
,
const
rt_uint8_t
ch
)
{
RT_ASSERT
(
rb
!=
RT_NULL
);
/* whether has enough space */
if
(
!
RT_RINGBUFFER_EMPTY
(
rb
))
return
0
;
rb
->
buffer_ptr
[
rb
->
write_index
]
=
ch
;
/* flip mirror */
if
(
rb
->
write_index
==
rb
->
buffer_size
-
1
)
{
rb
->
write_mirror
=
~
rb
->
write_mirror
;
rb
->
write_index
=
0
;
}
else
{
/* copy first and second */
memcpy
(
ptr
,
&
rb
->
buffer_ptr
[
read_position
],
rb
->
buffer_size
-
read_position
);
memcpy
(
&
ptr
[
rb
->
buffer_size
-
read_position
],
&
rb
->
buffer_ptr
[
0
],
length
-
rb
->
buffer_size
+
read_position
);
rb
->
write_index
++
;
}
rb
->
read_index
+=
length
;
return
length
;
return
1
;
}
RTM_EXPORT
(
rt_ringbuffer_
get
);
RTM_EXPORT
(
rt_ringbuffer_
putchar
);
/**
* get a character from a ringbuffer
*/
rt_size_t
rt_ringbuffer_getchar
(
struct
rt_ringbuffer
*
rb
,
rt_uint8_t
*
ch
)
{
rt_uint16_t
mask
;
RT_ASSERT
(
rb
!=
RT_NULL
);
/* ringbuffer is empty */
if
(
rb
->
read_index
==
rb
->
write_index
)
if
(
!
RT_RINGBUFFER_SIZE
(
rb
)
)
return
0
;
mask
=
rb
->
buffer_size
-
1
;
/* put character */
*
ch
=
rb
->
buffer_ptr
[
rb
->
read_index
&
mask
];
rb
->
read_index
+=
1
;
*
ch
=
rb
->
buffer_ptr
[
rb
->
read_index
];
if
(
rb
->
read_index
==
rb
->
buffer_size
-
1
)
{
rb
->
read_mirror
=
~
rb
->
read_mirror
;
rb
->
read_index
=
0
;
}
else
{
rb
->
read_index
++
;
}
return
1
;
}
RTM_EXPORT
(
rt_ringbuffer_getchar
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录