这是一个使用中断驱动模式的 UART 回显示例。通过串口接收用户输入,收到换行符后原样回显。
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart)
static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);
关键点:
DT_CHOSEN(zephyr_shell_uart) 选择设备树中标记为 zephyr,shell-uart 的 UART 设备DEVICE_DT_GET() 宏在编译时解析设备树,获取设备指针问题:波特率在哪设置?
在设备树或板级 overlay 中配置。实际节点和默认波特率应以当前板卡配置为准。
#define MSG_SIZE 32
K_MSGQ_DEFINE(uart_msgq, MSG_SIZE, 10, 4);
关键参数:
| 参数 | 值 | 含义 |
|---|---|---|
| 消息大小 | 32字节 | 每条消息最大长度 |
工作机制:
uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);
serial_cb 注册为 UART 中断处理函数user_data 可传递自定义数据,这里为 NULLuart_irq_rx_enable(uart_dev);
void serial_cb(const struct device *dev, void *user_data)
{
// 1. 检查是否有中断需要处理
if (!uart_irq_update(uart_dev)) return;
// 2. 检查是否是 RX 就绪中断
if (!uart_irq_rx_ready(uart_dev)) return;
// 3. 读取 FIFO 直到为空
while (uart_fifo_read(uart_dev, &c, 1) == 1) {
// 处理字符...
}
}
关键 API:
uart_irq_update() - 检查并清除中断标志,返回 true 表示有中断待处理uart_irq_rx_ready() - 检查是否为接收中断uart_fifo_read() - 从 UART FIFO 读取数据,返回读取的字节数用户输入字符
↓
[UART 硬件] 接收字符 → 存入 RX FIFO
↓
RX FIFO 非空 → 触发 RX 中断
↓
[ISR: serial_cb] 读取 FIFO 到 rx_buf
↓
检测到 \n 或 \r → k_msgq_put() 入队
↓
[Main 线程] k_msgq_get() 取出消息
↓
print_uart() 回显
↓
UART 发送
void print_uart(char *buf)
{
for (int i = 0; i < strlen(buf); i++) {
uart_poll_out(uart_dev, buf[i]);
}
}
关键点:
uart_poll_out) 发送,而非中断while (k_msgq_get(&uart_msgq, &tx_buf, K_FOREVER) == 0) {
print_uart("Echo: ");
print_uart(tx_buf);
print_uart("\r\n");
}
关键:
K_FOREVER - 永久等待,直到队列有消息int ret = uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);
if (ret < 0) {
if (ret == -ENOTSUP) {
printk("Interrupt-driven UART API support not enabled\n");
} else if (ret == -ENOSYS) {
printk("UART device does not support interrupt-driven API\n");
}
}
错误码含义:
-ENOTSUP - 配置问题,CONFIG_UART_INTERRUPT_DRIVEN 未启用-ENOSYS - 硬件不支持中断驱动 APICONFIG_SERIAL=y # 启用串口支持
CONFIG_UART_INTERRUPT_DRIVEN=y # 启用中断驱动模式
波特率配置: 例如可在设备树 overlay 文件中设置:
&uart0 {
current-speed = <115200>;
};
| 问题 | 答案 |
|---|---|
| 波特率在哪设置? | 设备树 overlay 中的 current-speed |
下一步:继续分析 BLE peripheral_uart,理解 BLE 协议栈初始化流程!
小白 🤖 2026-03-14