树莓派4B串口配置避坑指南:如何正确映射serial0到ttyS0(附蓝牙禁用技巧)
树莓派4B串口配置避坑指南:如何正确映射serial0到ttyS0(附蓝牙禁用技巧)
如果你正在用树莓派4B做物联网项目,比如连接传感器、驱动显示屏或者和单片机通信,大概率会用到串口。但当你兴冲冲地接好线,打开终端准备大干一场时,却发现/dev目录下空空如也——说好的serial0和ttyS0呢?更别提它们之间的映射关系了。这个问题在树莓派4B上尤其常见,特别是当你用的不是官方的Raspberry Pi OS,而是Ubuntu、Ubuntu Mate这类第三方系统时,情况会更加复杂。
我刚开始用树莓派4B做环境监测项目时就踩过这个坑。当时需要连接一个温湿度传感器,按照网上搜到的树莓派3B教程折腾了半天,enable_uart=1也加了,raspi-config里的串口也开了,可serial0就是不出来。后来才发现,树莓派4B的启动文件路径、蓝牙管理机制都和3B有细微但关键的差别。这些差别如果没搞清楚,就会像无头苍蝇一样乱撞,白白浪费好几个小时。
这篇文章就是为你梳理清楚树莓派4B串口配置的完整逻辑。我们不仅会解决“serial0不见了”这个表面问题,更会深入理解背后的原因:为什么会有ttyAMA0和ttyS0?serial0和serial1这两个符号链接到底代表什么?蓝牙功能又是如何影响串口分配的?弄明白这些,以后无论遇到什么奇怪的串口问题,你都能自己找到解决思路。
1. 理解树莓派4B的串口体系:PL011与Mini UART
在开始动手修改配置文件之前,我们有必要先搞清楚树莓派4B硬件上到底有哪些串口资源,以及操作系统是如何管理它们的。很多配置问题之所以发生,就是因为对底层硬件缺乏了解,盲目照搬教程导致的。
树莓派4B内部实际上有多个UART(通用异步收发传输器),但最常被我们使用的是其中两个:UART0和UART1。
- UART0:这是一个PL011类型的UART。PL011是一个功能比较完整的16550兼容UART,支持硬件流控制(RTS/CTS),性能稳定,适合高速率或需要可靠通信的场景。
- UART1:这是一个Mini UART。顾名思义,它是PL011的简化版,功能上有所缩减。它的波特率依赖于核心时钟频率,如果核心时钟频率发生变化(比如为了省电而降频),Mini UART的波特率就会漂移,导致通信错误。因此,它通常用于对速率和稳定性要求不高的场景。
在Linux系统中,这两个物理UART会对应到不同的设备文件:
| Linux设备文件 | 对应的物理UART | UART类型 | 默认状态 |
|---|---|---|---|
/dev/ttyAMA0 |
UART0 | PL011 | 启用 |
/dev/ttyS0 |
UART1 | Mini UART | 禁用 |
看到这里你可能要问:那我应该用ttyAMA0还是ttyS0呢?这就是serial0和serial1这两个符号链接存在的意义。它们不是真实的设备,而是指向当前“主串口”和“辅串口”的快捷方式。系统会根据配置动态决定serial0是指向ttyAMA0还是ttyS0。这样,你的应用程序只需要固定使用/dev/serial0,而不用关心底层硬件映射的具体情况,提高了代码的兼容性。
提示:始终建议在你的应用程序中使用
/dev/serial0或/dev/serial1,而不是直接使用ttyAMA0或ttyS0。这样即使未来硬件映射关系因系统更新或配置改变而发生变化,你的程序也无需修改。
那么,默认的映射关系是怎样的呢?这就要说到一个关键的“第三者”——蓝牙。
2. 蓝牙与串口的爱恨纠葛:资源冲突与解决方案
树莓派4B的板载蓝牙模块也需要一个UART来与主处理器通信。默认情况下,这个重任落在了功能更强的PL011 UART(即UART0,ttyAMA0) 上。这就产生了一个矛盾:蓝牙占用了ttyAMA0,而ttyS0(Mini UART)默认又是关闭的。
所以,当你第一次启动树莓派4B(尤其是安装Ubuntu等系统)后,执行ls -l /dev/serial*命令,很可能会看到这样的结果:
lrwxrwxrwx 1 root root 7 Apr 10 10:30 /dev/serial1 -> ttyAMA0
只有serial1指向了ttyAMA0(被蓝牙占用),而serial0根本不存在,因为它的候选目标ttyS0还没被启用。这就是我们遇到的核心问题。
解决思路有两条:
- 启用Mini UART(
ttyS0),并让serial0指向它。这样你就有了一个可用的串口,但蓝牙依然占用着更好的PL011 UART。 - 将蓝牙从PL011 UART上移走,从而释放
ttyAMA0,然后让serial0指向这个更稳定的UART。这通常需要禁用蓝牙,或者将蓝牙切换到Mini UART上。
对于大多数物联网硬件调试场景,我们通常不需要蓝牙功能,因此方案2——禁用蓝牙并释放PL011 UART——是更优的选择,能获得一个性能更可靠的串口。下面我们就来详细讲解这两种方案的具体操作。
3. 方案一:启用UART并检查映射(基础步骤)
无论你最终选择哪种方案,第一步都是确保UART功能已经在底层被启用。这个配置是通过修改启动配置文件完成的。
关键点:找到正确的config.txt文件 在树莓派4B上,尤其是使用Ubuntu及其衍生版本(如Ubuntu Mate、Ubuntu Server)时,启动配置文件的位置可能与经典的Raspberry Pi OS不同。它通常位于/boot/firmware/目录下,而不是/boot/。这是第一个容易踩坑的地方。
-
连接到你的树莓派4B,打开终端。
-
首先检查当前的串口设备状态,建立一个基准:
ls -l /dev/serial*如果输出是
ls: cannot access '/dev/serial*': No such file or directory,说明serial0和serial1都不存在。如果只有serial1,记下它指向哪里。 -
导航到启动目录并编辑配置文件:
cd /boot/firmware sudo nano config.txt使用
nano、vim或你喜欢的任何编辑器。 -
在
config.txt中启用UART。你需要找到[all]或[pi4]这样的分区标签(section),在相应分区内添加或修改以下行:[all] # 启用UART enable_uart=1如果文件中已经存在
enable_uart=0,请将其改为1,或者直接注释掉(在行首加#),然后另起一行写上enable_uart=1。 -
保存文件并重启:
sudo reboot -
重启后再次检查:
ls -l /dev/serial*现在,你很可能会看到:
lrwxrwxrwx 1 root root 5 May 20 14:25 /dev/serial0 -> ttyS0 lrwxrwxrwx 1 root root 7 May 20 14:25 /dev/serial1 -> ttyAMA0这意味着系统启用了Mini UART(
ttyS0),并将其作为主串口(serial0)。蓝牙仍然占用着ttyAMA0(serial1)。
此时,/dev/serial0已经可用,你可以用它连接传感器或其他设备。但是,如果你对这个Mini UART的性能(特别是波特率稳定性)有疑虑,或者你根本不需要蓝牙,那么请继续看方案二。
4. 方案二:禁用蓝牙,获取高性能PL011 UART
这个方案的目标是让serial0指向更强大的ttyAMA0。为此,我们需要做两件事:在设备树(Device Tree)层面将蓝牙与PL011 UART解绑,并禁用相关的蓝牙服务。
-
继续编辑
/boot/firmware/config.txt文件:sudo nano /boot/firmware/config.txt -
在之前添加的
enable_uart=1下面,添加一行设备树覆盖参数来禁用蓝牙:[all] enable_uart=1 dtoverlay=disable-bt这行
dtoverlay=disable-bt的作用是告诉内核,在启动时加载一个“禁用蓝牙”的覆盖层。这个操作会在硬件层面将蓝牙模块与PL011 UART断开连接,从而释放ttyAMA0供我们使用。 -
保存并退出编辑器。
-
禁用蓝牙服务(可选但推荐)。虽然设备树覆盖层禁用了硬件连接,但系统可能仍会尝试启动蓝牙服务,导致错误日志。我们可以禁用这些服务:
sudo systemctl disable bluetooth.service sudo systemctl disable hciuart.servicebluetooth.service是管理蓝牙功能的高级服务。hciuart.service是负责通过UART与蓝牙芯片通信的低级服务。禁用disable-bt后,这个服务会因为找不到设备而失败,所以最好也禁用它。
-
重启树莓派:
sudo reboot -
验证结果。重启后,再次列出串口设备:
ls -l /dev/serial*如果一切顺利,你现在应该看到映射关系已经“交换”了:
lrwxrwxrwx 1 root root 7 May 20 14:30 /dev/serial0 -> ttyAMA0 lrwxrwxrwx 1 root root 5 May 20 14:30 /dev/serial1 -> ttyS0成功! 现在
serial0指向了PL011 UART(ttyAMA0),这是一个功能完整、性能稳定的串口。serial1则指向了Mini UART(ttyS0)。蓝牙功能已被完全禁用,在桌面环境的右上角应该看不到蓝牙图标了。
5. 高级调试与故障排查
即使按照上述步骤操作,有时可能还是会遇到问题。别担心,我们可以通过一系列调试命令来定位问题所在。
1. 检查内核启动信息 dmesg命令可以显示内核启动和运行过程中的消息,其中包含UART设备初始化的信息。
dmesg | grep -E \"tty(AMA|S)|serial|uart\"
关注输出中是否有关于ttyAMA0、ttyS0、serial8250等设备的成功注册或错误信息。
2. 验证GPIO引脚复用 树莓派的GPIO引脚有多种功能(复用),我们需要确保引脚14和15被正确设置为UART功能(TXD0和RXD0)。可以使用raspi-gpio工具(如果已安装):
raspi-gpio get 14-15
查看func字段,对于UART0的TXD和RXD,它应该显示ALT0。
3. 进行回环测试(Loopback Test) 这是检验串口硬件和驱动是否正常工作的终极方法。你需要一个跳线帽或一小段导线。
- 物理连接:将树莓派GPIO的引脚8(TXD0)和引脚10(RXD0) 用导线短接。这样,从这个串口发送的数据会被自己接收回来。
- 安装测试工具:安装
minicom或screen。sudo apt update sudo apt install minicom -y - 进行测试:
- 在一个终端窗口,监听
/dev/serial0:minicom -b 115200 -D /dev/serial0 - 进入minicom后,你键入的每一个字符,都应该在屏幕上显示两次:一次是你敲击键盘发送的,一次是通过回环线路接收回来的。如果只显示一次,说明数据没有成功“发出-收回”,串口可能未正常工作。
- 按
Ctrl+A,然后按X退出minicom。
- 在一个终端窗口,监听
4. 检查启动分区 如果修改/boot/firmware/config.txt后完全不起作用,请确认你是否编辑了正确的文件。有时,特别是从SD卡直接读写时,可能存在多个config.txt。可以检查一下/boot目录下是否也有一个config.txt。
常见问题与解决思路表:
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
修改config.txt后无任何变化 |
1. 编辑了错误的文件。 2. 文件语法错误。 3. 需要冷重启(完全断电再上电)。 |
1. 确认路径是/boot/firmware/config.txt。2. 用 sudo cat /boot/firmware/config.txt检查内容。3. 执行 sudo shutdown -h now,拔电后再启动。 |
只有serial1,没有serial0 |
Mini UART (ttyS0) 未被启用。 |
确保config.txt中有enable_uart=1,且没有拼写错误。 |
serial0指向ttyS0,但通信不稳定 |
Mini UART的波特率受核心时钟影响。 | 1. 考虑改用方案二,获取ttyAMA0。2. 或在 config.txt中固定核心频率:core_freq=250。 |
添加dtoverlay=disable-bt后无法启动 |
设备树覆盖层冲突或错误。 | 1. 检查config.txt中是否有其他dtoverlay行与之冲突。2. 尝试在SD卡读卡器上编辑文件,移除该行。 |
| 回环测试时无回显 | 1. 引脚接错。 2. 串口被系统控制台占用。 |
1. 确认短接的是引脚8 (TXD)和10 (RXD)。 2. 检查 /boot/firmware/cmdline.txt,确保其中没有console=serial0或console=ttyAMA0这样的参数。 |
关于最后一点“串口被控制台占用”需要特别说明。Linux系统可以将一个串口用作内核和系统的控制台(Console),这会独占该串口,导致你的应用程序无法使用。在树莓派上,如果你从未设置过串口控制台,那么/boot/firmware/cmdline.txt文件里通常不会有相关参数,可以不用管。但如果你之前用raspi-config工具开启过串口登录,就需要检查并清理cmdline.txt。
折腾树莓派串口的过程,很像是在和一台精密的仪器对话,你需要理解它的“语言”(硬件映射)和“习惯”(系统配置)。一旦打通了这个关节,后面连接各种传感器、执行器就会变得畅通无阻。我自己的项目里,在正确配置串口后,曾经不稳定的GPS模块数据解析立刻变得丝滑流畅,那种感觉就像给堵塞的管道做了一次彻底的疏通。硬件编程的乐趣,往往就藏在这些看似繁琐的配置细节之后。
更多推荐
所有评论(0)