资讯详情

Ubuntu 22.04 CH340串口驱动排查:不是缺驱动,而是没加载、没权限

📅 2026/10/16 2:00:12 | 华诺云谱 👁 阅读
Ubuntu 22.04 CH340串口驱动排查:不是缺驱动,而是没加载、没权限
简介在 Ubuntu 22.04 中为 CH340 芯片安装串口驱动是许多 USB 转串口开发者与硬件爱好者都会遇到的常见问题由于 Linux 内核默认没有包含该芯片的驱动程序需要手动编译或加载对应模块。这套资源共 16 个文件压缩包仅 291KB内容以 C 语言驱动源码、预编译内核模块、Makefile 构建脚本和 readme 说明为主其余为编译过程产生的辅助文件可同时覆盖从源码编译安装和直接加载预编译模块两种路径。无论是用于开发板调试、嵌入式设备通信还是工业控制场景下的 USB 转串口对接正确安装驱动都是建立串口通信链路的基础。已有 778 人学习下载适合具备基础 Linux 命令行操作经验、希望快速解决设备无法识别问题的用户。借助包内说明与构建配置可以完成依赖包安装、模块编译加载、设备识别检查以及串口权限配置遇到编译报错或设备识别异常时这些资料也能作为定位问题的参考。1. Ubuntu 22.04 装 CH340 串口驱动多数时候不是缺驱动而是没加载、没权限插上一块 USB 转 TTL 的小板子ls /dev/ttyUSB0 什么都没有很多人的第一反应是“ubuntu 22.04 安装 CH340 串口驱动”然后满世界找驱动包。实际上 Ubuntu 22.04 的内核 5.15 早就把 CH340 的驱动编进系统里了模块名叫 ch341不叫 ch340。你真正用不起来大概率是驱动没加载、设备没枚举或者是权限不够。这篇文章按实际排查顺序把 lsusb、dmesg、modprobe、dialout 组、udev 规则和常见翻车点挨个过一遍照着敲命令就能定位问题。适合正在用 Ubuntu 调单片机、机器人底板或某跨平台系统串口外设的开发者新手能跟到底熟手也能快速对照排查。2. 先搞懂内核自带 ch341设备从 USB 到 ttyUSB0 的识别链路一个 USB 转串口设备要能被你打开至少要经过两层USB 控制器先把设备枚举出来然后内核的 usbserial 子系统把它转成一个字符设备 /dev/ttyUSB0。CH340 在 Linux 里的驱动模块名是 ch341这个命名几乎坑过每个从 Windows 转过来的开发者因为 Windows 下驱动都叫 CH340。绝大部分 Ubuntu 22.04 的内核都编译了这个模块。所以遇到问题别急着找驱动源码先把链路拆开检查。2.1 用 lsusb 确认硬件1a86:7523 是第一道门槛设备都没枚举上谈驱动就没有意义。插上模块后执行lsusb正常输出里会出现这样一行Bus 001 Device 004: ID 1a86:7523 CH340 serial converter1a86:7523 是 CH340/CH341 最常见的厂商 ID 和产品 ID。如果你看到的是别的 ID比如新款芯片可能出现的 1a86:55d4 这类值说明硬件不一定是 CH340 系列老内核的 ch341 驱动不一定认得。如果 lsusb 里根本没有新增行那问题在物理链路最常见的是 USB 线只供电不通数据或者插在了供电不足的前置面板上。换一根短的数据线直接插主板后置口再试。这一步还附带筛选作用市面上一批低价的 CH340 打磨片枚举 ID 一样是 1a86:7523但工作起来发热明显、波特率偏移、丢字节。这种芯片在软件层面没有太多手段只能在后续收发异常时优先怀疑硬件。2.2 lsmod 与 dmesg驱动加载没加载三条命令看明白确认设备枚举后看驱动状态# 查看 ch341 模块是否已经加载 lsmod | grep ch341 # 没有输出的话手动加载一次 sudo modprobe ch341 # 然后插拔一下设备看内核日志 dmesg | tail -20 dmesg | grep -i ch341如果驱动正常工作dmesg 会打印类似usb 1-2.3: ch341-uart converter now attached to ttyUSB0的信息。看到这一行说明驱动已经把 USB 设备转成了串口设备接下来直接去 /dev 下面找节点就行。这里有个容易误判的情况lsmod 没有任何输出但设备能正常用。这不代表模块没加载而是说明 ch341 被静态编译进了内核不再是可加载模块。判断依据是看模块文件是否存在ls -l /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ch341.ko如果这个文件不存在而 dmesg 又没有任何 attach 信息多半是你用的内核裁剪掉了这个功能那就需要走下一节的源码编译路线。如果文件存在但 lsmod 里没有用 sudo modprobe ch341 加载即可。2.3 什么情况下才需要手动编译裁剪内核与新芯片的差异需要动源码编译的场景不多就三种自己编译内核时没开 CONFIG_USB_SERIAL_CH341某 ARM 开发板的 BSP 内核太精简设备是较新的 CH342/CH343 系列老内核识别不了。前两种情况是内核真的缺驱动第三种是驱动版本跟不上芯片。编译前先确认内核头文件环境sudo apt install linux-headers-$(uname -r) build-essential然后把芯片厂商提供的 Linux 驱动包解压进入驱动包的 driver 子目录执行make sudo make install sudo modprobe ch341make 会根据当前内核版本编译出 ch341.komake install 会把模块拷到刚才 /lib/modules/ 对应目录最后 modprobe 加载。这里最常翻车的点是内核版本不一致如果你用 uname -r 看到的版本和头文件实际版本对不上insmod 会直接报 version magic 错误。解决办法是严格安装 linux-headers-$(uname -r) 这一套不要用通用 headers 包。编译安装完记得再跑一遍 2.2 的 dmesg 验证流程确认 attach 信息出现再继续往下调权限。3. 权限才是第一坑把当前用户加进 dialout 组设备节点已经在 /dev/ttyUSB0 出现了结果一打开串口工具就报 Permission denied这个现象在 Ubuntu 22.04 上比驱动缺失常见得多。3.1 为什么普通用户打不开 /dev/ttyUSB0先看节点权限ls -l /dev/ttyUSB0输出一般是crw-rw---- 1 root dialout 188, 0——属主是 root属组是 dialout普通用户既不在属主也不在属组里自然无权访问。这是 Linux 的安全设计串口设备默认只给 dialout 组的用户读写。你看到的“装不上驱动”的报错有相当一部分实际是这一层权限问题。系统里实际有两类用户能直接用串口的在 dialout 组里和不能的不在。把当前用户加进 dialout 组是最通用的解法也适用于绝大多数 USB 转串口工具不只是 CH340。3.2 usermod 追加到 dialout 组并验证生效sudo usermod -aG dialout $USER newgrp dialout groups id这里要提醒usermod 的 -aG 必须一起写-a 表示追加。如果写成sudo usermod -G dialout $USER会把该用户从其他所有附属组里踢出去造成一堆意外权限问题这是我在实际环境里踩过的血泪经验。命令执行后groups 输出里出现 dialout 才算完成。newgrp 只会让当前终端临时生效重新登录后系统会自动带上这个组。如果你是通过 SSH 远程连接的这一步尤其重要很多情况下新组不会自动传播到已有会话必须断开重连。3.3 组配置不生效时的两条后悔药现象一groups 里明明有 dialout打开设备还是 Permission denied。原因大概率是当前 shell 会话是在加组之前创建的没继承新组。解决方法是注销重新登录而不是继续折腾驱动。现象二udev 规则把权限覆盖了。系统可能存在自定义规则把 ttyUSB* 设备改成了 root 属主加 0600 权限。检查 /etc/udev/rules.d/ 下的规则文件尤其是名字靠前的规则优先级比系统默认规则高。找到后删掉或改低优先级。还有一种容易忽略的情况使用的串口工具是 snap 包装的版本。snap 有自己的一套设备访问控制不直接认宿主机 dialout 组。解决办法是卸掉 snap 版改用 apt 源里的同名工具或者直接用命令行工具。4. 多设备接入与固定设备名用 udev 规则终结 ttyUSB0 飘移如果你只用一个 USB 转串口直接在代码里写死 /dev/ttyUSB0 也没什么大问题。一旦插上两个 CH340或者一个 CH340 加一个调试器节点序号就会变得不可控这个问题做机器人或工控的人几乎都会撞上。4.1 两个 CH340 同时插设备节点是怎么分配的内核按 USB 枚举顺序给设备分配编号先被识别到的是 ttyUSB0然后是 ttyUSB1。麻烦在于枚举顺序受 USB 控制器初始化、插拔时序的影响重启后不一定保持原样。你代码里写死的 /dev/ttyUSB0下一次可能变成别的设备甚至不存在。先看看系统当前怎么分配ls -l /dev/ttyUSB*再通过 by-id 看看有没有稳定的符号链接ls -l /dev/serial/by-id/如果模块工厂端写了序列号by-id 下会出现usb-1a86_USB_Serial_xxx这种稳定链接按这个路径访问就不会受枚举顺序影响。但很多廉价 CH340 模块的序列号是空的by-id 里根本找不到可区分的项。这时候就得用 udev 规则按硬件物理位置来绑定。4.2 用 udevadm info 找到稳定属性绑定设备名的第一步是找到设备在 sysfs 里的稳定标识。执行udevadm info -a -n /dev/ttyUSB0输出会分段列出设备自身和各级父设备的属性其中有一段会给出KERNELS1-2.4这样的信息表示设备挂在 USB 控制器的哪个端口链路下。这个值由物理插口决定同一个 USB 口每次插同一个设备这个值不会变换到别的口值就变。实际操作中我最常拿来做绑定依据的属性有三个ATTRS{idVendor}芯片厂商 ID、ATTRS{idProduct}产品 ID、KERNELS物理端口路径。前两个保证设备确实是 CH340第三个保证物理位置稳定。如果设备本身有唯一序列号优先用 ATTRS{serial}但前面说了廉价模块往往没有。4.3 写 99-ch340.rules 并应用根据查到的属性写一条规则sudo vim /etc/udev/rules.d/99-ch340.rules规则内容SUBSYSTEMtty, ATTRS{idVendor}1a86, ATTRS{idProduct}7523, KERNELS1-2.4, SYMLINKrobot_uart, MODE0660, GROUPdialout然后重新加载规则sudo udevadm control --reload-rules sudo udevadm trigger ls -l /dev/robot_uart如果 /dev/robot_uart 出现说明绑定成功。之后应用层直接用这个路径不用再管 ttyUSB0 还是 ttyUSB1。这里解释一下规则各部分SUBSYSTEM 限制在 tty 子系统中ATTRS{idVendor} 和 ATTRS{idProduct} 用设备属性来锁定芯片型号KERNELS 匹配物理端口路径SYMLINK 创建额外设备链接不会删除原有的 ttyUSB0MODE 指定权限位GROUP 指定属组。权限配置成 0660 dialout 组既能让组内用户使用又不会像 0666 那样对所有人开放。另一个设备就再写一条把 SYMLINK 换成 robot_debugKERNELS 换成它实际所在端口的路径。这样不管插了几块板子每次开机后设备路径都是确定的。提示给普通用户的串口权限建议配合 dialout 组使用而不是直接开 MODE0666后者会让所有本地用户都能直接读写串口接手项目的人多半会质疑这个配置。5. 避坑排查CH340 在 Ubuntu 22.04 上最常见的五个翻车现场驱动、权限、设备名都处理完之后还有一批“时好时坏”的问题。我不按教程顺序讲直接说五个最常见的现象、原因和解决路径。5.1 插上没反应lsusb 里也看不到设备现象把 USB 转 TTL 插到电脑上lsusb 没有任何新增行dmesg 也没有任何 USB 插入日志。先说结论这跟驱动没关系驱动不会让一个未枚举的设备凭空出现。原因里最高频的是 USB 线只供电不通数据其次是机箱前置面板供电弱插后置口就正常。解决换一根短的数据线直插主板后置 USB 口再 lsusb 确认。如果换线后 1a86:7523 出现问题就在线上不用继续排查系统。5.2 dmesg 显示 attach 但 /dev/ttyUSB0 没出现现象dmesg 里能看到ch341-uart converter now attached to ttyUSB0但 ls /dev/ttyUSB* 什么都没有。原因是设备节点可能在 attach 之后又被系统服务移除了或者驱动模块状态异常。解决先lsmod | grep ch341确认模块然后卸载再加载sudo modprobe -r ch341 sudo modprobe ch341。之后重新插拔设备再看 /dev 目录。如果还不行重点检查有没有服务在快速反复探测这个串口见 5.5。5.3 串口能打开但全是乱码现象minicom 能打开 /dev/ttyUSB0但收到的数据全是乱码。原因优先级波特率不一致排第一其次是 GND 没和设备共地。TX/RX 接反通常表现是收不到数据而不是乱码。解决先把波特率统一到 115200 8N1确认接线正确。如果这些都对了仍然偶尔有乱码再用逻辑分析仪抓一下 UART 波形。还有一种少见但发生过的情况模块上的参考晶振误差大导致波特率整体偏移症状是短距离偶尔错字节这个只能换硬件解决。5.4 明明加了 dialout 组还是 Permission denied现象groups 输出里已经有 dialout打开设备还是拒绝。原因一般是当前会话没有重新加载组信息或者有自定义 udev 规则把设备权限覆盖了。解决先注销重新登录再试。如果仍然失败检查 /etc/udev/rules.d/ 里是否有一条规则匹配了 ttyUSB* 并设置了 MODE0600 或属主为 root把它删掉或改成 0660 GROUPdialout。还有一条隐藏路径snap 版串口工具不识别宿主机的 dialout 组换成 apt 版解决。5.5 刚插上能用过一会节点消失或被占用现象插上设备能正常用过几十秒 ttyUSB0 消失或者串口工具报 device or resource busy。罪魁祸首通常是桌面版自带的调制解调器检测服务它会枚举新出现的串口设备尝试用 AT 指令做探测测试过程中会占用设备甚至触发 USB reset。解决在 udev 规则里加一条环境变量让该服务跳过这个设备。在 99-ch340.rules 文件里追加SUBSYSTEMtty, ATTRS{idVendor}1a86, ATTRS{idProduct}7523, ENV{ID_MM_DEVICE_IGNORE}1, ENV{ID_MM_PORT_TYPE}serial然后重新加载规则并重启系统。如果这台机器完全不需要调制解调器功能也可以直接把服务禁用sudo systemctl mask ModemManager.service。这条是我在桌面版 Ubuntu 上遇到最多、也最少被资料翻到的问题。6. 收尾进阶验证串口链路是否真的通驱动、权限、设备名都搞定了不代表串口链路就一定通。我现在每拿到一块新的 USB 转串口板子都会先做一次回环自测把物理链路和驱动一起验掉把模块的 TXD 和 RXD 两个引脚短接从系统里写一串数据进去如果能在同一端口读回来说明链路是好的。可以用一段 Python 快速验证import serial ser serial.Serial(/dev/robot_uart, 115200, timeout2) ser.write(bloopback-ch340-test\n) data ser.read(64) print(recv:, data.decode(errorsreplace)) ser.close()运行后如果打印出 recv: loopback-ch340-test说明整条链路通了。如果 data 为空优先检查短接是否正确、引脚是否接触良好、设备路径是否选对。这里要注意串口的 RX 和 TX 是交叉的回环测试恰好是唯一需要 TXD 和 RXD 直连的场合正常对接设备时是反过来的。日常调试我更习惯用 minicom命令也更简短sudo apt install minicom minicom -D /dev/ttyUSB0 -b 115200进入界面后按 CtrlA 再按 Z 打开帮助菜单确认流控选项里 Hardware Flow Control 和 Software Flow Control 都是关闭状态否则部分模块会出现能发不能收、一收就卡死的现象。退出组合键是 CtrlA 然后 X会提示确认后退出。这个回环习惯帮我拦截过太多次“代码没问题结果是线断了或者引脚虚焊”的尴尬时刻。我现在拿到任何一块串口硬件都强制按这个顺序走一遍先 lsusb 看枚举再 dmesg 看驱动最后做一次回环写入。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑