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?