UART
概述
本文主要说明Rockchip系列芯片UART的使用和调试方法,包括UART作为普通串口和控制台两种不同使用场景。
产品版本
读者对象
本文档(本指南)主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
功能特点
Rockchip UART (Universal Asynchronous Receiver/Transmitter) 基于16550A串口标准,完整模块支持以下功能:
- 支持5、6、7、8 bits数据位。
- 支持1、1.5、2 bits停止位。
- 支持奇校验和偶校验,不支持mark校验和space校验。
- 支持接收FIFO和发送FIFO,一般为32字节或者64字节。
- 支持最高4M波特率,实际支持波特率需要芯片时钟分频策略配合。
- 支持中断传输模式和DMA传输模式。
- 支持硬件自动流控,RTS+CTS。
注意,实际芯片中的UART支持的功能请以芯片手册中UART章节的描述为准,部分UART功能会进行适当裁剪。
作为普通串口
2.1 驱动路径
在Linux kernel 3.10中,使用以下驱动文件:
drivers/tty/serial/rk_serial.c
在Linux kernel 4.4和Linux kernel 4.19中,使用8250串口通用驱动,以下为主要驱动文件:
drivers/tty/serial/8250/8250_core.c
# 8250串口驱动核心drivers/tty/serial/8250/8250_dw.c
# Synopsis DesignWare 8250串口驱动drivers/tty/serial/8250/8250_dma.c
# 8250串口DMA驱动drivers/tty/serial/8250/8250_port.c
# 8250串口端口操作drivers/tty/serial/8250/8250_early.c
# 8250串口early console驱动
2.2 menuconfig配置
在不同版本的Linux kernel中,UART相关的menuconfig配置均在以下路径选项,选项说明十分详细,这里不再展开:
Device Drivers --->
Character devices --->
Serial drivers --->
建议使用Rockchip SDK中提供的UART默认配置。
2.3 dts配置
在不同版本的Linux kernel中,UART的dts配置均与以下典型配置类似。以下典型配置以Linux kernel 4.19 RK3568芯片为例,在rk3568.dtsi
中:
UART的板级dts配置只有以下参数允许修改:
dma-names
:"tx"
打开tx dma"rx"
打开rx dma"!tx"
关闭tx dma"!rx"
关闭rx dma
pinctrl-0
:&uart1m0_xfer
配置tx和rx引脚为iomux group 0&uart1m1_xfer
配置tx和rx引脚为iomux group 1&uart1m0_ctsn
和&uart1m0_rtsn
配置硬件自动流控cts和rts引脚为iomux group 0&uart1m1_ctsn
和&uart1m1_rtsn
配置硬件自动流控cts和rts引脚为iomux group 1
status
:"okay"
打开"disabled"
关闭
例如,打开RK3568 UART1,打开dma,配置打开了硬件自动流控的UART1的tx、rx、cts、rts的iomux为group0,在板级dts里的配置如下:
uart1: serial@fe650000 {
compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
reg = <0x0 0xfe650000 0x0 0x100>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
dmas = <&dmac0 2>, <&dmac0 3>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1m0_xfer>;
status = "disabled";
};
&uart1 {
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
status = "okay";
};
需要注意,参数pinctrl-0
中对于硬件自动流控的操作仅仅是配置引脚iomux,实际使能硬件自动流控的操作在UART驱动中,如果不需要使用硬件自动流控,cts和rts引脚的iomux配置可以去掉。
2.4 波特率配置
UART波特率 = 工作时钟源 / 内部分频系数 / 16。当工作时钟源由24M晶振直接提供时,UART将使用内部时钟分频系数得到需要的波特率。当工作时钟源由CRU模块通过PLL分频提供时,UART波特率一般为工作时钟源的1/16。UART实际允许配置的波特率和此波特率下数据传输的稳定性在软件上主要由UART工作时钟分频策略决定。
目前,UART驱动会根据配置的波特率大小自动去获取需要的工作时钟频率,可以通过以下命令查询到UART工作时钟频率:
cat /sys/kernel/debug/clk/clk_summary | grep uart
Rockchip UART对常用的波特率,如115200、460800、921600、1500000、3000000、4000000 等确保稳定支持。对于一些特殊的波特率,可能需要修改工作时钟分频策略才能支持。
2.5 使用DMA
UART使用DMA传输模式只有在数据量很大时才会产生较为明显的减轻CPU负载的效果。一般情况下,和使用中断传输模式相比,UART使用DMA传输模式并不一定能提高数据传输速度。一方面,现在CPU性能都很高,传输瓶颈在外设。另一方面,启动DMA需要消耗额外的资源,并且由于UART数据存在长度不确定的特性,会使DMA传输效率下降。
因此,建议一般情况下使用默认中断传输模式,会有以下打印:
在DMA通道资源紧张的使用场景下,可以考虑关掉TX的DMA传输,会有以下打印:
failed to request DMA, use interrupt mode
got rx dma channels only
2.6 使用硬件自动流控
UART使用硬件自动流控时,需要确保UART驱动使能硬件自动流控功能,且在dts中已经切换cts和rts流控引脚的iomux。建议在高波特率(1.5M波特率及以上)、大数据量的场景下都使用硬件自动流控,即使用四线UART。
2.7 使用串口唤醒系统
串口唤醒系统功能是在系统待机时串口保持打开,并且把串口中断设置为唤醒源。使用时需要在dts中增加以下参数:
&uart1 {
wakeup-source;
};
注意,串口唤醒系统需要同时修改trust固件,请联系Rockchip以获取支持。
2.8 设备注册
在dts中使能UART后,能在系统启动的log中看到以下对应的打印,表示设备正常注册:
普通串口设备将会根据dts中的aliase来对串口进行编号,对应注册成ttySx设备。dts中的aliases如下:
aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
......
};