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);
