diff --git a/boards/posix/native_posix/doc/index.rst b/boards/posix/native_posix/doc/index.rst index 1592e50ff0f..6ee606d9f06 100644 --- a/boards/posix/native_posix/doc/index.rst +++ b/boards/posix/native_posix/doc/index.rst @@ -536,8 +536,13 @@ The following peripherals are currently provided with this board: UART ***** -This driver can be configured to either create and link the UART to a new -pseudoterminal (i.e. ``/dev/pts``), or to map the UART input and +This driver can be configured with :option:`CONFIG_UART_NATIVE_POSIX` +to instantiate up to two UARTs. By default only one UART is enabled. +With :option:`CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE` +you can enable the second one. + +For the first UART, it can link it to a new +pseudoterminal (i.e. ``/dev/pts``), or map the UART input and output to the executable's ``stdin`` and ``stdout``. This is chosen by selecting either :option:`CONFIG_NATIVE_UART_0_ON_OWN_PTY` or @@ -557,8 +562,8 @@ to it. This can be done, for example with the command:: where ``/dev/`` should be replaced with the actual TTY device. -You may also chose to automatically attach a terminal emulator to it by -passing the command line option ``-attach_uart`` to the executable. +You may also chose to automatically attach a terminal emulator to the first UART +by passing the command line option ``-attach_uart`` to the executable. The command used for attaching to the new shell can be set with the command line option ``-attach_uart_cmd=<"cmd">``. Where the default command is given by :option:`CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD`. diff --git a/drivers/serial/Kconfig.native_posix b/drivers/serial/Kconfig.native_posix index 450e2c9ac95..f044a09cd2f 100644 --- a/drivers/serial/Kconfig.native_posix +++ b/drivers/serial/Kconfig.native_posix @@ -5,9 +5,10 @@ config UART_NATIVE_POSIX select SERIAL_HAS_DRIVER depends on ARCH_POSIX help - This enables a UART driver for the POSIX ARCH. The driver can be configured + This enables a UART driver for the POSIX ARCH with up to 2 UARTs. + For the first UART port, the driver can be configured to either connect to the terminal from which native_posix was run, or into - one dedicated pseudoterminal for this UART. + one dedicated pseudoterminal for that UART. if UART_NATIVE_POSIX @@ -15,8 +16,8 @@ config UART_NATIVE_POSIX_PORT_0_NAME string "Port 0 Device Name" default "UART_0" help - This is the device name for UART, and is included in the device - struct. + This is the device name for the first UART, and is included in the + device struct. choice prompt "Native UART Port 0 connection" @@ -25,36 +26,52 @@ choice config NATIVE_UART_0_ON_OWN_PTY bool "Connect the UART to its own pseudo terminal" help - Connect the UART to its own pseudoterminal. This is the preferred option - for users who want to use Zephyr's shell. - Moreover this option does not conflict with any other native_posix backend - which may use the calling shell standard input/output. + Connect this UART to its own pseudoterminal. This is the preferred + option for users who want to use Zephyr's shell. + Moreover this option does not conflict with any other native_posix + backend which may use the calling shell standard input/output. config NATIVE_UART_0_ON_STDINOUT bool "Connect the UART to the invoking shell stdin/stdout" help - Connect the UART to the stdin & stdout of the calling shell/terminal which - invoked the native_posix executable. This is good enough for automated - testing, or when feeding from a file/pipe. - Note that other, non UART messages, will also be printed to the terminal. - This option should NOT be used in conjunction with + Connect this UART to the stdin & stdout of the calling shell/terminal + which invoked the native_posix executable. This is good enough for + automated testing, or when feeding from a file/pipe. + Note that other, non UART messages, will also be printed to the + terminal. This option should NOT be used in conjunction with NATIVE_POSIX_STDIN_CONSOLE - It is strongly discouraged to try to use this option with the new shell - interactively, as the default terminal configuration is NOT appropriate - for interactive use. + It is strongly discouraged to try to use this option with the new + shell interactively, as the default terminal configuration is NOT + appropriate for interactive use. endchoice +config UART_NATIVE_POSIX_PORT_1_ENABLE + bool "Enable second UART port" + help + Useful if you need to have another serial connection to host. + This is used for example in PPP (Point-to-Point Protocol) + implementation. + +config UART_NATIVE_POSIX_PORT_1_NAME + string "Port 1 Device Name" + default "UART_1" + depends on UART_NATIVE_POSIX_PORT_1_ENABLE + help + This is the device name for UART, and is included in the device + struct. + config NATIVE_UART_AUTOATTACH_DEFAULT_CMD string "Default command to attach the UART to a new terminal" default "xterm -e screen %s &" help - If the native_posix executable is called with the --attach_uart command line - option, this will be the default command which will be run to attach a new - terminal to it. - Note that this command must have one, and only one, '%s' as placeholder for - the pseudoterminal device name (e.g. /dev/pts/35) - This is only applicable if a UART is configured to use its own PTY with - NATIVE_UART_x_ON_OWN_PTY. + If the native_posix executable is called with the --attach_uart + command line option, this will be the default command which will be + run to attach a new terminal to the 1st UART. + Note that this command must have one, and only one, '%s' as + placeholder for the pseudoterminal device name (e.g. /dev/pts/35) + This is only applicable if the UART_0 is configured to use its own + PTY with NATIVE_UART_0_ON_OWN_PTY. + The 2nd UART will not be affected by this option. endif # UART_NATIVE_POSIX diff --git a/drivers/serial/uart_native_posix.c b/drivers/serial/uart_native_posix.c index b5a25e8b658..256dcfdea77 100644 --- a/drivers/serial/uart_native_posix.c +++ b/drivers/serial/uart_native_posix.c @@ -20,6 +20,10 @@ /* * UART driver for POSIX ARCH based boards. + * It can support up to two UARTs. + * + * For the first UART: + * * It can either be connected to the process STDIN+STDOUT * OR * to a dedicated pseudo terminal @@ -41,11 +45,22 @@ static bool auto_attach; static const char default_cmd[] = CONFIG_NATIVE_UART_AUTOATTACH_DEFAULT_CMD; static char *auto_attach_cmd; -static struct uart_driver_api np_uart_driver_api = { +static struct native_uart_status native_uart_status_0; + +static struct uart_driver_api np_uart_driver_api_0 = { .poll_out = np_uart_poll_out, .poll_in = np_uart_tty_poll_in, }; +#if defined(CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE) +static struct native_uart_status native_uart_status_1; + +static struct uart_driver_api np_uart_driver_api_1 = { + .poll_out = np_uart_poll_out, + .poll_in = np_uart_tty_poll_in, +}; +#endif /* CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE */ + struct native_uart_status { int out_fd; /* File descriptor used for output */ int in_fd; /* File descriptor used for input */ @@ -84,7 +99,9 @@ static void attach_to_tty(const char *slave_tty) * If auto_attach was set, it will also attempt to connect a new terminal * emulator to its slave side. */ -static int open_tty(void) +static int open_tty(struct native_uart_status *driver_data, + const char *uart_name, + bool do_auto_attach) { int master_pty; char *slave_pty_name; @@ -160,9 +177,10 @@ static int open_tty(void) ERROR("Could not change terminal driver settings\n"); } - posix_print_trace("UART connected to pseudotty: %s\n", slave_pty_name); + posix_print_trace("%s connected to pseudotty: %s\n", + uart_name, slave_pty_name); - if (auto_attach) { + if (do_auto_attach) { attach_to_tty(slave_pty_name); } @@ -170,28 +188,29 @@ static int open_tty(void) } /** - * @brief Initialize the native_posix serial port + * @brief Initialize the first native_posix serial port * - * @param dev UART device struct + * @param dev UART_0 device struct * * @return 0 (if it fails catastrophically, the execution is terminated) */ -static int np_uart_init(struct device *dev) +static int np_uart_0_init(struct device *dev) { struct native_uart_status *d; d = (struct native_uart_status *)dev->driver_data; if (IS_ENABLED(CONFIG_NATIVE_UART_0_ON_OWN_PTY)) { - int tty_fn = open_tty(); + int tty_fn = open_tty(d, CONFIG_UART_NATIVE_POSIX_PORT_0_NAME, + auto_attach); d->in_fd = tty_fn; d->out_fd = tty_fn; - np_uart_driver_api.poll_in = np_uart_tty_poll_in; + np_uart_driver_api_0.poll_in = np_uart_tty_poll_in; } else { /* NATIVE_UART_0_ON_STDINOUT */ d->in_fd = STDIN_FILENO; d->out_fd = STDOUT_FILENO; - np_uart_driver_api.poll_in = np_uart_stdin_poll_in; + np_uart_driver_api_0.poll_in = np_uart_stdin_poll_in; if (isatty(STDIN_FILENO)) { WARN("The UART driver has been configured to map to the" @@ -207,6 +226,27 @@ static int np_uart_init(struct device *dev) return 0; } +#if defined(CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE) +/* + * Initialize the 2nd UART port. + * This port will be always attached to its own new pseudoterminal. + */ +static int np_uart_1_init(struct device *dev) +{ + struct native_uart_status *d; + int tty_fn; + + d = (struct native_uart_status *)dev->driver_data; + + tty_fn = open_tty(d, CONFIG_UART_NATIVE_POSIX_PORT_1_NAME, false); + + d->in_fd = tty_fn; + d->out_fd = tty_fn; + + return 0; +} +#endif + /* * @brief Output a character towards the serial port * @@ -296,13 +336,19 @@ static int np_uart_tty_poll_in(struct device *dev, unsigned char *p_char) return 0; } -static struct native_uart_status native_uart_status_0; - DEVICE_AND_API_INIT(uart_native_posix0, - CONFIG_UART_NATIVE_POSIX_PORT_0_NAME, &np_uart_init, + CONFIG_UART_NATIVE_POSIX_PORT_0_NAME, &np_uart_0_init, (void *)&native_uart_status_0, NULL, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &np_uart_driver_api); + &np_uart_driver_api_0); + +#if defined(CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE) +DEVICE_AND_API_INIT(uart_native_posix1, + CONFIG_UART_NATIVE_POSIX_PORT_1_NAME, &np_uart_1_init, + (void *)&native_uart_status_1, NULL, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &np_uart_driver_api_1); +#endif /* CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE */ static void np_add_uart_options(void) { @@ -341,6 +387,12 @@ static void np_cleanup_uart(void) close(native_uart_status_0.in_fd); } } + +#if defined(CONFIG_UART_NATIVE_POSIX_PORT_1_ENABLE) + if (native_uart_status_1.in_fd != 0) { + close(native_uart_status_1.in_fd); + } +#endif } NATIVE_TASK(np_add_uart_options, PRE_BOOT_1, 11);