diff options
| author | [email protected] <[email protected]> | 2012-09-30 07:33:13 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-09-30 07:33:13 +0000 |
| commit | 4f05dd5426c277cd1b14f7d20f678983f88b2c0a (patch) | |
| tree | 8056c39a8fda068c56375b7f3c4a7c647225726f /components/drivers/src/ringbuffer.c | |
| parent | 5064df210f29ef0e8e83011a007bbb28983a42dd (diff) | |
Add pipe, data queue implementation; Fix the issue which leaks one item in the available data of ring buffer.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2313 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/drivers/src/ringbuffer.c')
| -rw-r--r-- | components/drivers/src/ringbuffer.c | 119 |
1 files changed, 53 insertions, 66 deletions
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c index 80606469af..cc6484aed8 100644 --- a/components/drivers/src/ringbuffer.c +++ b/components/drivers/src/ringbuffer.c @@ -1,3 +1,17 @@ +/*
+ * File : ringbuffer.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2012-09-30 Bernard first version.
+ */
+
#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
@@ -13,71 +27,64 @@ void rt_ringbuffer_init(struct rt_ringbuffer* rb, rt_uint8_t *pool, rt_uint16_t rb->buffer_ptr = pool;
rb->buffer_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
}
+RTM_EXPORT(rt_ringbuffer_init);
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer* rb, const rt_uint8_t *ptr, 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) & mask);
+ size = rb->buffer_size - (rb->write_index - rb->read_index);
/* no space */
if (size == 0) return 0;
/* drop some data */
if (size < length) length = size;
- if (rb->read_index > rb->write_index)
+ write_position = (rb->write_index & mask);
+ if (rb->buffer_size - write_position> length)
{
/* read_index - write_index = empty space */
- memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
- rb->write_index += length;
+ memcpy(&rb->buffer_ptr[write_position], ptr, length);
}
else
{
- if (rb->buffer_size - rb->write_index >= length)
- {
- /* there is enough space after write_index */
- memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
- rb->write_index = (rb->write_index + length) & mask;
- }
- else
- {
- memcpy(&rb->buffer_ptr[rb->write_index], ptr,
- 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));
- rb->write_index = length - (rb->buffer_size - rb->write_index);
- }
+ 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));
}
+ 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 next;
rt_uint16_t mask;
RT_ASSERT(rb != RT_NULL);
/* whether has enough space */
mask = rb->buffer_size - 1;
- next = (rb->write_index + 1) & mask;
-
- if (next == rb->read_index) return 0;
+
+ /* whether has enough space */
+ if (rb->write_index - rb->read_index == rb->buffer_size) return 0;
/* put character */
- rb->buffer_ptr[rb->write_index] = ch;
- rb->write_index = next;
+ rb->buffer_ptr[rb->write_index & mask] = ch;
+ rb->write_index += 1;
return 1;
}
+RTM_EXPORT(rt_ringbuffer_putchar);
/**
* get data from ring buffer
@@ -86,47 +93,42 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer* rb, rt_uint8_t *ptr, rt_uint16 {
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) & mask;
+ size = rb->write_index - rb->read_index;
/* no data */
if (size == 0) return 0;
/* less data */
if (size < length) length = size;
- if (rb->read_index > rb->write_index)
+ read_position = rb->read_index & mask;
+ if (rb->buffer_size - read_position >= length)
{
- if (rb->buffer_size - rb->read_index >= length)
- {
- /* copy directly */
- memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
- rb->read_index = (rb->read_index + length) & mask;
- }
- else
- {
- /* copy first and second */
- memcpy(ptr, &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);
- rb->read_index = length - rb->buffer_size + rb->read_index;
- }
+ /* copy all of data */
+ memcpy(ptr, &rb->buffer_ptr[read_position], length);
}
else
{
- memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
- rb->read_index += length;
+ /* 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->read_index += length;
return length;
}
+RTM_EXPORT(rt_ringbuffer_get);
+/**
+ * get a character from a ringbuffer
+ */
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer* rb, rt_uint8_t *ch)
{
- rt_uint16_t next;
rt_uint16_t mask;
RT_ASSERT(rb != RT_NULL);
@@ -134,40 +136,25 @@ rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer* rb, rt_uint8_t *ch) /* ringbuffer is empty */
if (rb->read_index == rb->write_index) return 0;
- /* whether has data */
mask = rb->buffer_size - 1;
- next = (rb->read_index + 1) & mask;
/* put character */
- *ch = rb->buffer_ptr[rb->read_index];
- rb->read_index = next;
+ *ch = rb->buffer_ptr[rb->read_index & mask];
+ rb->read_index += 1;
return 1;
}
+RTM_EXPORT(rt_ringbuffer_getchar);
/**
* get available data size
*/
-rt_size_t rt_ringbuffer_available_size(struct rt_ringbuffer* rb)
+rt_size_t rt_ringbuffer_get_datasize(struct rt_ringbuffer* rb)
{
- rt_size_t size;
- rt_uint16_t mask;
-
RT_ASSERT(rb != RT_NULL);
- mask = rb->buffer_size - 1;
- size = (rb->write_index - rb->read_index) & mask;
-
/* return the available size */
- return size;
+ return rb->write_index - rb->read_index;
}
+RTM_EXPORT(rt_data_queue_reset);
-/**
- * get empty space size
- */
-rt_size_t rt_ringbuffer_emptry_size(struct rt_ringbuffer* rb)
-{
- RT_ASSERT(rb != RT_NULL);
-
- return rb->buffer_size - rt_ringbuffer_available_size(rb);
-}
|
