From e20a3d0c488a99054605a3b22da83226e12b1863 Mon Sep 17 00:00:00 2001 From: Jacek Maksymowicz Date: Wed, 25 Sep 2024 14:29:24 +0200 Subject: [PATCH] imxrt-multi: implement adaptive polling rate for RTT JIRA: RTOS-754 --- multi/imxrt-multi/rtt.c | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/multi/imxrt-multi/rtt.c b/multi/imxrt-multi/rtt.c index dd6c49fe..d1b76577 100644 --- a/multi/imxrt-multi/rtt.c +++ b/multi/imxrt-multi/rtt.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -33,9 +34,11 @@ #define RTT_TX_BUF_SIZE 1024 #define RTT_RX_BUF_SIZE 256 -#define RTT_POLLING_RATE_MS 20 -#define RTT_NO_PICKUP_TIMEOUT_MS (2 * RTT_POLLING_RATE_MS) -#define RTT_RETRIES (RTT_NO_PICKUP_TIMEOUT_MS / RTT_POLLING_RATE_MS) +#define RTT_IDLE_TIMEOUT_US 1048576 +#define RTT_NO_PICKUP_TIMEOUT_US 131072 +#define RTT_RATE_IDLE_US 131072 +#define RTT_RATE_MAX_US 32768 +#define RTT_RATE_MIN_US 2048 /* Doesn't need to be large, data will mostly be stored in RTT buffers */ #define TTY_BUF_SIZE 64 @@ -77,10 +80,13 @@ static inline ssize_t rtt_txAvailMode(unsigned int chn) static void rtt_thread(void *arg) { - unsigned retries[RTT_ACTIVE_CNT]; - memset(retries, 0, sizeof(retries)); + int timeout[RTT_ACTIVE_CNT]; + memset(timeout, 0, sizeof(timeout)); + int pollingRate = RTT_RATE_MAX_US; + int idleTimeout = 0; for (;;) { + unsigned chnsIdle = 0; for (int chn_idx = 0; chn_idx < RTT_ACTIVE_CNT; chn_idx++) { rtt_t *uart = &rtt_common.uarts[chn_idx]; unsigned char data; @@ -92,19 +98,19 @@ static void rtt_thread(void *arg) /* Do nothing, in this case the remaining code is unnecessary */ } else if (librtt_txCheckReaderAttached(uart->chn) != 0) { - retries[chn_idx] = RTT_RETRIES; + timeout[chn_idx] = RTT_NO_PICKUP_TIMEOUT_US; } else if (onTx == 0) { - if (retries[chn_idx] == 0) { + if (timeout[chn_idx] == 0) { onTx = 1; } else { - retries[chn_idx]--; + timeout[chn_idx] = max(0, timeout[chn_idx] - pollingRate); } } - if ((onRx == 0) && ((txReady == 0) || (onTx == 0))) { + chnsIdle++; continue; } @@ -116,21 +122,39 @@ static void rtt_thread(void *arg) onRx = librtt_rxAvail(uart->chn); } - while (onTx > 0 && txReady) { + while ((onTx > 0) && (txReady != 0)) { data = libtty_getchar(&uart->tty_common, NULL); ssize_t written = librtt_write(uart->chn, &data, 1, 0); if (written <= 0) { uart->diag_txSkipped++; } - onTx = rtt_txAvailMode(uart->chn); + onTx = (timeout[chn_idx] == 0) ? 1 : rtt_txAvailMode(uart->chn); txReady = libtty_txready(&uart->tty_common); } mutexUnlock(uart->lock); } - usleep(RTT_POLLING_RATE_MS * 1000); + if (chnsIdle == RTT_ACTIVE_CNT) { + if (idleTimeout == 0) { + pollingRate = RTT_RATE_IDLE_US; + } + else { + idleTimeout = max(0, idleTimeout - pollingRate); + pollingRate = min(RTT_RATE_MAX_US, (pollingRate * 3) / 2); + } + } + else { + if (idleTimeout == 0) { + pollingRate = RTT_RATE_MAX_US; + } + + idleTimeout = RTT_IDLE_TIMEOUT_US; + pollingRate = max(RTT_RATE_MIN_US, pollingRate / 2); + } + + usleep(pollingRate); } }