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:14 UTC

[incubator-nuttx] branch master updated (93ff68e -> 8f9ca79)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 93ff68e  serial: Prevent RX stall
     new 23ddeaf  mm/circbuf: support circular buffer managerment
     new 8f9ca79  driver/sensor rc: use mm/circbuf manage intermediate buffer

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 drivers/rc/Kconfig                                 |   1 +
 drivers/rc/lirc_dev.c                              | 133 +-----
 drivers/sensors/Kconfig                            |   1 +
 drivers/sensors/sensor.c                           | 226 ++--------
 include/nuttx/mm/circbuf.h                         | 308 +++++++++++++
 mm/Kconfig                                         |   6 +
 mm/Makefile                                        |   1 +
 .../machine/risc-v/rv32 => mm/circbuf}/Make.defs   |  13 +-
 mm/circbuf/circbuf.c                               | 474 +++++++++++++++++++++
 9 files changed, 853 insertions(+), 310 deletions(-)
 create mode 100644 include/nuttx/mm/circbuf.h
 copy {libs/libc/machine/risc-v/rv32 => mm/circbuf}/Make.defs (82%)
 create mode 100644 mm/circbuf/circbuf.c


[incubator-nuttx] 01/02: mm/circbuf: support circular buffer managerment

Posted by xi...@apache.org.
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 23ddeaf3be530cd8faa7e7077fa9ea7caa83d708
Author: dongjiuzhu <do...@xiaomi.com>
AuthorDate: Thu Nov 12 18:40:06 2020 +0800

    mm/circbuf: support circular buffer managerment
    
    N/A
    
    Change-Id: Ib1fc009b9ce3af5815920f22221fe8a7262299ef
    Signed-off-by: dongjiuzhu <do...@xiaomi.com>
---
 include/nuttx/mm/circbuf.h | 308 +++++++++++++++++++++++++++++
 mm/Kconfig                 |   6 +
 mm/Makefile                |   1 +
 mm/circbuf/Make.defs       |  30 +++
 mm/circbuf/circbuf.c       | 474 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 819 insertions(+)

diff --git a/include/nuttx/mm/circbuf.h b/include/nuttx/mm/circbuf.h
new file mode 100644
index 0000000..c6d291c
--- /dev/null
+++ b/include/nuttx/mm/circbuf.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+ * include/nuttx/mm/circbuf.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_MM_CIRCBUF_H
+#define __INCLUDE_NUTTX_MM_CIRCBUF_H
+
+/* Note about locking: There is no locking required while only one reader
+ * and one writer is using the circular buffer.
+ * For multiple writer and one reader there is only a need to lock the
+ * writer. And vice versa for only one writer and multiple reader there is
+ * only a need to lock the reader.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This structure describes circular buffer */
+
+struct circbuf_s
+{
+  FAR void *base;     /* The pointer to buffer space */
+  size_t    size;     /* The size of buffer space */
+  size_t    head;     /* The head of buffer space */
+  size_t    tail;     /* The tail of buffer space */
+  bool      external; /* The flag for external buffer */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: circbuf_init
+ *
+ * Description:
+ *   Initialize a circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   base  - A pointer to circular buffer's internal buffer. It can be
+ *           provided by caller because sometimes the creation of buffer
+ *           is special or needs to preallocated, eg: DMA buffer.
+ *           If NULL, a buffer of the given size will be allocated.
+ *   bytes - The size of the internal buffer.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int circbuf_init(FAR struct circbuf_s *circ,
+                  FAR void *base, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_resize
+ *
+ * Description:
+ *   Resize a circular buffer (change buffer size).
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   bytes - The size of the internal buffer.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int circbuf_resize(FAR struct circbuf_s *circ, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_uninit
+ *
+ * Description:
+ *   Free the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+void circbuf_uninit(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_reset
+ *
+ * Description:
+ *   Remove the entire circular buffer content.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+void circbuf_reset(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_is_full
+ *
+ * Description:
+ *   Return true if the circular buffer is full.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+bool circbuf_is_full(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_is_empty
+ *
+ * Description:
+ *   Return true if the circular buffer is empty.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+bool circbuf_is_empty(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_size
+ *
+ * Description:
+ *   Return size of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_size(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_used
+ *
+ * Description:
+ *   Return the used bytes of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_used(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_space
+ *
+ * Description:
+ *   Return the remaing space of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_space(FAR struct circbuf_s *circ);
+
+/****************************************************************************
+ * Name: circbuf_peek
+ *
+ * Description:
+ *   Get data form the circular buffer without removing
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   dst   - Address where to store the data.
+ *   bytes - Number of bytes to get.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the peek data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_peek(FAR struct circbuf_s *circ,
+                      FAR void *dst, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_read
+ *
+ * Description:
+ *   Get data form the circular buffer.
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   dst   - Address where to store the data.
+ *   bytes - Number of bytes to get.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the read data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_read(FAR struct circbuf_s *circ,
+                      FAR void *dst, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_skip
+ *
+ * Description:
+ *   Skip data form the circular buffer.
+ *
+ * Note:
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   bytes - Number of bytes to skip.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the skip data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_skip(FAR struct circbuf_s *circ, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_write
+ *
+ * Description:
+ *   Write data to the circular buffer.
+ *
+ * Note:
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   src   - The data to be added.
+ *   bytes - Number of bytes to be added.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the write data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_write(FAR struct circbuf_s *circ,
+                       FAR const void *src, size_t bytes);
+
+/****************************************************************************
+ * Name: circbuf_overwrite
+ *
+ * Description:
+ *   Write data to the circular buffer. It can overwrite old data when
+ *   circular buffer don't have enough space to store data.
+ *
+ * Note:
+ *   Usage circbuf_overwrite () is dangerous. It should be only called
+ *   when the buffer is exclusived locked or when it is secured that no
+ *   other thread is accessing the buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   src   - The data to be added.
+ *   bytes - Number of bytes to be added.
+ *
+ * Returned Value:
+ *   The bytes length of overwrite is returned if it's successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_overwrite(FAR struct circbuf_s *circ,
+                           FAR const void *src, size_t bytes);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/mm/Kconfig b/mm/Kconfig
index e4b8170..788ae47 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -155,4 +155,10 @@ config MM_FILL_ALLOCATIONS
 		Fill all malloc() allocations with 0xAA. This helps
 		detecting uninitialized variable errors.
 
+config MM_CIRCBUF
+	bool "Circular buffer support"
+	default n
+	---help---
+		Build in support for the circular buffer management.
+
 source "mm/iob/Kconfig"
diff --git a/mm/Makefile b/mm/Makefile
index b08ad3a..ae04d19 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -43,6 +43,7 @@ include kmm_heap/Make.defs
 include mm_gran/Make.defs
 include shm/Make.defs
 include iob/Make.defs
+include circbuf/Make.defs
 
 BINDIR ?= bin
 
diff --git a/mm/circbuf/Make.defs b/mm/circbuf/Make.defs
new file mode 100644
index 0000000..1d71c24
--- /dev/null
+++ b/mm/circbuf/Make.defs
@@ -0,0 +1,30 @@
+############################################################################
+# mm/circbuf/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Circular buffer management
+
+ifeq ($(CONFIG_MM_CIRCBUF),y)
+CSRCS += circbuf.c
+
+# Add the circular buffer directory to the build
+
+DEPPATH += --dep-path circbuf
+VPATH += :circbuf
+endif
diff --git a/mm/circbuf/circbuf.c b/mm/circbuf/circbuf.c
new file mode 100644
index 0000000..cef8e13
--- /dev/null
+++ b/mm/circbuf/circbuf.c
@@ -0,0 +1,474 @@
+/****************************************************************************
+ * mm/circbuf/circbuf.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Note about locking: There is no locking required while only one reader
+ * and one writer is using the circular buffer.
+ * For multiple writer and one reader there is only a need to lock the
+ * writer. And vice versa for only one writer and multiple reader there is
+ * only a need to lock the reader.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mm/circbuf.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: circbuf_init
+ *
+ * Description:
+ *   Initialize a circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   base  - A pointer to circular buffer's internal buffer. It can be
+ *           provided by caller because sometimes the creation of buffer
+ *           is special or needs to preallocated, eg: DMA buffer.
+ *           If NULL, a buffer of the given size will be allocated.
+ *   bytes - The size of the internal buffer.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int circbuf_init(FAR struct circbuf_s *circ, FAR void *base, size_t bytes)
+{
+  DEBUGASSERT(circ);
+  DEBUGASSERT(!base || bytes);
+
+  circ->external = !!base;
+
+  if (!base && bytes)
+    {
+      base = kmm_malloc(bytes);
+      if (!base)
+        {
+          return -ENOMEM;
+        }
+    }
+
+  circ->base = base;
+  circ->size = bytes;
+  circ->head = 0;
+  circ->tail = 0;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: circbuf_resize
+ *
+ * Description:
+ *   Resize a circular buffer (change buffer size).
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   bytes - The size of the internal buffer.
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int circbuf_resize(FAR struct circbuf_s *circ, size_t bytes)
+{
+  FAR void *tmp;
+  size_t len;
+
+  DEBUGASSERT(circ);
+  DEBUGASSERT(!circ->external);
+
+  tmp = kmm_malloc(bytes);
+  if (!tmp)
+    {
+      return -ENOMEM;
+    }
+
+  len = circbuf_used(circ);
+  if (bytes < len)
+    {
+      circbuf_skip(circ, len - bytes);
+      len = bytes;
+    }
+
+  circbuf_read(circ, tmp, len);
+
+  kmm_free(circ->base);
+
+  circ->base = tmp;
+  circ->size = bytes;
+  circ->head = len;
+  circ->tail = 0;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: circbuf_reset
+ *
+ * Description:
+ *   Remove the entire circular buffer content.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+void circbuf_reset(FAR struct circbuf_s *circ)
+{
+  DEBUGASSERT(circ);
+  circ->head = circ->tail = 0;
+}
+
+/****************************************************************************
+ * Name: circbuf_uninit
+ *
+ * Description:
+ *   Free the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+void circbuf_uninit(FAR struct circbuf_s *circ)
+{
+  DEBUGASSERT(circ);
+
+  if (!circ->external)
+    {
+      kmm_free(circ->base);
+    }
+
+  memset(circ, 0, sizeof(*circ));
+}
+
+/****************************************************************************
+ * Name: circbuf_size
+ *
+ * Description:
+ *   Return size of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_size(FAR struct circbuf_s *circ)
+{
+  DEBUGASSERT(circ);
+  return circ->size;
+}
+
+/****************************************************************************
+ * Name: circbuf_used
+ *
+ * Description:
+ *   Return the used bytes of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_used(FAR struct circbuf_s *circ)
+{
+  DEBUGASSERT(circ);
+  return circ->head - circ->tail;
+}
+
+/****************************************************************************
+ * Name: circbuf_space
+ *
+ * Description:
+ *   Return the remaing space of the circular buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+size_t circbuf_space(FAR struct circbuf_s *circ)
+{
+  return circbuf_size(circ) - circbuf_used(circ);
+}
+
+/****************************************************************************
+ * Name: circbuf_is_empty
+ *
+ * Description:
+ *   Return true if the circular buffer is empty.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+bool circbuf_is_empty(FAR struct circbuf_s *circ)
+{
+  return !circbuf_used(circ);
+}
+
+/****************************************************************************
+ * Name: circbuf_is_full
+ *
+ * Description:
+ *   Return true if the circular buffer is full.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ ****************************************************************************/
+
+bool circbuf_is_full(FAR struct circbuf_s *circ)
+{
+  return !circbuf_space(circ);
+}
+
+/****************************************************************************
+ * Name: circbuf_peek
+ *
+ * Description:
+ *   Get data form the circular buffer without removing
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   dst   - Address where to store the data.
+ *   bytes - Number of bytes to get.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the peek data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_peek(FAR struct circbuf_s *circ,
+                      FAR void *dst, size_t bytes)
+{
+  size_t len;
+  size_t off;
+
+  DEBUGASSERT(circ);
+
+  len = circbuf_used(circ);
+  off = circ->tail % circ->size;
+
+  if (bytes > len)
+    {
+      bytes = len;
+    }
+
+  len = circ->size - off;
+  if (bytes < len)
+    {
+      len = bytes;
+    }
+
+  memcpy(dst, circ->base + off, len);
+  memcpy(dst + len, circ->base, bytes - len);
+
+  return bytes;
+}
+
+/****************************************************************************
+ * Name: circbuf_read
+ *
+ * Description:
+ *   Get data form the circular buffer.
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   dst   - Address where to store the data.
+ *   bytes - Number of bytes to get.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the read data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_read(FAR struct circbuf_s *circ,
+                      FAR void *dst, size_t bytes)
+{
+  DEBUGASSERT(circ);
+  DEBUGASSERT(dst || !bytes);
+
+  bytes = circbuf_peek(circ, dst, bytes);
+  circ->tail += bytes;
+
+  return bytes;
+}
+
+/****************************************************************************
+ * Name: circbuf_skip
+ *
+ * Description:
+ *   Skip data form the circular buffer.
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   bytes - Number of bytes to skip.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the skip data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_skip(FAR struct circbuf_s *circ, size_t bytes)
+{
+  size_t len;
+
+  DEBUGASSERT(circ);
+
+  len = circbuf_used(circ);
+
+  if (bytes > len)
+    {
+      bytes = len;
+    }
+
+  circ->tail += bytes;
+
+  return bytes;
+}
+
+/****************************************************************************
+ * Name: circbuf_write
+ *
+ * Description:
+ *   Write data to the circular buffer.
+ *
+ * Note :
+ *   That with only one concurrent reader and one concurrent writer,
+ *   you don't need extra locking to use these api.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   src   - The data to be added.
+ *   bytes - Number of bytes to be added.
+ *
+ * Returned Value:
+ *   The bytes of get data is returned if the write data is successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_write(FAR struct circbuf_s *circ,
+                       FAR const void *src, size_t bytes)
+{
+  size_t space;
+  size_t off;
+
+  DEBUGASSERT(circ);
+  DEBUGASSERT(src || !bytes);
+
+  space = circbuf_space(circ);
+  off = circ->head % circ->size;
+  if (bytes > space)
+    {
+      bytes = space;
+    }
+
+  space = circ->size - off;
+  if (bytes < space)
+    {
+      space = bytes;
+    }
+
+  memcpy(circ->base + off, src, space);
+  memcpy(circ->base, src + space, bytes - space);
+  circ->head += bytes;
+
+  return bytes;
+}
+
+/****************************************************************************
+ * Name: circbuf_overwrite
+ *
+ * Description:
+ *   Write data to the circular buffer. It can overwrite old data when
+ *   circular buffer don't have enough space to store data.
+ *
+ * Note:
+ *   Usage circbuf_overwrite () is dangerous. It should be only called
+ *   when the buffer is exclusived locked or when it is secured that no
+ *   other thread is accessing the buffer.
+ *
+ * Input Parameters:
+ *   circ  - Address of the circular buffer to be used.
+ *   src   - The data to be added.
+ *   bytes - Number of bytes to be added.
+ *
+ * Returned Value:
+ *   The bytes length of overwrite is returned if it's successful;
+ *   A negated errno value is returned on any failure.
+ ****************************************************************************/
+
+ssize_t circbuf_overwrite(FAR struct circbuf_s *circ,
+                           FAR const void *src, size_t bytes)
+{
+  size_t overwrite = 0;
+  size_t space;
+  size_t off;
+
+  DEBUGASSERT(circ);
+  DEBUGASSERT(src || !bytes);
+
+  if (bytes > circ->size)
+    {
+      src += bytes - circ->size;
+      bytes = circ->size;
+    }
+
+  space = circbuf_space(circ);
+  if (bytes > space)
+    {
+      overwrite = bytes - space;
+    }
+
+  off = circ->head % circ->size;
+  space = circ->size - off;
+  if (bytes < space)
+    {
+      space = bytes;
+    }
+
+  memcpy(circ->base + off, src, space);
+  memcpy(circ->base, src + space, bytes - space);
+  circ->head += bytes;
+  circ->tail += overwrite;
+
+  return overwrite;
+}


[incubator-nuttx] 02/02: driver/sensor rc: use mm/circbuf manage intermediate buffer

Posted by xi...@apache.org.
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);
 }