isr + uart + thread testing

This commit is contained in:
2026-02-21 14:22:56 -07:00
parent 7a82e54414
commit 2ea338e289
2 changed files with 114 additions and 20 deletions

View File

@@ -3,5 +3,6 @@ CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_PRINTK=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_RING_BUFFER=y
CONFIG_PRINTK=y

View File

@@ -1,37 +1,130 @@
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/ring_buffer.h>
#define SLEEP_MS 2000
#include <string.h>
#define LED_NODE DT_ALIAS(led0)
#if !DT_NODE_HAS_STATUS(LED_NODE, okay)
#error "led0 not enabled in devicetree"
#endif
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart)
#define RX_BUF_SIZE 256
#define LINE_BUF_SIZE 128
#define THREAD_STACK 1024
#define THREAD_PRIO 5
// Ring buffer: callback writes, thread reads (could probably be a msg_queue too)
RING_BUF_DECLARE(rx_buf, RX_BUF_SIZE);
// Semaphore to wake the thread (name, initial count, max count)
K_SEM_DEFINE(rx_sem, 0, 1);
K_THREAD_STACK_DEFINE(rx_stack, THREAD_STACK);
static struct k_thread rx_thread_data;
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED_NODE, gpios);
static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(lpuart1));
void uart_print(const char buffer[]);
void uart_println(const char buffer[]);
void uart_cb(const struct device *dev, void *user_data);
static void rx_thread(void *p1, void *p2, void *p3);
int main(void)
{
printk("app started\n");
if (!gpio_is_ready_dt(&led))
if (!device_is_ready(uart))
{
printk("LED GPIO not ready\n");
return 0;
printk("UART not ready\n");
return -1;
}
int ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0)
{
printk("LED GPIO configure failed: %d\n", ret);
// Set up interrupt-driven RX
uart_irq_callback_set(uart, uart_cb);
uart_irq_rx_enable(uart);
// Spawn the processing thread
k_thread_create(&rx_thread_data, rx_stack,
THREAD_STACK,
rx_thread, NULL, NULL, NULL,
THREAD_PRIO, 0, K_NO_WAIT);
printk("UART ready — type something!\r\n");
return 0;
}
// ============= Helpers =============
void uart_print(const char buffer[])
{
size_t len = strlen(buffer);
for (size_t i = 0; i < len; i++)
uart_poll_out(uart, buffer[i]);
}
void uart_println(const char buffer[])
{
uart_print(buffer);
uart_poll_out(uart, '\r');
uart_poll_out(uart, '\n');
}
// ============= Callbacks =============
void uart_cb(const struct device *dev, void *user_data)
{
uint8_t byte;
while (uart_irq_update(dev) && uart_irq_rx_ready(dev))
{
if (uart_fifo_read(dev, &byte, 1) == 1)
{
ring_buf_put(&rx_buf, &byte, 1);
}
}
char incoming;
int i = 0;
// wake up thread
k_sem_give(&rx_sem);
}
// ============= Threads =============
static void rx_thread(void *p1, void *p2, void *p3)
{
char line[LINE_BUF_SIZE];
size_t pos = 0;
while (1)
{
k_sem_take(&rx_sem, K_FOREVER);
uint8_t byte;
while (ring_buf_get(&rx_buf, &byte, 1) == 1)
{
// Echo the character back
uart_poll_out(uart, byte);
if (byte == '\r' || byte == '\n')
{
if (pos > 0)
{
line[pos] = '\0';
printk("\r\n");
printk("─────────────────────────────\r\n");
printk("│ RX: %-24s \r\n", line);
printk("│ Len: %-3d, Time: %-10u \r\n",
pos, k_uptime_get_32());
printk("─────────────────────────────\r\n");
pos = 0;
}
}
else if (pos < LINE_BUF_SIZE - 1)
{
line[pos++] = byte;
}
}
}
}