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 <dongjiuz...@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 <dongjiuz...@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); }