This is an automated email from the ASF dual-hosted git repository. jerpelea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4cafbc5ce1ccf885bc52db19a41fe377732b1238 Author: p-szafonimateusz <[email protected]> AuthorDate: Tue Apr 7 09:43:09 2026 +0200 drivers/serial: Add console over CAN (ISO-TP). Add console over CAN support with ISO-TP protocol. Signed-off-by: p-szafonimateusz <[email protected]> Signed-off-by: dongjiuzhu1 <[email protected]> --- Documentation/os/networking/console.rst | 23 +++++- drivers/serial/Kconfig | 27 ++++++- drivers/serial/netdev_console.c | 132 ++++++++++++++++++++++++++------ 3 files changed, 156 insertions(+), 26 deletions(-) diff --git a/Documentation/os/networking/console.rst b/Documentation/os/networking/console.rst index c0a06c94d18..5e6709cfad0 100644 --- a/Documentation/os/networking/console.rst +++ b/Documentation/os/networking/console.rst @@ -3,8 +3,12 @@ Console over NETDEV =================== Console over NETDEV provides a remote interactive system console (stdin/stdout) -over a network instead of a serial port. It use bidirectional communication over -UDP. +over a network interface. At this moment UDP and ISO-TP protocols are supported. + +UDP +=== + +It uses bidirectional communication over UDP. To connect to the console on the default port 55000 you can use ``socat``:: @@ -12,3 +16,18 @@ To connect to the console on the default port 55000 you can use ``socat``:: NOTE: you should first start ``socat``, then start NuttX, so that the console driver has a chance to connect to your host. + +ISO-TP +====== + +It uses bidirectional communication over CAN network with ISO-TP protocol. + +To create an ISO-TP to PTY bridge you can use ``tools/isotp_pty.py`` +script. For default ISO-TP console configuration use:: + + python tools/isotp_pty.py can0 7d0 7d1 + +Then you can connect to the created PTY console with Minicom:: + + minicom -D /tmp/isotp-pty + diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index a6c1c246f2f..7f3961513db 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1028,6 +1028,7 @@ config CONSOLE_NETDEV bool "Console on netdev" default n depends on NETDEVICES && SCHED_LPWORK + depends on NET_UDP || NET_CAN_ISOTP select SERIAL_RXDMA select SERIAL_TXDMA ---help--- @@ -1035,6 +1036,25 @@ config CONSOLE_NETDEV if CONSOLE_NETDEV +config CONSOLE_NETDEV_UDP + bool "Netdev Console interface over UDP" + default y if NET_UDP + ---help--- + Network interface over UDP used for Console. + +config CONSOLE_NETDEV_CAN + bool "Netdev Console interface over CAN" + default y if NET_CAN_ISOTP + ---help--- + Network interface over CAN (ISO-TP) used for Console. + +config CONSOLE_NETDEV_INTF + string "Netdev Console CAN interface name" + default "can0" + depends on CONSOLE_NETDEV_CAN && NETDEV_IFINDEX + ---help--- + Name of the CAN interface used by the ISO-TP console. + config CONSOLE_NETDEV_IPADDR hex "CONSOLE netdev destination IP address" default 0xffffffff @@ -1043,9 +1063,12 @@ config CONSOLE_NETDEV_IPADDR config CONSOLE_NETDEV_PORT int "CONSOLE netdev port" - default 55000 + default 55000 if CONSOLE_NETDEV_UDP + default 2000 if CONSOLE_NETDEV_CAN ---help--- - UDP port for CONSOLE input/output. + For UDP: UDP port for CONSOLE input/output. + For CAN ISO-TP: TX CAN ID. The RX CAN ID is derived as + CONSOLE_NETDEV_PORT + 1. config CONSOLE_NETDEV_RXBUFSIZE int "CONSOLE netdev receive buffer size" diff --git a/drivers/serial/netdev_console.c b/drivers/serial/netdev_console.c index ecf861e76cc..a20cb850e32 100644 --- a/drivers/serial/netdev_console.c +++ b/drivers/serial/netdev_console.c @@ -40,6 +40,13 @@ #include <nuttx/serial/serial.h> #include <nuttx/wqueue.h> +#ifdef CONFIG_NET_CAN +# include <nuttx/can.h> +# ifdef CONFIG_NET_CAN_ISOTP +# include <nuttx/can/isotp.h> +# endif +#endif + /**************************************************************************** * Pre-processor definitions ****************************************************************************/ @@ -65,6 +72,13 @@ struct netdev_consol_s * Private Function Prototypes ****************************************************************************/ +#ifdef CONFIG_NET_UDP +static int netdev_console_udp_init(FAR struct uart_dev_s *dev); +#endif +#ifdef CONFIG_NET_CAN +static int netdev_console_can_init(FAR struct uart_dev_s *dev); +#endif + static int netdev_console_setup(FAR struct uart_dev_s *dev); static void netdev_console_shutdown(FAR struct uart_dev_s *dev); static int netdev_console_attach(FAR struct uart_dev_s *dev); @@ -135,36 +149,17 @@ static struct netdev_consol_s g_netdev_console = * Private Functions ****************************************************************************/ +#ifdef CONFIG_CONSOLE_NETDEV_UDP /**************************************************************************** - * Name: netdev_console_setup - ****************************************************************************/ - -static int netdev_console_setup(FAR struct uart_dev_s *dev) -{ - return OK; -} - -/**************************************************************************** - * Name: netdev_console_shutdown - ****************************************************************************/ - -static void netdev_console_shutdown(FAR struct uart_dev_s *dev) -{ -} - -/**************************************************************************** - * Name: netdev_console_attach + * Name: netdev_console_udp_init ****************************************************************************/ -static int netdev_console_attach(FAR struct uart_dev_s *dev) +static int netdev_console_udp_init(FAR struct uart_dev_s *dev) { FAR struct netdev_consol_s *priv = (FAR struct netdev_consol_s *)dev; struct sockaddr_in addr; int ret; - priv->rxdgram_off = 0; - priv->rxdgram_len = 0; - /* Initialize UDP socket for CONSOLE TX/RX */ ret = psock_socket(PF_INET, SOCK_DGRAM, 0, &priv->psock); @@ -191,6 +186,99 @@ static int netdev_console_attach(FAR struct uart_dev_s *dev) return OK; } +#endif + +#ifdef CONFIG_CONSOLE_NETDEV_CAN +/**************************************************************************** + * Name: netdev_console_can_init + ****************************************************************************/ + +static int netdev_console_can_init(FAR struct uart_dev_s *dev) +{ + FAR struct netdev_consol_s *priv = (FAR struct netdev_consol_s *)dev; +#ifdef CONFIG_NET_CAN_CANFD + struct can_isotp_ll_options ll; +#endif + struct sockaddr_can addr; + int ret; + + ret = psock_socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP, &priv->psock); + if (ret < 0) + { + nerr("ERROR: Failed to create ISO-TP socket: %d\n", ret); + return ret; + } + + memset(&addr, 0, sizeof(addr)); + addr.can_family = AF_CAN; +#ifdef CONFIG_NETDEV_IFINDEX + addr.can_ifindex = if_nametoindex(CONFIG_CONSOLE_NETDEV_INTF); +#else + addr.can_ifindex = 0; +#endif + addr.can_addr.tp.tx_id = CONFIG_CONSOLE_NETDEV_PORT; + addr.can_addr.tp.rx_id = CONFIG_CONSOLE_NETDEV_PORT + 1; + + ret = psock_bind(&priv->psock, (FAR struct sockaddr *)&addr, + sizeof(addr)); + if (ret < 0) + { + psock_close(&priv->psock); + nerr("ERROR: Failed to bind ISO-TP socket: %d\n", ret); + return ret; + } + +#ifdef CONFIG_NET_CAN_CANFD + /* Always use CAN FD if enabled */ + + ll.mtu = CANFD_MTU; + ll.tx_dl = CANFD_MAX_DLEN; + ll.tx_flags = 0; + + psock_setsockopt(&priv->psock, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &ll, + sizeof(ll)); +#endif + + return OK; +} +#endif + +/**************************************************************************** + * Name: netdev_console_setup + ****************************************************************************/ + +static int netdev_console_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: netdev_console_shutdown + ****************************************************************************/ + +static void netdev_console_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: netdev_console_attach + ****************************************************************************/ + +static int netdev_console_attach(FAR struct uart_dev_s *dev) +{ + FAR struct netdev_consol_s *priv = (FAR struct netdev_consol_s *)dev; + + priv->rxdgram_off = 0; + priv->rxdgram_len = 0; + +#ifdef CONFIG_CONSOLE_NETDEV_UDP + return netdev_console_udp_init(dev); +#endif + +#ifdef CONFIG_CONSOLE_NETDEV_CAN + return netdev_console_can_init(dev); +#endif +} /**************************************************************************** * Name: netdev_console_detach
