UART是一种串行、异步、全双工的通信协议,在嵌入式领域应用的非常广泛,调试阶段最基本的手段。开发者可以使用串口来调试,如获取boot log和kernel log信息。android可以通过adb,不过adb进程启动较晚,获取不到boot log信息。当bootloader加载linux时,可以通过cmdline.txt中的参数(其中115200表示传输速率,tty1表示使用的设备)把boot log输出到控制台(console),当启动过程出现异常时,可以通过boot log进行诊断。后面debug kernel会经常用到,这里记录下配置的过程。
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=698e33bd-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait init=/usr/lib/raspi-config/init_resize.sh splash plymouth.ignore-serial-consoles
UART 类型
Raspberry Pi有2种类型的串口可供使用:PL011和mini UART。
- PL011 UART为硬件串口,是由ARM设计或授权的,具有独立的时钟源,可靠性和性能好吞吐量高,通常是建议使用该串口通信;
- mini UART和VPU(Video Processing Unit,视频处理单元)核心频率有关,当VPU核心频率变化,UART的波特率也会变化,不是特别稳定。
注:Raspberry Pi 所有串口采用的电压为3.3V,如果用5V可能会损坏。
不同型号Raspberry Pi对应的UART类型有差异:
- Raspberry Pi Zero, 1, 2 and 3
Name | Type |
UART0 | PL011 |
UART1 | mini UART |
- Raspberry Pi 4 and 400
Name | Type |
UART0 | PL011 |
UART1 | mini UART |
UART2 | PL011 |
UART3 | PL011 |
UART4 | PL011 |
UART5 | PL011 |
注:The Raspberry Pi 4B和400有额外新增4个PL011串口,默认是关闭的
Primary UART和Secondary UART
Primary UART:为Pi的主串口,连接到硬件引脚上:GPIO14->TXD0; GPIO15->RXD0。
Secondary UART:为Pi的辅助串口,不存在于GPIO连接器上,通常被蓝牙控制器使用。
注;GPIO引脚上使用的一定是主串口,主串口和UART类型对应关系和Pi的型号有关系。
不同型号的Pi的对应关系:
Model | first PL011 | mini UART |
Raspberry Pi Zero | primary | secondary |
Raspberry Pi Zero W / Raspberry Pi Zero 2 W | secondary (Bluetooth) | primary |
Raspberry Pi 1 | primary | secondary |
Raspberry Pi 2 | primary | secondary |
Raspberry Pi 3 | secondary (Bluetooth) | primary |
Compute Module 3 & 3+ | primary | secondary |
Raspberry Pi 4 | secondary (Bluetooth) | primary |
上表可以看出Raspberry Pi 4上primary为mini UART(默认关闭),而secondary为PL011,被蓝牙使用。如果想要使用GPIO接串口板(USB转TTL)进行通信或调试,必须打开primary。可以查看/dev/设备确认:ls -l /dev/
UART初始化状态
打开primary串口步骤:
- sudo raspi-config
- 选择:3 - Interface Options.
- 选择:P6 - Serial Port.
- At the prompt Would you like a login shell to be accessible over serial? 选择: 'No'
- At the prompt Would you like the serial port hardware to be enabled? 选择: 'Yes'
硬串口serial0
/dev/下2个串口设备
mini UART由于时钟源采用的是VPU的(依据2023-02-04官方文档解释),所以并不是固定的,这样会导致UART波特率也会变化。修改参数做如下解释:
- 如果primary UART对应的是mini UART,打开后即配置了参数enable_uart=1,那VPU的时钟默认就固定为了250MHZ,不需要特殊设置其他参数。
- 如果secondary UART对应的是mini UART,需要在/boot/config.txt设置core_freq=250来固定时钟频率。
UART接线
如果想要PC和Raspberry Pi进行串口通信或者debug,需要借助USB转TTL小板,这里采用的CH340G模块,接线如下,CH340小板输入(rx)接Pi的输出(tx),CH340小板输出(tx)接Pi的输入(rx),CH340小板地线tx接Pi的地线。供电可以不用接,USB可以供电。
CH340接线
PC端安装串口助手,我这里使用的是友善串口调试助手,
Raspberry Pi端可以通过minicom(或screen)工具与PC端进行通信,选择其中一个即可,安装命令:
sudo apt-get install minicom
sudo apt-get install screen
运行命令,启动minincom,115200为波特率,ttyS0为对应GPIO pin脚的串口设备,
sudo minicom -D /dev/ttyS0 -b115200
或
sudo screen /dev/ttyAMA0 115200
minincom与串口助手通信
UART获取开机日志
linux虽然在启动阶段比较早的启动了UART,还是需要经过一定的时间,有些kernel启动异常无法诊断,可以通过以下2步获取更多的log信息,如start.elf debug信息:
1、在/boot/cmdline.txt设置earlycon参数来获取更早阶段的信息,添加以下信息,针对不同的PI型号设置:
注:如果型号和参数不对应,可能会导致Raspberry Pi起不来
- Raspberry Pi 4, 400:
earlycon=uart8250,mmio32,0xfe215040
earlycon=pl011,mmio32,0xfe201000
- Raspberry Pi 2, Pi 3:
earlycon=uart8250,mmio32,0x3f215040
earlycon=pl011,mmio32,0x3f201000
- Raspberry Pi 1, Pi Zero:
earlycon=uart8250,mmio32,0x20215040
earlycon=pl011,mmio32,0x20201000
cmdline.txt
2、在/boot/config.txt中添加uart_2ndstage=1,如下:
config.txt
3、重启查看串口助手信息:
kernel log
primary采用PL011
默认serial0为primary,serial1为secondary。而如果对串口通信性能有要求,需要更稳定,可以把serial0设置为PL011。Raspberry Pi 4B的PL011默认是被蓝牙使用,需要关闭,通过修改/boot/config.txt,,添加:dtoverlay=disable-bt或者dtoverlay=miniuart-bt。
注:上面的方式是官网给出的,文档有时效性(2023-02-04)。另外网上很多使用的是dtoverlay=pi3-miniuart-bt,尝试了下也是可以的,可能依据的是老文档。
关闭蓝牙
serial0修改后
打开UART2/3/4/5
The Raspberry Pi 4B默认有6个串口,其中没有打开,新手也可以直接通过打开其他的串口使用,就不用以上操作那么麻烦了。查看串口信息:dtoverlay -a|grep uart
uart信息
查看uart的GPIO信息,如查看uart3:dtoverlay -h uart3
uart3
在/boot/config.txt中打开uart2/3/4/5:
dtoverlay=uart2
dtoverlay=uart3
dtoverlay=uart4
dtoverlay=uart5
对应关系如下,用minicom测试时注意修改dev
UART | DEV | TX | RX |
UART2 | ttyAMA1 | GPIO0 | GPIO1 |
UART3 | ttyAMA2 | GPIO4 | GPIO5 |
UART4 | ttyAMA3 | GPIO8 | GPIO9 |
UART5 | ttyAMA4 | GPIO12 | GPIO13 |
串口无法通信
当线接好后,串口无法通信,可以排查是否为小板问题:
把串口小板短接,输入接输出:RX <-> TX,然后在PC端通过串口助手发送命令,如果有输出的情况下,说明小板通信没问题。
RX接TX
串口助手