首页 / 资讯中心 / 文章详情

Ubuntu 22.04下CH340串口驱动、权限与udev排错指南

Ubuntu 22.04下CH340串口驱动、权限与udev排错指南 ★ FEATURED ARTICLE
简介面向在 Ubuntu 22.04 上使用 CH340 USB 转串口芯片的开发者与嵌入式学习者这份驱动资料包针对 Linux 内核未默认集成 CH340 驱动、串口设备难以识别的问题提供可参考的驱动源码、编译脚本与模块文件。压缩包共 16 个文件约 291KB主要包含 C 源码、Makefile 编译脚本、ko 内核模块、o 中间文件、cmd 构建命令记录及 txt 说明文档覆盖从源码编译到模块生成的基本材料。已有 779 人学习下载说明其在同类环境配置中具有一定参考价值。读者可借此了解 Linux 串口驱动模块的组织方式、编译产物构成与加载前准备并结合说明文档排查设备识别、权限配置等常见问题适合需要搭建 CH340 串口通信环境或对照编译过程查漏补缺的中初级用户。1. 先别急着找驱动包Ubuntu 22.04 识别 CH340 的真实路径Ubuntu 22.04 安装 CH340 串口驱动最容易翻车的地方不是“找不到驱动”而是把它当成 Windows 那套思路先到处找安装包再双击下一步。CH340 在 Linux 下走的是内核ch341模块Ubuntu 22.04 的 5.15 内核和后续 HWE 内核一般都带了这个模块。插上模块后lsusb能看到1a86:7523但/dev/ttyUSB0迟迟不出现问题往往落在模块没加载、brltty抢占、ModemManager干扰或者当前用户不在dialout组。这套环境在开发板调试、工控设备日志抓取、传感器串口读数里太常见了。装不好不会蓝屏只会让你对着一个“有 USB 设备、没有串口节点”的黑匣子干瞪眼。下面按“先核对环境、再加载模块、然后配权限和 udev、最后验证收发”的顺序走新手能照抄熟手也能看到版本差异和参数取舍。2. 装前把环境钉死Ubuntu 22.04 内核、CH340 硬件 ID 与串口工具链先把机器底细摸清比一上来就modprobe更省时间。CH340 在 Ubuntu 22.04 上能不能出/dev/ttyUSB0第一取决于内核里有没有ch341第二取决于 USB 设备有没有被别的服务截胡第三才轮到权限。环境核对这一步做细后面排错就不靠猜。2.1 核对内核与 ch341 模块5.15 与 HWE 内核的差异先看当前跑的内核uname -rUbuntu 22.04 初始版本常见的是 5.15 系列内核后面启用 HWE 的机器会跑到 6.2、6.5 一类分支。版本号本身不决定 CH340 能不能用关键是这个内核的模块包里有没有ch341.ko。我一般接着查模块信息modinfo ch341正常会看到filename指向/lib/modules/$(uname -r)/kernel/drivers/usb/serial/ch341.ko还会带alias: usb:v1A86p7523d*这类别名。只要这个输出在就说明内核侧已经具备识别 CH340 的能力不需要去外面找所谓“CH340 Linux 驱动包”。如果报modprobe: FATAL: Module ch341 not found或者modinfo: ERROR: Module ch341 not found先别怀疑芯片先看模块包ls /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ | grep ch341 grep CONFIG_USB_SERIAL_CH341 /boot/config-$(uname -r)grep的结果如果是CONFIG_USB_SERIAL_CH341m说明编成了模块如果是y说明编进内核如果是# CONFIG_USB_SERIAL_CH341 is not set这个内核就没带换官方内核比乱装第三方包靠谱。Ubuntu 上常见做法是补linux-modules-extrasudo apt update sudo apt install -y linux-modules-extra-$(uname -r)这个包补的是当前内核的额外模块不是替换内核。装完再跑一次modinfo ch341。不同内核分支的包名会跟着版本走$(uname -r)不要写死否则换内核后对不上。下面这张表是我核对环境时常用的判断顺序检查项命令正常表现异常时先看什么当前内核uname -r5.15 或 HWE 分支是否刚换过内核没重启模块信息modinfo ch341有 filename 和 alias模块包是否缺失内核配置grep CONFIG_USB_SERIAL_CH341 /boot/config-$(uname -r)m或y是否为not setUSB 枚举lsusb -d 1a86:7523能看到设备线缆、接口、供电硬件 ID 也要以实际lsusb为准。CH340 常见的是1a86:7523但不同封装、不同小板子未必完全一样。不要只记一个 PID 就到处套插上设备跑lsusb lsusb -tlsusb -t能看出设备挂在哪条 USB 总线上、速率是 12M 还是 480M。CH340 是 USB 转串口通常不会跑高速看到它挂在总线下面就够了。若lsusb完全没动静先换线、换口不要继续折腾驱动。2.2 安装 minicom、picocom 与内核头文件依赖一次装齐串口工具不用装一堆但常用的几个装上后面省事。下面这条命令把 USB 查看、串口终端、编译依赖和当前内核头文件一起补齐sudo apt update sudo apt install -y usbutils picocom minicom screen \ build-essential linux-headers-$(uname -r) linux-modules-extra-$(uname -r)usbutils提供lsusb和usb-devicespicocom轻量适合快速打开串口minicom功能多菜单和配置习惯看个人screen在临时调试时也够用。build-essential和linux-headers-$(uname -r)不是 CH340 内置模块的硬依赖但后面一旦要编译外部模块、DKMS 驱动或者排查内核头文件问题没有它们会卡住。linux-modules-extra-$(uname -r)则是补当前内核的额外模块。装完先确认工具在picocom --help | head lsusb -V如果linux-headers-$(uname -r)报找不到包不要硬装一个版本号对不上的头文件。先查可用包apt-cache search linux-headers | grep $(uname -r)HWE 内核的 headers 包名可能和主内核不同按uname -r的实际版本找。还有一点Secure Boot 开启时自己编译的外部模块会涉及签名但 CH340 走的是内核自带ch341通常不碰这一层。只有在模块确实缺失、需要自己编译时才去处理 MOK 签名不要一上来就把问题复杂化。工具装好后插上 CH340马上看 USB 层lsusb -d 1a86:7523 sudo dmesg -T | tail -n 30dmesg里如果出现ch341-uart converter now attached to ttyUSB0说明内核已经认了如果只有 USB 枚举信息没有 tty 绑定就往第 3 章的模块加载和brltty方向查。这个顺序不要反先看 USB再看模块最后看设备节点。3. 从 lsusb 到 /dev/ttyUSB0ch341 模块加载与设备节点确认lsusb能看到设备只代表 USB 层认出了这颗芯片不代表串口驱动已经绑定。Linux 下 USB 转串口要经过“USB 枚举 - 匹配ch341驱动 - 注册 tty - 生成/dev/ttyUSB0”这条链。中间任何一环被挡住设备节点就不会出现。3.1 手动加载 ch341modprobe、dmesg 与 brltty 抢占先手动加载一次排除“模块没加载”这种低级问题sudo modprobe ch341 lsmod | grep ch341 sudo dmesg -T | tail -n 30modprobe会自动处理依赖模块比insmod适合日常使用。lsmod里看到ch341一行后面跟着usbserial之类的依赖说明模块在。dmesg里重点看两类信息一类是ch341-uart converter now attached to ttyUSB0这是正常绑定另一类是brltty字样这通常意味着盲文终端服务把 CH340 当成了自己的设备。brltty是 Ubuntu 桌面环境里可能预装的服务它会扫描 USB 串口设备。CH340 被它抢走后表现就是lsusb有设备、dmesg有 USB 枚举但/dev/ttyUSB0不出现。先看服务状态systemctl status brltty-udev.service --no-pager systemctl status brltty.service --no-pager如果确认是它先停掉再插拔sudo systemctl stop brltty-udev.service sudo systemctl stop brltty.service sudo systemctl mask brltty-udev.servicemask是防止它被别的依赖重新拉起来。注意如果这台机器真的接盲文显示设备不要直接卸载brltty用stop和mask更可控需要时再unmask。普通串口调试环境里停掉它一般不影响别的功能。停完把 CH340 拔下再插上重新看ls -l /dev/ttyUSB* sudo dmesg -T | tail -n 20如果日志里出现ch341-uart converter now attached to ttyUSB0节点基本就出来了。若仍然没有继续看dmesg里的错误关键词。下面这张表是我排查枚举问题时常用的对照日志关键词可能原因下一步ch341-uart converter now attached绑定成功看/dev/ttyUSB0权限brltty盲文服务抢占停brltty-udev.service后重插device descriptor read/64, error -71线缆、接口、供电换线、直插主板 USB 口unable to enumerate USB deviceUSB 枚举失败去掉 Hub检查供电ch341但无 tty驱动绑定异常modprobe -r ch341后重载重载模块可以这样sudo modprobe -r ch341 sudo modprobe ch341modprobe -r是卸载执行前确认没有串口工具占着设备否则会提示模块在使用。重载后再插拔一次设备让 USB 重新枚举。这个动作比重启整台机器轻适合反复试。3.2 固定设备名modules-load.d 与 by-id 路径手动modprobe成功不等于重启后还在。让ch341开机自动加载写一个modules-load.d配置echo ch341 | sudo tee /etc/modules-load.d/ch341.conf sudo systemctl restart systemd-modules-load.service这个文件里一行一个模块名systemd-modules-load.service启动时会读取。写完后可以用systemctl status systemd-modules-load.service --no-pager看有没有报错。注意文件名不要和已有配置冲突ch341.conf这种就够清楚。设备节点名也要注意。/dev/ttyUSB0不是永久名字拔插顺序、多个 USB 串口同时插编号都可能变。看固定路径ls -l /dev/serial/by-id/ ls -l /dev/serial/by-path/ udevadm info -q symlink -n /dev/ttyUSB0by-id通常包含设备序列信息重插后相对固定by-path跟物理 USB 口走换口会变。/dev/ttyUSB0适合临时调试写脚本、做长期采集时我一般用by-id或者后面第 4 章加的 udev 别名。路径对比如下路径特点适用场景/dev/ttyUSB0编号会变临时插拔调试/dev/serial/by-id/...跟设备标识走脚本长期使用/dev/serial/by-path/...跟物理口走固定插口的设备/dev/ch340自定义别名单设备、规则简单udevadm info -q symlink -n /dev/ttyUSB0能看到当前节点关联的符号链接。如果by-id目录不存在先确认udev正常、设备确实是 tty 类。不要把ttyUSB0写死进生产脚本换一台机器或者多插一个模块就会翻车。4. 权限与 udev 规则让普通用户直接打开 CH340 串口设备节点出来以后下一步不是马上sudo picocom而是把权限模型理清。Ubuntu 默认的/dev/ttyUSB0一般是root:dialout权限0660。普通用户不在dialout组就会看到Permission denied。长期用sudo打开串口日志、锁文件、配置文件的属主都会乱后面更麻烦。4.1 dialout 组与权限模型为什么不要 chmod 666先看当前用户和节点权限id ls -l /dev/ttyUSB0如果输出是crw-rw---- 1 root dialout ... /dev/ttyUSB0说明组权限已经给到dialout。把当前用户加进去sudo usermod -aG dialout $(id -un)-aG是追加组不要写成-G覆盖原有组。执行后当前 shell 不会立刻生效可以重新登录或者临时用newgrp dialout groupsnewgrp会开一个新 shell退出后回到原环境。最省事的还是注销重登。确认id -nG输出里出现dialout就对了。不要用sudo chmod 666 /dev/ttyUSB0图省事这个权限在拔插、重启后会丢而且把串口设备开放给所有用户不是合格做法。sudo打开串口虽然能通但picocom、minicom生成的锁文件和日志容易变成 root 属主下次普通用户再开就可能被锁文件挡住。4.2 写 99-ch340.rulesVID/PID、SYMLINK 与 GROUP 的取舍只靠dialout组能解决权限但设备名还是会变。写一条 udev 规则把 VID/PID 匹配、权限和别名一次定下来sudo tee /etc/udev/rules.d/99-ch340.rules /dev/null EOF SUBSYSTEMtty, ATTRS{idVendor}1a86, ATTRS{idProduct}7523, MODE0660, GROUPdialout, SYMLINKch340 EOF sudo udevadm control --reload-rules sudo udevadm trigger --subsystem-matchtty这条规则里SUBSYSTEMtty限定只处理 tty 设备ATTRS{idVendor}和ATTRS{idProduct}匹配父 USB 设备的厂商 ID 和产品 IDCH340 常见是1a86:7523以lsusb实际输出为准MODE0660给属主和组读写GROUPdialout把组设为dialoutSYMLINKch340创建/dev/ch340这个稳定别名。这里用ATTRS而不是ATTR是因为idVendor、idProduct在父 USB 设备上当前 tty 节点上未必直接有。规则写完后重新插拔设备检查ls -l /dev/ch340 ls -l /dev/ttyUSB0如果/dev/ch340没出现先看规则文件权限和换行sudo cat /etc/udev/rules.d/99-ch340.rules sudo udevadm test /sys/class/tty/ttyUSB0udevadm test是模拟执行不会真正改设备但能看到规则有没有命中。规则文件名用99-是为了排在后面避免被更早的规则覆盖。多个 CH340 同时插时SYMLINKch340会冲突可以改成SYMLINKch340-%k或者干脆在脚本里用by-id。单设备调试用/dev/ch340最顺手多设备就不要偷这个懒。4.3 ModemManager 与串口独占谁在抢 /dev/ttyUSB0节点有了、权限对了串口还是打不开就要看谁占着设备。ModemManager是常见嫌疑它会扫描串口设备把一些 USB 串口当成调制解调器。查状态systemctl status ModemManager --no-pager sudo fuser -v /dev/ttyUSB0fuser会列出占用进程。如果是ModemManager可以先停sudo systemctl stop ModemManager但不建议上来就mask。这台机器如果真用 4G/5G 模块联网ModemManager还有用。更细的做法是在 udev 规则里让 ModemManager 忽略这个设备sudo tee /etc/udev/rules.d/99-ch340.rules /dev/null EOF SUBSYSTEMtty, ATTRS{idVendor}1a86, ATTRS{idProduct}7523, MODE0660, GROUPdialout, ENV{ID_MM_DEVICE_IGNORE}1, SYMLINKch340 EOF sudo udevadm control --reload-rules sudo udevadm trigger --subsystem-matchttyENV{ID_MM_DEVICE_IGNORE}1是给 ModemManager 看的标记让它跳过这个设备。改完重插再用fuser确认。还有一类占用是串口工具自己没退干净比如screen挂在后台、minicom异常退出留下锁文件。先ps看进程再决定是杀进程还是清锁文件不要一上来就拔线。5. 避坑与排查Ubuntu 22.04 下 CH340 最常见的五类翻车CH340 的坑不复杂但很分散有的在 USB 层有的在 tty 层有的在权限层还有的在接线层。下面五条是我在 Ubuntu 22.04 上反复遇到的翻车记录按“现象 - 原因 - 解决”写遇到问题可以直接对号。5.1 枚举与节点类问题lsusb 有、ttyUSB 没有现象一lsusb能看到1a86:7523但/dev/ttyUSB0不存在dmesg里出现brltty。原因brltty把 CH340 当成盲文终端抢占了USB 设备虽然枚举但 tty 没注册出来。解决先停服务再重插不要直接删包sudo systemctl stop brltty-udev.service sudo systemctl stop brltty.service sudo systemctl mask brltty-udev.service停完拔插设备再看dmesg和ls /dev/ttyUSB*。如果这台机器确实用盲文设备改成临时stop不要mask。现象二sudo modprobe ch341报Module ch341 not found。原因当前内核的模块包没装全或者这个内核根本没编CONFIG_USB_SERIAL_CH341。解决先补linux-modules-extra-$(uname -r)再modinfo ch341。如果仍然没有换 Ubuntu 官方内核不要从不明来源下载所谓“CH340 Linux 驱动压缩包”。内置模块能解决的事不要引入外部编译风险。现象三dmesg反复出现device descriptor read/64, error -71或unable to enumerate USB device。原因多半是线缆、USB Hub、供电或接口接触。CH340 小板子供电不足时枚举会反复失败。解决换一根能传数据的 USB 线直插主板后置 USB 口去掉 Hub检查模块供电。不要在这个阶段继续改 udev 规则先把 USB 层弄干净。5.2 权限与通信类问题能打开但收不到数据现象四picocom报Permission denied但/dev/ttyUSB0明明存在。原因当前用户不在dialout组或者 udev 规则把GROUP写错或者ModemManager占着设备。解决按顺序查id -nG ls -l /dev/ttyUSB0 sudo fuser -v /dev/ttyUSB0id -nG没有dialout就重新登录ls -l的组不对就改 udev 规则fuser有占用就先处理占用进程。不要用chmod 666掩盖问题。现象五串口能打开但收不到数据或者全是乱码。原因波特率不对、TX/RX 没交叉、GND 没共地、流控没关或者目标板电平不匹配。解决先确认串口参数是115200 8N1、无流控再确认 CH340 的 TX 接目标板 RX、RX 接目标板 TX、GND 对接最后做一次回环测试短接 CH340 的 TX 和 RX看输入字符能不能回显。回环能通问题就在接线或目标板回环不通问题在串口工具或驱动。这五条里前三条偏枚举后两条偏通信。排查时不要跳步先lsusb再dmesg再ls -l /dev/ttyUSB*最后才开串口工具。顺序乱了很容易把权限问题当成驱动问题。6. 装完怎么验证用 picocom 回环测试确认 CH340 真能收发验证不要只看/dev/ttyUSB0在不在那只能说明节点出来了。我一般固定跑三步先看别名和权限再开串口最后做回环。ls -l /dev/ch340 picocom -b 115200 --flow n /dev/ch340ls -l /dev/ch340应该指向ttyUSB0属组是dialout权限是crw-rw----。picocom里-b 115200是波特率--flow n关闭硬件流控。进去后按Ctrl-A再按Ctrl-X退出。如果打不开先回到第 4 章看dialout和fuser不要反复重装工具。回环测试更直接断电后把 CH340 模块的 TX 和 RX 短接再上电打开picocom输入任意字符屏幕上应该回显。能回显说明 USB、驱动、tty、权限、串口工具这条链全通了。不能回显就查线序和模块供电。验证项可以按下面这张表过一遍检查项命令预期设备别名ls -l /dev/ch340指向 ttyUSB0组为 dialout模块加载lsmodgrep ch341内核日志sudo dmesg -Ttail -n 20串口打开picocom -b 115200 --flow n /dev/ch340不报 Permission denied回环收发短接 TX/RX 后输入字符字符回显从那以后我每次把 CH340 插到新机器上都先跑一遍lsusb、dmesg、ls -l /dev/ch340这三步再开picocom。这套习惯不花时间但能少走很多“以为驱动坏了、其实是权限或线序”的弯路。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站