UART 串口驱动
本文档介绍 RK3588 UART 控制器在 Linux 6.1 内核中的驱动配置、设备树绑定、调试串口的使用方法,以及 RS485 模式的开启方式。
适用范围: RK3588 Linux 6.1 Debian 12 / Ubuntu 22.04 系统,C-3588LQ V1.0 + SHIMETAPI-M5-R2A V1.0 底板。
1. 概念基础
1.1 UART 是什么
UART(Universal Asynchronous Receiver/Transmitter)是异步串行通信接口,收发双方不共时钟线,靠事先约定的波特率对齐数据。RK3588 内置 10 路 UART,每个都支持:
- 数据位 5/6/7/8
- 校验位 None / Odd / Even
- 停止位 1 / 1.5 / 2
- 内置 32 字节 FIFO + DMA
- 最高 4 Mbps
1.2 控制器基地址
| 控制器 | 基地址 |
|---|---|
| UART0 | 0xfea90000 |
| UART1 | 0xfeaa0000 |
| UART2 | 0xfe660000 |
| UART3 | 0xfe670000 |
| UART4 | 0xfe680000 |
| UART5 | 0xfe690000 |
| UART6 | 0xfe6a0000 |
| UART7 | 0xfe6b0000 |
| UART8 | 0xfe6c0000 |
| UART9 | 0xfe6d0000 |
驱动源码
drivers/tty/serial/8250/8250_of.c(Rockchip UART 兼容 8250)。
2. 准备工作
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3588LQ 核心板 + SHIMETAPI-M5-R2A 底板 | 1 | |
| USB 转 TTL 模块 | CH340 / CP2102 / FT232 | 1 | 用于调试串口连接 |
| 串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| GPS 模块(可选) | BN-220 / NEO-6M | 1 | UART 接口 |
| 杜邦线 | 母对母 | 若干 |
2.2 调试串口引脚
| 主控板引脚 | USB 转 TTL 模块 | 功能说明 |
|---|---|---|
| DEBUG_TX(Sheet 6/21) | RXD | 调试输出 |
| DEBUG_RX(Sheet 6/21) | TXD | 调试输入 |
| GND | GND | 共地 |
引脚对应 GPIO0_B6_D / GPIO0_B5_D,板载 1500000 波特率。接线时注意 TX、RX 要交叉接。
2.3 扩展串口(UART4 示例)
| 主控板引脚 | 外设引脚 | 功能说明 |
|---|---|---|
| UART4_TX(Sheet 12/21) | GPS TX | 串口输出 |
| UART4_RX(Sheet 12/21) | GPS RX | 串口输入 |
| 3.3V | GPS VCC | 电源 |
| GND | GPS GND | 共地 |
3. 软件准备
3.1 内核配置
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y /* 8250 generic */
CONFIG_SERIAL_ROCKCHIP_CONSOLE=y /* 控制台重定向支持 */
CONFIG_OF=y
CONFIG_OF_SERIAL=yRK3588 UART 兼容 8250 框架,驱动自动绑定到
serial8250。
3.2 设备树
SoC 级定义(rk3588.dtsi):
uart2: serial@fe660000 {
compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
reg = <0x0 0xfe660000 0x0 0x100>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
clock-names = "baudclk", "apb_pclk";
pinctrl-names = "default";
pinctrl-0 = <&uart2m0_xfer>;
reg-shift = <2>;
reg-io-width = <4>;
status = "okay"; /* 调试串口默认开 */
};4. 调试串口(U-Boot 控制台)
先看看出厂镜像把 console(内核日志和控制台输出所重定向到的设备)设在了哪个串口上:
# 查看当前 console
cat /proc/cmdline | grep -o 'console=[^ ]*'实机输出如下:
console=ttyFIQ0默认 console 是 Rockchip FIQ 调试串口(
/dev/ttyFIQ0),内核启动早期就能用它看到输出。常规 16550A UART 在/dev/ttyS9(ttyS9 at MMIO 0xfebc0000, base_baud=1500000)。
[电脑端] 连接 USB 转 TTL 后,用 1500000 波特率打开:
sudo minicom -d /dev/ttyUSB0 -b 1500000如需切换 console:
# 在 U-Boot 中改 bootargs
setenv bootargs 'earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0'
# 或用常规 UART:
setenv bootargs 'console=ttyS2,1500000n8'5. 用户态串口操作(开发板)
5.1 设置串口参数
stty -F /dev/ttyS9 1500000 raw -echo -echoe -echok几个参数的含义:
raw:原始模式(无处理)-echo:不回显1500000:波特率
5.2 收发数据
# 发送
echo "Hello RK3588" > /dev/ttyS9
# 接收(cat 阻塞)
cat /dev/ttyS95.3 通过 minicom 串口交互
apt install -y minicom
minicom -D /dev/ttyS9 -b 1500000退出:Ctrl-A → X。
5.4 串口状态查询
# 查看当前串口详细配置
stty -F /dev/ttyS9 -a
# 查看中断号
cat /proc/interrupts | grep uart
# 查看 UART 时钟
cat /sys/kernel/debug/clk/clk_uart/clk_rate6. RS485 模式(PC 端配置)
[电脑端] 编辑板级 .dts,开启 UART4 的 RS485:
&uart4 {
status = "okay";
pinctrl-0 = <&uart4m0_xfer &uart4m0_ctsn>;
/* RS485 模式 */
linux,rs485-enabled-at-boot-time;
rs485-rts-delay-low = <1>;
rs485-rts-delay-high = <1>;
};电脑端 重编译烧录后,设备端可以用下面的命令确认 RS485 已生效:
cat /sys/class/tty/ttyS4/device/rs4857. 代码解读
7.1 驱动注册
// drivers/tty/serial/8250/8250_of.c(简化,使用 8250 通用驱动)
static struct of_device_id rockchip_8250_match[] = {
{ .compatible = "rockchip,rk3588-uart" },
{ /* sentinel */ }
};7.2 用户态调用链
用户空间: open(/dev/ttyS9)
→ tty_open()
→ uart_open()
→ rockchip_8250_startup()
→ 配置 8250 寄存器、启用 FIFO
用户空间: write()
→ tty_write()
→ uart_write()
→ rockchip_8250_tx_chars()
→ 数据写入 UART 发送 FIFO8. 故障排除
8.1 调试串口无输出
按下面的顺序逐项排查:
- 串口线是否交叉连接(TX 接 RX)
- 波特率是否为 1500000(出厂默认;PC 端
minicom -b 1500000) - 当前 console 设备是哪个(
console=ttyFIQ0还是ttyS2,参考cat /proc/cmdline) - 内核启动是否正常(看 indicator LED 和核心板电源指示)
- USB 转 TTL 模块电平是否 3.3V
8.2 串口乱码
乱码多半是两边参数不一致,先确认配置:
stty -F /dev/ttyS9 -a # 确认配置
# 波特率 / 数据位 / 停止位 / 校验 应匹配出厂默认:1500000 8N1。
8.3 高速传输丢字节
可以按下面的方向优化:
- 设备树中启用 DMA(
dmas = <&dmac ...>) - 流控:
stty -F /dev/ttyS9 crtscts - 加大驱动 TX/RX FIFO(驱动已默认 32 字节)
