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

Reply via email to