-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Description
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":
zephyr/drivers/serial/uart_native_pty.c
Lines 156 to 171 in e09d0ad
| 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