mirror of
https://github.com/apache/nuttx.git
synced 2026-09-22 06:04:28 +08:00
driver/sensor rc: use mm/circbuf manage intermediate buffer
N/A Change-Id: Ifdd8117da9d20ac2f48f04b7b383449e6dd03f06 Signed-off-by: dongjiuzhu <dongjiuzhu1@xiaomi.com>
This commit is contained in:
+17
-116
@@ -30,6 +30,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mm/circbuf.h>
|
||||
#include <nuttx/rc/lirc_dev.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -56,23 +57,13 @@ struct lirc_upperhalf_s
|
||||
uint64_t gap_duration; /* duration of initial gap */
|
||||
};
|
||||
|
||||
/* This structure describes lirc circular buffer */
|
||||
|
||||
struct lirc_buffer_s
|
||||
{
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
uint32_t size;
|
||||
FAR void *data;
|
||||
};
|
||||
|
||||
/* The structure describes an open lirc file */
|
||||
|
||||
struct lirc_fh_s
|
||||
{
|
||||
struct list_node node; /* list of open file handles */
|
||||
FAR struct lirc_lowerhalf_s *lower; /* the pointer to lirc_lowerhalf_s */
|
||||
FAR struct lirc_buffer_s *buffer; /* buffer for incoming IR */
|
||||
struct circbuf_s buffer; /* buffer for incoming IR */
|
||||
FAR struct pollfd *fd; /* poll structures of threads waiting for driver events */
|
||||
sem_t waitsem; /* sem of wait buffer for ready */
|
||||
int carrier_low; /* when setting the carrier range, first the low end must be
|
||||
@@ -117,96 +108,6 @@ static const struct file_operations g_lirc_fops =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void lirc_buffer_free(FAR struct lirc_buffer_s *buffer)
|
||||
{
|
||||
kmm_free(buffer);
|
||||
}
|
||||
|
||||
static uint32_t lirc_buffer_len(FAR struct lirc_buffer_s *buffer)
|
||||
{
|
||||
return buffer->head - buffer->tail;
|
||||
}
|
||||
|
||||
static uint32_t lirc_buffer_empty(FAR struct lirc_buffer_s *buffer)
|
||||
{
|
||||
return !lirc_buffer_len(buffer);
|
||||
}
|
||||
|
||||
static uint32_t lirc_buffer_unused(FAR struct lirc_buffer_s *buffer)
|
||||
{
|
||||
return buffer->size - lirc_buffer_len(buffer);
|
||||
}
|
||||
|
||||
static uint32_t lirc_buffer_read(FAR struct lirc_buffer_s *buffer,
|
||||
FAR void *dest, uint32_t bytes)
|
||||
{
|
||||
uint32_t len = lirc_buffer_len(buffer);
|
||||
uint32_t off = buffer->tail % buffer->size;
|
||||
|
||||
if (bytes > len)
|
||||
{
|
||||
bytes = len;
|
||||
}
|
||||
|
||||
len = buffer->size - off;
|
||||
if (bytes < len)
|
||||
{
|
||||
len = bytes;
|
||||
}
|
||||
|
||||
memcpy(dest, buffer->data + off, len);
|
||||
memcpy(dest + len, buffer->data, bytes - len);
|
||||
buffer->tail += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static uint32_t lirc_buffer_write(FAR struct lirc_buffer_s *buffer,
|
||||
FAR const void *src, uint32_t bytes)
|
||||
{
|
||||
uint32_t space = lirc_buffer_unused(buffer);
|
||||
uint32_t off = buffer->head % buffer->size;
|
||||
|
||||
if (bytes > space)
|
||||
{
|
||||
bytes = space;
|
||||
}
|
||||
|
||||
space = buffer->size - off;
|
||||
if (bytes < space)
|
||||
{
|
||||
space = bytes;
|
||||
}
|
||||
|
||||
memcpy(buffer->data + off, src, space);
|
||||
memcpy(buffer->data, src + space, bytes - space);
|
||||
buffer->head += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int lirc_buffer_create(FAR struct lirc_buffer_s **buffer,
|
||||
uint32_t bytes)
|
||||
{
|
||||
FAR struct lirc_buffer_s *tmp;
|
||||
|
||||
tmp = kmm_malloc(sizeof((*tmp)) + bytes);
|
||||
if (!tmp)
|
||||
{
|
||||
rcerr("Faild to malloc memory for circular buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tmp->size = bytes;
|
||||
tmp->data = tmp + 1;
|
||||
tmp->head = 0;
|
||||
tmp->tail = 0;
|
||||
|
||||
*buffer = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lirc_pollnotify(FAR struct lirc_fh_s *fh,
|
||||
pollevent_t eventset)
|
||||
{
|
||||
@@ -263,9 +164,9 @@ static int lirc_open(FAR struct file *filep)
|
||||
fh->send_mode = LIRC_MODE_PULSE;
|
||||
}
|
||||
|
||||
if (lirc_buffer_create(&fh->buffer, lower->buffer_bytes))
|
||||
ret = circbuf_init(&fh->buffer, NULL, lower->buffer_bytes);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto buffer_err;
|
||||
}
|
||||
|
||||
@@ -293,7 +194,7 @@ static int lirc_open(FAR struct file *filep)
|
||||
|
||||
open_err:
|
||||
nxsem_destroy(&fh->waitsem);
|
||||
lirc_buffer_free(fh->buffer);
|
||||
circbuf_uninit(&fh->buffer);
|
||||
buffer_err:
|
||||
kmm_free(fh);
|
||||
return ret;
|
||||
@@ -312,7 +213,7 @@ static int lirc_close(FAR struct file *filep)
|
||||
leave_critical_section(flags);
|
||||
|
||||
nxsem_destroy(&fh->waitsem);
|
||||
lirc_buffer_free(fh->buffer);
|
||||
circbuf_uninit(&fh->buffer);
|
||||
|
||||
kmm_free(fh);
|
||||
if (list_is_empty(&upper->fh))
|
||||
@@ -343,7 +244,7 @@ static int lirc_poll(FAR struct file *filep,
|
||||
fh->fd = fds;
|
||||
fds->priv = &fh->fd;
|
||||
|
||||
if (!lirc_buffer_empty(fh->buffer))
|
||||
if (!circbuf_is_empty(&fh->buffer))
|
||||
{
|
||||
eventset = (fds->events & (POLLIN | POLLRDNORM));
|
||||
}
|
||||
@@ -787,7 +688,7 @@ static ssize_t lirc_read_scancode(FAR struct file *filep, FAR char *buffer,
|
||||
flags = enter_critical_section();
|
||||
do
|
||||
{
|
||||
if (lirc_buffer_empty(fh->buffer))
|
||||
if (circbuf_is_empty(&fh->buffer))
|
||||
{
|
||||
if (filep->f_oflags & O_NONBLOCK)
|
||||
{
|
||||
@@ -802,9 +703,9 @@ static ssize_t lirc_read_scancode(FAR struct file *filep, FAR char *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
len = lirc_buffer_read(fh->buffer, buffer, length);
|
||||
len = circbuf_read(&fh->buffer, buffer, length);
|
||||
}
|
||||
while (len == 0);
|
||||
while (len <= 0);
|
||||
|
||||
err:
|
||||
leave_critical_section(flags);
|
||||
@@ -827,7 +728,7 @@ static ssize_t lirc_read_mode2(FAR struct file *filep, FAR char *buffer,
|
||||
flags = enter_critical_section();
|
||||
do
|
||||
{
|
||||
if (lirc_buffer_empty(fh->buffer))
|
||||
if (circbuf_is_empty(&fh->buffer))
|
||||
{
|
||||
if (filep->f_oflags & O_NONBLOCK)
|
||||
{
|
||||
@@ -842,9 +743,9 @@ static ssize_t lirc_read_mode2(FAR struct file *filep, FAR char *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
len = lirc_buffer_read(fh->buffer, buffer, length);
|
||||
len = circbuf_read(&fh->buffer, buffer, length);
|
||||
}
|
||||
while (len == 0);
|
||||
while (len <= 0);
|
||||
|
||||
err:
|
||||
leave_critical_section(flags);
|
||||
@@ -1035,7 +936,7 @@ void lirc_raw_event(FAR struct lirc_lowerhalf_s *lower,
|
||||
list_for_every_safe(&upper->fh, node, tmp)
|
||||
{
|
||||
fh = (FAR struct lirc_fh_s *)node;
|
||||
if (lirc_buffer_write(fh->buffer, &gap, sizeof(int)))
|
||||
if (circbuf_write(&fh->buffer, &gap, sizeof(int)) > 0)
|
||||
{
|
||||
lirc_pollnotify(fh, POLLIN | POLLRDNORM);
|
||||
nxsem_get_value(&fh->waitsem, &semcount);
|
||||
@@ -1063,7 +964,7 @@ void lirc_raw_event(FAR struct lirc_lowerhalf_s *lower,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lirc_buffer_write(fh->buffer, &sample, sizeof(unsigned int)))
|
||||
if (circbuf_write(&fh->buffer, &sample, sizeof(unsigned int)) > 0)
|
||||
{
|
||||
lirc_pollnotify(fh, POLLIN | POLLRDNORM);
|
||||
nxsem_get_value(&fh->waitsem, &semcount);
|
||||
@@ -1107,7 +1008,7 @@ void lirc_scancode_event(FAR struct lirc_lowerhalf_s *lower,
|
||||
list_for_every_safe(&upper->fh, node, tmp)
|
||||
{
|
||||
fh = (FAR struct lirc_fh_s *)node;
|
||||
if (lirc_buffer_write(fh->buffer, lsc, sizeof(*lsc)))
|
||||
if (circbuf_write(&fh->buffer, lsc, sizeof(*lsc)) > 0)
|
||||
{
|
||||
lirc_pollnotify(fh, POLLIN | POLLRDNORM);
|
||||
nxsem_get_value(&fh->waitsem, &semcount);
|
||||
@@ -1153,7 +1054,7 @@ void lirc_sample_event(FAR struct lirc_lowerhalf_s *lower,
|
||||
list_for_every_safe(&upper->fh, node, tmp)
|
||||
{
|
||||
fh = (FAR struct lirc_fh_s *)node;
|
||||
if (lirc_buffer_write(fh->buffer, &sample, sizeof(unsigned int)))
|
||||
if (circbuf_write(&fh->buffer, &sample, sizeof(unsigned int)) > 0)
|
||||
{
|
||||
lirc_pollnotify(fh, POLLIN | POLLRDNORM);
|
||||
nxsem_get_value(&fh->waitsem, &semcount);
|
||||
|
||||
Reference in New Issue
Block a user