From 4f9b9a4500d8d6d70e385fc931bc2e26c35cf88a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 11 Feb 2020 16:31:12 +0100 Subject: [PATCH] shell: telnet: Replace timer with a delayed work A `k_timer` callback is called from the ISR context on certain devices (nRF), which resulted in an assert in the kernel, as `telnet_send`, and thus `net_context_send` used a mutex. Fix the issue by replacing a timer used by the `shell_telnet` module with a delayed work, which will execute it's callback in a system workqueue context. Fixes #22697 Signed-off-by: Robert Lubos --- include/shell/shell_telnet.h | 4 ++-- subsys/shell/shell_telnet.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/shell/shell_telnet.h b/include/shell/shell_telnet.h index da7ff5fdf84..c514f1609fb 100644 --- a/include/shell/shell_telnet.h +++ b/include/shell/shell_telnet.h @@ -41,11 +41,11 @@ struct shell_telnet { /** RX packet FIFO. */ struct k_fifo rx_fifo; - /** The timer is used to send non-lf terminated output that has + /** The delayed work is used to send non-lf terminated output that has * been around for "too long". This will prove to be useful * to send the shell prompt for instance. */ - struct k_timer send_timer; + struct k_delayed_work send_work; /** If set, no output is sent to the TELNET client. */ bool output_lock; diff --git a/subsys/shell/shell_telnet.c b/subsys/shell/shell_telnet.c index 2df48038cc4..36109a5825a 100644 --- a/subsys/shell/shell_telnet.c +++ b/subsys/shell/shell_telnet.c @@ -43,7 +43,7 @@ static void telnet_end_client_connection(void) sh_telnet->client_ctx = NULL; sh_telnet->output_lock = false; - k_timer_stop(&sh_telnet->send_timer); + k_delayed_work_cancel(&sh_telnet->send_work); /* Flush the RX FIFO */ while ((pkt = k_fifo_get(&sh_telnet->rx_fifo, K_NO_WAIT)) != NULL) { @@ -109,7 +109,7 @@ static void telnet_reply_command(struct telnet_simple_command *cmd) /* OK, no output then */ sh_telnet->output_lock = true; sh_telnet->line_out.len = 0; - k_timer_stop(&sh_telnet->send_timer); + k_delayed_work_cancel(&sh_telnet->send_work); break; case NVT_CMD_AYT: telnet_reply_ay_command(); @@ -150,7 +150,7 @@ static int telnet_send(void) return 0; } -static void telnet_send_prematurely(struct k_timer *timer) +static void telnet_send_prematurely(struct k_work *work) { (void)telnet_send(); } @@ -343,7 +343,7 @@ static int init(const struct shell_transport *transport, sh_telnet->shell_context = context; k_fifo_init(&sh_telnet->rx_fifo); - k_timer_init(&sh_telnet->send_timer, telnet_send_prematurely, NULL); + k_delayed_work_init(&sh_telnet->send_work, telnet_send_prematurely); return 0; } @@ -389,8 +389,8 @@ static int write(const struct shell_transport *transport, /* Stop the transmission timer, so it does not interrupt the operation. */ - timeout = k_timer_remaining_get(&sh_telnet->send_timer); - k_timer_stop(&sh_telnet->send_timer); + timeout = k_delayed_work_remaining_get(&sh_telnet->send_work); + k_delayed_work_cancel(&sh_telnet->send_work); do { if (lb->len + length - *cnt > TELNET_LINE_SIZE) { @@ -422,7 +422,7 @@ static int write(const struct shell_transport *transport, */ timeout = (timeout == 0) ? TELNET_TIMEOUT : timeout; - k_timer_start(&sh_telnet->send_timer, timeout, K_NO_WAIT); + k_delayed_work_submit(&sh_telnet->send_work, timeout); } sh_telnet->shell_handler(SHELL_TRANSPORT_EVT_TX_RDY,