You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2020/11/20 13:33:16 UTC
[incubator-nuttx] 02/02: driver/sensor rc: use mm/circbuf manage
intermediate buffer
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 8f9ca79ffc7d031e273449b2fbff4a6dc56f3730
Author: dongjiuzhu <do...@xiaomi.com>
AuthorDate: Thu Nov 12 18:40:37 2020 +0800
driver/sensor rc: use mm/circbuf manage intermediate buffer
N/A
Change-Id: Ifdd8117da9d20ac2f48f04b7b383449e6dd03f06
Signed-off-by: dongjiuzhu <do...@xiaomi.com>
---
drivers/rc/Kconfig | 1 +
drivers/rc/lirc_dev.c | 133 ++++------------------------
drivers/sensors/Kconfig | 1 +
drivers/sensors/sensor.c | 226 ++++++++---------------------------------------
4 files changed, 57 insertions(+), 304 deletions(-)
diff --git a/drivers/rc/Kconfig b/drivers/rc/Kconfig
index 65cf457..9e4a5d4 100644
--- a/drivers/rc/Kconfig
+++ b/drivers/rc/Kconfig
@@ -5,6 +5,7 @@
menuconfig DRIVERS_RC
bool "Remote Control Device Support"
+ select MM_CIRCBUF
default n
---help---
Drivers for various remote control
diff --git a/drivers/rc/lirc_dev.c b/drivers/rc/lirc_dev.c
index 057a6b3..d68a1d8 100644
--- a/drivers/rc/lirc_dev.c
+++ b/drivers/rc/lirc_dev.c
@@ -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);
diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig
index f800092..0ac30e2 100644
--- a/drivers/sensors/Kconfig
+++ b/drivers/sensors/Kconfig
@@ -5,6 +5,7 @@
menuconfig SENSORS
bool "Sensor Device Support"
+ select MM_CIRCBUF
default n
---help---
Drivers for various sensors
diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index 1f6ae10..64d26a3 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -34,6 +34,7 @@
#include <poll.h>
#include <fcntl.h>
#include <nuttx/kmalloc.h>
+#include <nuttx/mm/circbuf.h>
#include <nuttx/sensors/sensor.h>
/****************************************************************************
@@ -59,16 +60,6 @@ struct sensor_info
FAR char *name;
};
-/* This structure describes sensor circular buffer */
-
-struct sensor_buffer_s
-{
- uint32_t head;
- uint32_t tail;
- uint32_t size;
- FAR void *data;
-};
-
/* This structure describes the state of the upper half driver */
struct sensor_upperhalf_s
@@ -77,7 +68,7 @@ struct sensor_upperhalf_s
FAR struct pollfd *fds[CONFIG_SENSORS_NPOLLWAITERS];
FAR struct sensor_lowerhalf_s *lower; /* the handle of lower half driver */
- FAR struct sensor_buffer_s *buffer; /* The circualr buffer of sensor device */
+ struct circbuf_s buffer; /* The circular buffer of sensor device */
uint8_t crefs; /* Number of times the device has been opened */
sem_t exclsem; /* Manages exclusive access to file operations */
sem_t buffersem; /* Wakeup user waiting for data in circular buffer */
@@ -148,154 +139,6 @@ static const struct file_operations g_sensor_fops =
* Private Functions
****************************************************************************/
-static bool sensor_buffer_is_empty(FAR struct sensor_buffer_s *buffer)
-{
- return buffer->head == buffer->tail;
-}
-
-static uint32_t sensor_buffer_len(FAR struct sensor_buffer_s *buffer)
-{
- return buffer->head - buffer->tail;
-}
-
-static uint32_t sensor_buffer_unused(FAR struct sensor_buffer_s *buffer)
-{
- return buffer->size - sensor_buffer_len(buffer);
-}
-
-static void sensor_buffer_reset(FAR struct sensor_buffer_s *buffer)
-{
- buffer->head = buffer->tail = 0;
-}
-
-static void sensor_buffer_push(FAR struct sensor_buffer_s *buffer,
- FAR const void *data, uint32_t bytes)
-{
- uint32_t space = sensor_buffer_unused(buffer);
- uint32_t off = buffer->head % buffer->size;
- uint32_t overwrite = 0;
-
- /* If buffer is full or there is not enough space, overwriting of old
- * data will occur, we should move tail point after pushing data
- * completely.
- */
-
- if (bytes > buffer->size)
- {
- data += bytes - buffer->size;
- bytes = buffer->size;
- }
-
- if (bytes > space)
- {
- overwrite = bytes - space;
- }
-
- space = buffer->size - off;
- if (bytes < space)
- {
- space = bytes;
- }
-
- memcpy(buffer->data + off, data, space);
- memcpy(buffer->data, data + space, bytes - space);
- buffer->head += bytes;
- buffer->tail += overwrite;
-}
-
-static uint32_t sensor_buffer_pop(FAR struct sensor_buffer_s *buffer,
- FAR void *data, uint32_t bytes)
-{
- uint32_t len = sensor_buffer_len(buffer);
- uint32_t off;
-
- if (bytes > len)
- {
- bytes = len;
- }
-
- if (!data)
- {
- goto skip;
- }
-
- off = buffer->tail % buffer->size;
- len = buffer->size - off;
- if (bytes < len)
- {
- len = bytes;
- }
-
- memcpy(data, buffer->data + off, len);
- memcpy(data + len, buffer->data, bytes - len);
-
-skip:
- buffer->tail += bytes;
-
- return bytes;
-}
-
-static int sensor_buffer_resize(FAR struct sensor_buffer_s **buffer,
- int type, uint32_t bytes)
-{
- FAR struct sensor_buffer_s *tmp;
- int len = sensor_buffer_len(*buffer);
- int skipped;
-
- bytes = ROUNDUP(bytes, g_sensor_info[type].esize);
- tmp = kmm_malloc(sizeof(*tmp) + bytes);
- if (!tmp)
- {
- snerr("Faild to alloc memory for circular buffer\n");
- return -ENOMEM;
- }
-
- tmp->data = tmp + 1;
-
- skipped = (bytes > len) ? 0 : len - bytes;
- len -= skipped;
- sensor_buffer_pop(*buffer, NULL, skipped);
- sensor_buffer_pop(*buffer, tmp->data, len);
-
- tmp->size = bytes;
- tmp->head = len;
- tmp->tail = 0;
-
- kmm_free(*buffer);
- *buffer = tmp;
-
- return 0;
-}
-
-static int sensor_buffer_create(FAR struct sensor_buffer_s **buffer,
- int type, uint32_t bytes)
-{
- FAR struct sensor_buffer_s *tmp;
-
- bytes = ROUNDUP(bytes, g_sensor_info[type].esize);
-
- tmp = kmm_malloc(sizeof(*tmp) + bytes);
- if (!tmp)
- {
- snerr("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 sensor_buffer_release(FAR struct sensor_buffer_s *buffer)
-{
- kmm_free(buffer);
-}
-
static void sensor_pollnotify(FAR struct sensor_upperhalf_s *upper,
pollevent_t eventset)
{
@@ -328,6 +171,8 @@ static int sensor_open(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct sensor_upperhalf_s *upper = inode->i_private;
+ FAR struct sensor_lowerhalf_s *lower = upper->lower;
+ size_t bytes;
uint8_t tmp;
int ret;
@@ -347,7 +192,14 @@ static int sensor_open(FAR struct file *filep)
}
else if (tmp == 1)
{
- sensor_buffer_reset(upper->buffer);
+ /* Initialize sensor buffer */
+
+ bytes = ROUNDUP(lower->buffer_size, g_sensor_info[lower->type].esize);
+ ret = circbuf_init(&upper->buffer, NULL, bytes);
+ if (ret < 0)
+ {
+ goto err;
+ }
}
upper->crefs = tmp;
@@ -376,6 +228,7 @@ static int sensor_close(FAR struct file *filep)
if (ret >= 0)
{
upper->enabled = false;
+ circbuf_uninit(&upper->buffer);
}
}
@@ -390,6 +243,7 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
FAR struct sensor_upperhalf_s *upper = inode->i_private;
FAR struct sensor_lowerhalf_s *lower = upper->lower;
ssize_t ret;
+ size_t bytes;
if (!buffer || !len)
{
@@ -430,7 +284,7 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
* that have just entered the buffer.
*/
- while (sensor_buffer_is_empty(upper->buffer))
+ while (circbuf_is_empty(&upper->buffer))
{
if (filep->f_oflags & O_NONBLOCK)
{
@@ -454,7 +308,7 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
}
}
- ret = sensor_buffer_pop(upper->buffer, buffer, len);
+ ret = circbuf_read(&upper->buffer, buffer, len);
/* Release some buffer space when current mode isn't batch mode
* and last mode is batch mode, and the number of bytes avaliable
@@ -462,11 +316,12 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
*/
if (upper->latency == 0 &&
- upper->buffer->size > lower->buffer_size &&
- sensor_buffer_len(upper->buffer) <= lower->buffer_size)
+ circbuf_size(&upper->buffer) > lower->buffer_size &&
+ circbuf_used(&upper->buffer) <= lower->buffer_size)
{
- sensor_buffer_resize(&upper->buffer, lower->type,
- lower->buffer_size);
+ bytes = ROUNDUP(lower->buffer_size,
+ g_sensor_info[lower->type].esize);
+ ret = circbuf_resize(&upper->buffer, bytes);
}
}
@@ -481,6 +336,7 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
FAR struct sensor_upperhalf_s *upper = inode->i_private;
FAR struct sensor_lowerhalf_s *lower = upper->lower;
FAR unsigned int *val = (unsigned int *)(uintptr_t)arg;
+ size_t bytes;
int ret;
sninfo("cmd=%x arg=%08x\n", cmd, arg);
@@ -547,11 +403,13 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
/* Adjust length of buffer in batch mode */
- sensor_buffer_resize(&upper->buffer, lower->type,
- lower->buffer_size +
- ROUNDUP(*val, upper->interval) /
- upper->interval *
- g_sensor_info[lower->type].esize);
+ bytes = ROUNDUP(ROUNDUP(*val, upper->interval) /
+ upper->interval *
+ g_sensor_info[lower->type].esize +
+ lower->buffer_size,
+ g_sensor_info[lower->type].esize);
+
+ ret = circbuf_resize(&upper->buffer, bytes);
}
}
}
@@ -569,9 +427,13 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
lower->buffer_size = ROUNDUP(*val,
g_sensor_info[lower->type].esize);
- sensor_buffer_resize(&upper->buffer, lower->type,
- lower->buffer_size);
- *val = lower->buffer_size;
+ bytes = ROUNDUP(lower->buffer_size,
+ g_sensor_info[lower->type].esize);
+ ret = circbuf_resize(&upper->buffer, bytes);
+ if (ret >= 0)
+ {
+ *val = lower->buffer_size;
+ }
}
}
break;
@@ -650,7 +512,7 @@ static int sensor_poll(FAR struct file *filep,
}
}
}
- else if (!sensor_buffer_is_empty(upper->buffer))
+ else if (!circbuf_is_empty(&upper->buffer))
{
eventset |= (fds->events & POLLIN);
}
@@ -689,7 +551,7 @@ static void sensor_push_event(FAR void *priv, FAR const void *data,
return;
}
- sensor_buffer_push(upper->buffer, data, bytes);
+ circbuf_overwrite(&upper->buffer, data, bytes);
sensor_pollnotify(upper, POLLIN);
nxsem_get_value(&upper->buffersem, &semcount);
if (semcount < 1)
@@ -799,15 +661,6 @@ int sensor_register(FAR struct sensor_lowerhalf_s *lower, int devno)
lower->notify_event = sensor_notify_event;
}
- /* Initialize sensor buffer */
-
- ret = sensor_buffer_create(&upper->buffer,
- lower->type, lower->buffer_size);
- if (ret)
- {
- goto buf_err;
- }
-
snprintf(path, DEVNAME_MAX, DEVNAME_FMT,
g_sensor_info[lower->type].name,
lower->uncalibrated ? DEVNAME_UNCAL : "",
@@ -823,8 +676,6 @@ int sensor_register(FAR struct sensor_lowerhalf_s *lower, int devno)
return ret;
drv_err:
- sensor_buffer_release(upper->buffer);
-buf_err:
nxsem_destroy(&upper->exclsem);
nxsem_destroy(&upper->buffersem);
@@ -867,6 +718,5 @@ void sensor_unregister(FAR struct sensor_lowerhalf_s *lower, int devno)
nxsem_destroy(&upper->exclsem);
nxsem_destroy(&upper->buffersem);
- sensor_buffer_release(upper->buffer);
kmm_free(upper);
}