Skip to content

native_sim pty uart device ordering issue with CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT #100812

@vai-mikar

Description

@vai-mikar

Describe the bug

I have a twister pytest, that is enabling two uart pty nodes:

chosen {
    zephyr,console = &uart0;                     /* in zephyr/boards/native/native_sim/native_sim.dts:18 */
    zephyr,shell-uart = &uart0;                  /* in zephyr/boards/native/native_sim/native_sim.dts:19 */
    ...
};

uart0: uart {
    status = "okay";                       /* in zephyr/boards/native/native_sim/native_sim.dts:154 */
    compatible = "zephyr,native-pty-uart"; /* in zephyr/boards/native/native_sim/native_sim.dts:155 */
    current-speed = < 0x0 >;               /* in zephyr/boards/native/native_sim/native_sim.dts:159 */
};

/* node '/uart_1' defined in zephyr/boards/native/native_sim/native_sim.dts:162 */
uart1: uart_1 {
    compatible = "zephyr,native-pty-uart"; /* in zephyr/boards/native/native_sim/native_sim.dts:164 */
    status = "okay";
    current-speed = < 0x4b00 >; 
};

I want to run pytests on native_sim board, so I configure CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y as it is done in the samples so that pytest twister harness can capture the shell.

However, np_uart_init function gets to initialize uart_1 first, so stdin and stdout are not configured to uart_0 where the shell is, but uart_1 instead. The implementation of np_uart_init considers the first uart it initializes to be the "UART 0":

static int np_uart_init(const struct device *dev)
{
static bool stdinout_used;
struct native_pty_status *d;
d = (struct native_pty_status *)dev->data;
if (IS_ENABLED(CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT)) {
static bool first_node = true;
if (first_node) {
d->on_stdinout = true;
}
first_node = false;
}

I don't know where the order of uart nodes is coming from, but devicetree_generated.h shows that in node dependency ordering uart_1 is really before uart, which might mean it is iterated before uart when initializing devices:

 * Node dependency ordering (ordinal and path):
 *   0   /
 *   1   /aliases
 *   2   /bt_hci_userchan
 *   3   /can
 *   4   /can_loopback0
 *   5   /chosen
 *   6   /counter
 *   7   /dma
 *   8   /dummy_display
 *   9   /eeprom
 *   10  /espi@300
 *   11  /gpio_emul
 *   12  /externally_powered
 *   13  /hw_revision
 *   14  /sdl_dc
 *   15  /input-sdl-touch
 *   16  /lvgl_pointer
 *   17  /mspi@400
 *   18  /boost-pwr-ctrl
 ----> *   19  /uart_1
 *   20  /rng
 *   21  /rtc
 *   22  /spi@200
 ----> *   23  /uart
 *   24  /adc
 *   25  /vbatt

As an ugly test is that that only problem, I tried patching np_uart_init:

diff --git a/drivers/serial/uart_native_pty.c b/drivers/serial/uart_native_pty.c
index 0e1dbe626da..50f21c2432c 100644
--- a/drivers/serial/uart_native_pty.c
+++ b/drivers/serial/uart_native_pty.c
@@ -13,6 +13,8 @@
 #define DT_DRV_COMPAT zephyr_native_pty_uart
 #endif
 
+#include <string.h>
+
 #include <stdbool.h>
 #include <zephyr/drivers/uart.h>
 #include <zephyr/kernel.h>
@@ -167,7 +169,7 @@ static int np_uart_init(const struct device *dev)
 
        d = (struct native_pty_status *)dev->data;
 
-       if (IS_ENABLED(CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT)) {
+       if (IS_ENABLED(CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT) && strcmp(dev->name, "uart") == 0) {
                static bool first_node = true;
 
                if (first_node) {

With it, the standard in/out is set properly to the pty where the shell is configured, and shell and pytests work via stdin/stdout.

The issue could perhaps be solved by switching shell to be in uart_1. But that would require overriding many configuration originating from zephyr, and makes this unnecessary complex. It would be much better if it would be somehow explicit what is UART_0 mentioned in the Kconfigs, maybe by Kconfig chosen directive? Or alternatively (and better?), replace UART_NATIVE_PTY_0_ON_STDINOUT flag with device tree attribute?

This is a "regression", or at least changed behavior. With Zephyr 3.7, this was working without hassle.

Regression

  • This is a regression.

Steps to reproduce

No response

Relevant log output

Impact

Annoyance – Minor irritation; no significant impact on usability or functionality.

Environment

Zephyr 4.3

Additional Context

No response

Metadata

Metadata

Assignees

Labels

RegressionSomething, which was working, does not anymorearea: native portHost native arch port (native_sim)bugThe issue is a bug, or the PR is fixing a bugpriority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions