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:
dongjiuzhu
2020-11-20 05:33:03 -08:00
committed by Xiang Xiao
parent 23ddeaf3be
commit 8f9ca79ffc
4 changed files with 57 additions and 304 deletions
+17 -116
View File
@@ -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);