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

jiuzhudong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ad864ff0c2 mm/iob: add iob_init method to support external buffer 
init as iob structure
6ad864ff0c2 is described below

commit 6ad864ff0c2a1fc33cba3adc69356164bf5c6a9f
Author: zhanghongyu <[email protected]>
AuthorDate: Tue Apr 15 22:32:24 2025 +0800

    mm/iob: add iob_init method to support external buffer init as iob structure
    
    This interface allows different protocol modules to use their own unique IOB
    buffer sources and allocation strategies without interfering with each 
other.
    Representative examples are the IP protocol and the CAN protocol. The IP
    protocol generally transmits packets of varying lengths and requires
    relatively high peak throughput. In this case, to ensure higher performance,
    IOB_BUFSIZE is often configured to be relatively large, such as greater than
    500. The CAN protocol generally transmits short packets of fixed length.
    In this case, to improve memory utilization, IOB_BUFSIZE is often configured
    to be relatively small, such as 16 or 64. To optimize the memory utilization
    when the IP protocol and the CAN protocol share the same core,
    this interface was added.
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 Documentation/components/mm/index.rst |  6 +++++
 include/nuttx/mm/iob.h                | 27 +++++++++++++++++++++
 mm/iob/iob_alloc.c                    | 44 ++++++++++++++++++++++++++++++++++-
 mm/iob/iob_free.c                     | 15 ++++++++++--
 4 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/Documentation/components/mm/index.rst 
b/Documentation/components/mm/index.rst
index aabe8355039..e2a9988bbdb 100644
--- a/Documentation/components/mm/index.rst
+++ b/Documentation/components/mm/index.rst
@@ -232,3 +232,9 @@ available for usage by drivers.  The I/O buffers have these 
properties:
    it is removed from the free list; when a buffer is freed it is
    returned to the free list.
 #. The calling application will wait if there are not free buffers.
+#. IOBs can be chained together to form larger buffers.
+#. The extension interface ``iob_init_with_data`` supports external
+   buffer init as iob structure when CONFIG_IOB_ALLOC is enabled. This
+   interface allows different protocol modules to use their own unique
+   I/O buffer sources and allocation strategies without interfering with
+   each other.
diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index 0dea9b47998..f2914762371 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -266,6 +266,33 @@ FAR struct iob_s *iob_alloc_dynamic(uint16_t size);
 
 FAR struct iob_s *iob_alloc_with_data(FAR void *data, uint16_t size,
                                       iob_free_cb_t free_cb);
+
+/****************************************************************************
+ * Name: iob_init_with_data
+ *
+ * Description:
+ *   Initialize an I/O buffer and playload
+ *
+ * Input Parameters:
+ *   data    - Make io_data point to a specific address, the caller is
+ *             responsible for the memory management. The caller should
+ *             ensure that the memory is not freed before the iob is freed,
+ *             and caller need to reserve space for alignment.
+ *   size    - The size of the data parameter
+ *   free_cb - Notify the caller when the iob is freed. The caller can
+ *             perform additional operations on the data before it is freed.
+ *
+ *             +---------+
+ *             |   IOB   |
+ *             | io_data |--+
+ *             | buffer  |<-+
+ *             +---------+
+ *
+ ****************************************************************************/
+
+FAR struct iob_s *iob_init_with_data(FAR void *data, uint16_t size,
+                                     iob_free_cb_t free_cb);
+
 #endif
 
 /****************************************************************************
diff --git a/mm/iob/iob_alloc.c b/mm/iob/iob_alloc.c
index a0fb94ec523..921b9d3b48a 100644
--- a/mm/iob/iob_alloc.c
+++ b/mm/iob/iob_alloc.c
@@ -226,7 +226,7 @@ static FAR struct iob_s *iob_allocwait(bool throttled, 
unsigned int timeout)
  * Name: iob_free_dynamic
  *
  * Description:
- *   Dummy free callback function, do nothing.
+ *   Free the I/O buffer and payload to the heap
  *
  * Input Parameters:
  *   data -
@@ -235,6 +235,7 @@ static FAR struct iob_s *iob_allocwait(bool throttled, 
unsigned int timeout)
 
 static void iob_free_dynamic(FAR void *data)
 {
+  kmm_free(data);
 }
 #endif
 
@@ -396,4 +397,45 @@ FAR struct iob_s *iob_alloc_with_data(FAR void *data, 
uint16_t size,
 
   return iob;
 }
+
+/****************************************************************************
+ * Name: iob_init_with_data
+ *
+ * Description:
+ *   Initialize an I/O buffer and playload
+ *
+ * Input Parameters:
+ *   data    - Make io_data point to a specific address, the caller is
+ *             responsible for the memory management. The caller should
+ *             ensure that the memory is not freed before the iob is freed,
+ *             and caller need to reserve space for alignment.
+ *   size    - The size of the data parameter
+ *   free_cb - Notify the caller when the iob is freed. The caller can
+ *             perform additional operations on the data before it is freed.
+ *
+ *             +---------+
+ *             |   IOB   |
+ *             | io_data |--+
+ *             | buffer  |<-+
+ *             +---------+
+ *
+ ****************************************************************************/
+
+FAR struct iob_s *iob_init_with_data(FAR void *data, uint16_t size,
+                                     iob_free_cb_t free_cb)
+{
+  FAR struct iob_s *iob = (FAR struct iob_s *)data;
+
+  iob->io_flink   = NULL;    /* Not in a chain */
+  iob->io_len     = 0;       /* Length of the data in the entry */
+  iob->io_offset  = 0;       /* Offset to the beginning of data */
+  iob->io_pktlen  = 0;       /* Total length of the packet */
+  iob->io_free    = free_cb; /* Customer free callback */
+  iob->io_data    = (FAR uint8_t *)ALIGN_UP((uintptr_t)(iob + 1),
+                                            CONFIG_IOB_ALIGNMENT);
+  iob->io_bufsize = ((FAR uint8_t *)data + size) - iob->io_data;
+
+  return iob;
+}
+
 #endif
diff --git a/mm/iob/iob_free.c b/mm/iob/iob_free.c
index 86af4304d26..7d734adc880 100644
--- a/mm/iob/iob_free.c
+++ b/mm/iob/iob_free.c
@@ -35,6 +35,7 @@
 #ifdef CONFIG_IOB_ALLOC
 #  include <nuttx/kmalloc.h>
 #endif
+#include <nuttx/nuttx.h>
 #include <nuttx/mm/iob.h>
 
 #include "iob.h"
@@ -120,8 +121,18 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob)
 #ifdef CONFIG_IOB_ALLOC
   if (iob->io_free != NULL)
     {
-      iob->io_free(iob->io_data);
-      kmm_free(iob);
+      FAR uint8_t *io_data = (FAR uint8_t *)ALIGN_UP((uintptr_t)(iob + 1),
+                                                     CONFIG_IOB_ALIGNMENT);
+      if (iob->io_data == io_data)
+        {
+          iob->io_free(iob);
+        }
+      else
+        {
+          iob->io_free(iob->io_data);
+          kmm_free(iob);
+        }
+
       return next;
     }
 #endif

Reply via email to