Driver: UART FIFO¶
1 功能概述¶
本例程演示了 Zephyr UART (Serial) Driver 的基本使用方法。
2 环境要求¶
PAN1080 EVB 一块
USB-TypeC 线一条(用于供电和查看串口打印 Log)
硬件接线:
使用 USB 线,将 PC USB 与 EVB USB-TypeC(USB->UART)相连
使用杜邦线将 EVB 上的:
TX0 与 P00 相连
RX0 与 P01 相连
另准备一个 USB 转串口模块,将其 RX 连到芯片 P06 (UART0-Tx) 引脚,TX 连到芯片 P07 (UART0-Rx) 引脚
PC 软件: 串口调试助手(UartAssist)或终端工具(SecureCRT)
3 编译和烧录¶
例程位置:zephyr\samples_panchip\drivers\uart\uart_fifo
使用 ZAL 工具可以对其进行编译、烧录、打开 VS Code 调试等操作。关于 ZAL 工具的详细介绍请参考:Zephyr APP Launcher 工具介绍。
4 演示说明¶
首先在 PC 上打开 2 个串口终端:
第一个选择与芯片 P00/P01 (UART0) 相连的串口号,波特率配置为 921600,用于显示 Log 打印
第二个选择与芯片 P06/P07 (UART1) 相连的串口号,波特率配置为 115200,用作待测 UART 交互
成功编译烧录程序后,按 EVB 板上的复位按钮,执行芯片复位,可以看到第一个串口终端打印了如下的 Log:
*** Booting Zephyr OS build zephyr-v2.7.0 *** Start uart fifo demo.. UART configure done, exit main thread.
然后向第二个串口终端发送
1234567890asdfghjklzxcvbnm\n
并回车,可以看到接收界面随后显示了1234567890asdfghjklzxcvbnm
,说明例程成功从 UART1 Rx 引脚接收到了数据,并转发到 UART1 Tx 引脚,最终发送到 PC 终端。
5 开发说明¶
5.1 使能 UART Driver¶
确认
CONFIG_UART=y
,以将 UART Driver 正确加入编译确认 Devicetree 或 DTS Overlay 配置文件中 UART 模块的:
status 属性值为
okay
,以确保系统在启动阶段能正确初始化 UART 模块pinctrl-0 属性中正确配置了 pinmux 引脚参数
/* pan108xxb5_evb.dts */ ... &uart0 { current-speed = <921600>; pinctrl-0 = <&p0_0_uart0_tx &p0_1_uart0_rx>; status = "okay"; }; &uart1 { current-speed = <115200>; pinctrl-0 = <&p0_6_uart1_tx &p0_7_uart1_rx>; status = "okay"; }; ...
5.2 确认 UART 初始化成功¶
const struct device *uart0 = DEVICE_DT_GET(DT_NODELABEL(uart0));
if (!device_is_ready(uart0)) {
printk("uart devices not ready\n");
return;
}
5.3 配置 UART 通信参数¶
配置串口的波特率、校验位、停止位、数据位和流控:
#define BAUDRATE 115200 const struct uart_config uart_cfg = { .baudrate = BAUDRATE, .parity = UART_CFG_PARITY_NONE, .stop_bits = UART_CFG_STOP_BITS_1, .data_bits = UART_CFG_DATA_BITS_8, .flow_ctrl = UART_CFG_FLOW_CTRL_NONE };
串口配置读取与设置:
uart_config_get(uart0, &uart_cfg_check); if(uart_cfg_check.baudrate != BAUDRATE) { uart_configure(uart0, &uart_cfg); }
5.4 UART中断回调和使能¶
中断回调注册:
uart_irq_callback_set(uart0, uart_fifo_callback);
使能UART TRX:
uart_irq_tx_enable(uart0); uart_irq_rx_enable(uart0);
TX的逻辑处理:
static void tx_isr(const struct device *dev) { static uint8_t tx_index = 0; int len; if(tx_index >= data_len) { uart_irq_tx_disable(dev); uart_irq_rx_enable(dev); tx_index = 0; } else { len = uart_fifo_fill(dev, fifo_data + tx_index, (data_len - tx_index)); tx_index += len; if(tx_index >= BUFFER_SIze) { tx_index = 0; } } }
将tx的数据写到fifo中,直到所有的数据都写完,然后关闭tx,使能rx,等待数据接收。fifo的最大深度为16。
RX的逻辑处理:
static void rx_isr(const struct device *dev) { static uint8_t rx_index = 0; uart_fifo_read(dev, fifo_data + rx_index, 1); if ((fifo_data[rx_index] == '\n') || (fifo_data[rx_index] == '\r')) { uart_irq_rx_disable(dev); data_len = rx_index + 1; rx_index = 0; uart_irq_tx_enable(dev); } else { rx_index ++; if(rx_index >= BUFFER_SIze) { rx_index = 0; } } }
将串口工具发过来的数据保存到“fifo_data”,每次接收一个数据,直到出现换行符,停止接收。然后将接收的数据原封不动的发送给串口工具。
6 RAM/Flash资源使用情况¶
Memory region Used Size Region Size %age Used
FLASH: 16492 B 1020 KB 1.58%
SRAM: 3960 B 64 KB 6.04%
IDT_LIST: 0 GB 2 KB 0.00%