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/nuttx.git

commit 425a760799353f601c5c6e54b43d9ce390355465
Author: liaoao <[email protected]>
AuthorDate: Mon Feb 17 17:25:56 2025 +0800

    drivers/rpmsg: implement timestamp support for rpmsg_port
    
    Add TX/RX timestamp tracking for rpmsg_port to enable latency
    measurement and debugging:
    
    - Add rpmsg_port_get_timestamp() to retrieve buffer timestamps
    - Add rpmsg_port_update_timestamp() to record timestamps at TX/RX time
    - Integrate timestamp recording in rpmsg_port_spi and rpmsg_port_spi_slave
    - Reserve space for rpmsg_timestamp_s in buffer size calculations
    
    Signed-off-by: liaoao <[email protected]>
---
 drivers/rpmsg/rpmsg_port.c           | 62 ++++++++++++++++++++++++++++++++++--
 drivers/rpmsg/rpmsg_port.h           |  8 +++++
 drivers/rpmsg/rpmsg_port_spi.c       |  2 ++
 drivers/rpmsg/rpmsg_port_spi_slave.c |  2 ++
 4 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c
index 2147808f477..bbc8688f301 100644
--- a/drivers/rpmsg/rpmsg_port.c
+++ b/drivers/rpmsg/rpmsg_port.c
@@ -27,6 +27,7 @@
 #include <debug.h>
 #include <execinfo.h>
 #include <stdio.h>
+#include <time.h>
 
 #include <nuttx/irq.h>
 #include <nuttx/kmalloc.h>
@@ -50,6 +51,9 @@
  ****************************************************************************/
 
 static void rpmsg_port_dump(FAR struct rpmsg_s *rpmsg);
+static int rpmsg_port_get_timestamp(FAR struct rpmsg_s *rpmsg,
+                                    FAR const void *data,
+                                    FAR struct rpmsg_timestamp_s *ts);
 
 /****************************************************************************
  * Private Data
@@ -62,6 +66,7 @@ static const struct rpmsg_ops_s g_rpmsg_port_ops =
   NULL,
   NULL,
   rpmsg_port_dump,
+  rpmsg_port_get_timestamp,
 };
 
 /****************************************************************************
@@ -253,7 +258,7 @@ rpmsg_port_get_tx_payload_buffer(FAR struct rpmsg_device 
*rdev,
     }
 
   *len = hdr->len - sizeof(struct rpmsg_port_header_s) -
-         sizeof(struct rpmsg_hdr);
+         sizeof(struct rpmsg_hdr) - sizeof(struct rpmsg_timestamp_s);
 
   return RPMSG_LOCATE_DATA(hdr->buf);
 }
@@ -379,7 +384,7 @@ static int rpmsg_port_get_tx_buffer_size(FAR struct 
rpmsg_device *rdev)
     metal_container_of(rdev, struct rpmsg_port_s, rdev);
 
   return port->txq.len - sizeof(struct rpmsg_port_header_s) -
-         sizeof(struct rpmsg_hdr);
+         sizeof(struct rpmsg_hdr) - sizeof(struct rpmsg_timestamp_s);
 }
 
 /****************************************************************************
@@ -392,7 +397,34 @@ static int rpmsg_port_get_rx_buffer_size(FAR struct 
rpmsg_device *rdev)
     metal_container_of(rdev, struct rpmsg_port_s, rdev);
 
   return port->rxq.len - sizeof(struct rpmsg_port_header_s) -
-         sizeof(struct rpmsg_hdr);
+         sizeof(struct rpmsg_hdr) - sizeof(struct rpmsg_timestamp_s);
+}
+
+/****************************************************************************
+ * Name: rpmsg_port_get_timestamp
+ ****************************************************************************/
+
+static int rpmsg_port_get_timestamp(FAR struct rpmsg_s *rpmsg,
+                                    FAR const void *data,
+                                    FAR struct rpmsg_timestamp_s *ts)
+{
+  FAR struct rpmsg_port_s *port = (FAR struct rpmsg_port_s *)rpmsg;
+  FAR const struct rpmsg_hdr *rphdr = RPMSG_LOCATE_HDR(data);
+  FAR const struct rpmsg_port_header_s *hdr =
+    metal_container_of(rphdr, struct rpmsg_port_header_s, buf);
+  FAR const struct rpmsg_timestamp_s *rpts =
+    (FAR const struct rpmsg_timestamp_s *)((uint8_t *)hdr + port->rxq.len -
+                                           sizeof(struct rpmsg_timestamp_s));
+
+  if (hdr->len > port->rxq.len - sizeof(struct rpmsg_timestamp_s))
+    {
+      return -EINVAL;
+    }
+
+  ts->tx_nsec = rpts->tx_nsec;
+  ts->rx_nsec = rpts->rx_nsec;
+
+  return RPMSG_SUCCESS;
 }
 
 /****************************************************************************
@@ -704,6 +736,30 @@ void rpmsg_port_queue_add_buffer(FAR struct 
rpmsg_port_queue_s *queue,
   rpmsg_port_post(&queue->ready.sem);
 }
 
+/****************************************************************************
+ * Name: rpmsg_port_update_timestamp
+ ****************************************************************************/
+
+void rpmsg_port_update_timestamp(FAR struct rpmsg_port_queue_s *queue,
+                                 FAR struct rpmsg_port_header_s *hdr,
+                                 bool tx)
+{
+  FAR struct rpmsg_timestamp_s *rpts =
+    (FAR struct rpmsg_timestamp_s *)((uint8_t *)hdr + queue->len -
+                                     sizeof(struct rpmsg_timestamp_s));
+  struct timespec ts;
+
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+  if (tx)
+    {
+      rpts->tx_nsec = 1000000000ull * ts.tv_sec + ts.tv_nsec;
+    }
+  else if (hdr->len <= queue->len - sizeof(struct rpmsg_timestamp_s))
+    {
+      rpts->rx_nsec = 1000000000ull * ts.tv_sec + ts.tv_nsec;
+    }
+}
+
 /****************************************************************************
  * Name: rpmsg_port_drop_packets
  ****************************************************************************/
diff --git a/drivers/rpmsg/rpmsg_port.h b/drivers/rpmsg/rpmsg_port.h
index 16491dd8c1b..02f6072fd9b 100644
--- a/drivers/rpmsg/rpmsg_port.h
+++ b/drivers/rpmsg/rpmsg_port.h
@@ -274,6 +274,14 @@ uint16_t rpmsg_port_queue_nused(FAR struct 
rpmsg_port_queue_s *queue)
   return atomic_read(&queue->ready.num);
 }
 
+/****************************************************************************
+ * Name: rpmsg_port_update_timestamp
+ ****************************************************************************/
+
+void rpmsg_port_update_timestamp(FAR struct rpmsg_port_queue_s *queue,
+                                 FAR struct rpmsg_port_header_s *hdr,
+                                 bool tx);
+
 /****************************************************************************
  * Name: rpmsg_port_drop_packets
  ****************************************************************************/
diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c
index da0c584c857..4cfa7596510 100644
--- a/drivers/rpmsg/rpmsg_port_spi.c
+++ b/drivers/rpmsg/rpmsg_port_spi.c
@@ -311,6 +311,7 @@ static void rpmsg_port_spi_exchange(FAR struct 
rpmsg_port_spi_s *rpspi)
   rpmsginfo("irq send cmd:%u avail:%u\n", txhdr->cmd, txhdr->avail);
 
   rpmsg_port_spi_pm_action(rpspi, true);
+  rpmsg_port_update_timestamp(&rpspi->port.txq, txhdr, true);
   SPI_SELECT(rpspi->spi, rpspi->devid, true);
   SPI_EXCHANGE(rpspi->spi, txhdr, rpspi->rxhdr,
                RPMSG_PORT_SPI_BYTES2WORDS(rpspi, rpspi->port.txq.len));
@@ -332,6 +333,7 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg)
   rpmsginfo("received cmd:%u avail:%u\n",
             rpspi->rxhdr->cmd, rpspi->rxhdr->avail);
 
+  rpmsg_port_update_timestamp(&rpspi->port.rxq, rpspi->rxhdr, false);
   if (rpspi->txhdr != NULL)
     {
       rpmsg_port_queue_return_buffer(&rpspi->port.txq, rpspi->txhdr);
diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c 
b/drivers/rpmsg/rpmsg_port_spi_slave.c
index eca0019dd75..79d547b6af0 100644
--- a/drivers/rpmsg/rpmsg_port_spi_slave.c
+++ b/drivers/rpmsg/rpmsg_port_spi_slave.c
@@ -280,6 +280,7 @@ static void rpmsg_port_spi_exchange(FAR struct 
rpmsg_port_spi_s *rpspi)
   rpmsginfo("send cmd:%u avail:%u\n", txhdr->cmd, txhdr->avail);
 
   rpmsg_port_spi_pm_action(rpspi, true);
+  rpmsg_port_update_timestamp(&rpspi->port.txq, txhdr, true);
   SPIS_CTRLR_ENQUEUE(rpspi->spictrlr, txhdr,
                      RPMSG_PORT_SPI_BYTES2WORDS(rpspi, rpspi->port.txq.len));
   IOEXP_WRITEPIN(rpspi->ioe, rpspi->sreq, 1);
@@ -411,6 +412,7 @@ static void rpmsg_port_spi_slave_notify(FAR struct 
spi_slave_dev_s *dev,
   rpmsginfo("received cmd:%u avail:%u\n",
             rpspi->rxhdr->cmd, rpspi->rxhdr->avail);
 
+  rpmsg_port_update_timestamp(&rpspi->port.rxq, rpspi->rxhdr, false);
   if (rpspi->txhdr != NULL)
     {
       rpmsg_port_queue_return_buffer(&rpspi->port.txq, rpspi->txhdr);

Reply via email to