Zephyr Output of USB UART Serial Leaks Into Input Buffer


I wrote a simple terminal that reads the keyboard input from USB UART device
and echos it back to the same device. It works as follows:

1. It registers an interrupt handler (uart_isr)
2. The handler reads input data and writes it to a buffer
3. Main loop prints the buffer

Unfortunatelly the ISR reads 15 characters from the early Zephyr
boot process standard output "*** Booting Zeph". Subsequent ISR calls
read keystrokes properly. An example application interaction can look as follows:


1. Zephyr boots
2. Main loop prints: `size: 16, buffer: *** Booting Zeph`
3. The user presses 1, 2, 3 on the keyboard
4. Main loop prints: `size: 16, buffer: *** Booting Zeph123`

The application code looks as follows:

#include <zephyr/kernel.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/device.h>
#include <stdint.h> // int32_t

uint32_t buffer_size = 0;
uint8_t buffer[64];

void uart_isr(const device *dev, void *user_data) {
    while (uart_irq_update(dev) == 1 && uart_irq_is_pending(dev) == 1) {
        if (uart_irq_rx_ready(dev) != 1) return;

        uint32_t remaining_space = sizeof(buffer) - buffer_size;
        if (remaining_space > 1) {
            buffer_size += uart_fifo_read(
                dev,
                &buffer[buffer_size],
                remaining_space - 1
            );
        }
    }
}

int main() {
    const device *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
    if (!device_is_ready(uart_dev)) return -ENODEV;
    if (uart_irq_callback_set(uart_dev, uart_isr)) return -ENODEV;

    uart_irq_rx_enable(uart_dev);

    while (1) {
        buffer[buffer_size] = 0;
        printk("size: %i, buffer: %s\n", buffer_size, buffer);
        k_msleep(3000); // give some time to accumulate data in the receive buffer
    }

    return 0;
}



prj.conf:
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y


The samples/subsys/console/getchar sample exhibits the same behaviour.
Did I do something wrong or is it a Zephyr bug?

Related