文章目录
- 解决ubuntu22.04无法识别CH340/CH341和vscode espidf插件无法选择串口设备节点问题
- 不识别CH340/CH341
- 报错
- 解决办法
- 升级驱动
- 编译安装
- 卸载brltty程序
- vscode espidf插件无法选择串口设备节点
- 问题
- 解决办法
- 编译安装
解决ubuntu22.04无法识别CH340/CH341和vscode espidf插件无法选择串口设备节点问题
不识别CH340/CH341
报错
lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 009: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Bus 001 Device 004: ID 0e0f:0008 VMware, Inc. Virtual Bluetooth Adapter
Bus 001 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 001 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hubxxxxxxxxxx dmesglsusb Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 009: ID 1a86:7523 QinHeng Electronics CH340 serial converterBus 001 Device 004: ID 0e0f:0008 VMware, Inc. Virtual Bluetooth AdapterBus 001 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB HubBus 001 Device 002: ID 0e0f:0003 VMware, Inc. Virtual MouseBus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
执行lsusb,发现可以检测到ch340设备,但是/dev下却没有设备节点
dmesg
[ 582.564563] usb 1-2.2: USB disconnect, device number 6
[ 610.085165] usb 1-2.2: new full-speed USB device number 7 using uhci_hcd
[ 610.396210] usb 1-2.2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
[ 610.396216] usb 1-2.2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 610.396218] usb 1-2.2: Product: USB Serial
[ 610.401423] ch341 1-2.2:1.0: ch341-uart converter detected
[ 610.415702] usb 1-2.2: ch341-uart converter now attached to ttyUSB0
[ 610.975480] input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input9
[ 610.982887] usb 1-2.2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[ 610.986786] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[ 610.986811] ch341 1-2.2:1.0: device disconnected
发现和 brltty程序冲突。
解决办法
升级驱动
CH341SER_LINUX.ZIP - 南京沁恒微电子股份有限公司 (wch.cn)
下载后解压,可以看到下列文件。
README.md文件写有教程。
描述
这是一个为 CH340、CH341 等 USB 至 UART 芯片设计的 USB 串行驱动程序。实际上,自从内核版本 2.6.24 开始,Linux 主线内核就已经内置了 CH341 串行驱动程序。该驱动程序的位置是:drivers/usb/serial/ch341.c。遗憾的是,内置的驱动程序可能无法保持最新状态。我们建议客户使用这个驱动程序。
打开“终端”
切换到“driver”目录
使用 make 命令编译驱动程序,如果成功,您将看到模块 ch341.ko
输入 sudo make load 或者 sudo insmod ch341.ko 动态加载驱动程序
输入 sudo make unload 或者 sudo rmmod ch341.ko 卸载驱动程序
输入 sudo make install 使驱动程序永久生效
输入 sudo make uninstall 移除驱动程序
您可以参考下面的链接获取 UART 应用程序,您可以使用 gcc 或者交叉编译工具 cross-gcc https://github.com/WCHSoftGroup/tty_uart
在驱动程序工作之前,请确保 USB 设备已经插入并且正常工作,您可以通过 shell 命令 lsusb 或 dmesg 来确认这一点。这些设备的 USB VID 是 [1a86],您可以从定义在 ch341.c 中的 ID 表中查看所有 ID。
如果设备工作良好,驱动程序将在 /dev 目录下创建名为 ttyCH341USBx 的 tty 设备。
注意
有任何问题,您可以发送反馈至邮箱:tech@wch.cn
编译安装
进入到driver目录编译后报错,gcc-12: not found。
make
make -C /lib/modules/6.8.0-40-generic/build M=/home/donnel/CH341SER_LINUX/driver
make[1]: Entering directory '/usr/src/linux-headers-6.8.0-40-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using:
CC [M] /home/donnel/CH341SER_LINUX/driver/ch341.o
/bin/sh: 1: gcc-12: not found
make[3]: *** [scripts/Makefile.build:243: /home/donnel/CH341SER_LINUX/driver/ch341.o] Error 127
make[2]: *** [/usr/src/linux-headers-6.8.0-40-generic/Makefile:1926: /home/donnel/CH341SER_LINUX/driver] Error 2
make[1]: *** [Makefile:240: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.8.0-40-generic'
make: *** [Makefile:5: default] Error 2
安装gcc-12即可。
sudo apt install gcc-12
然后继续编译,报错,函数原型不一致。
make -C /lib/modules/6.8.0-40-generic/build M=/home/donnel/CH341SER_LINUX/driver
make[1]: Entering directory '/usr/src/linux-headers-6.8.0-40-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
CC [M] /home/donnel/CH341SER_LINUX/driver/ch341.o
/home/donnel/CH341SER_LINUX/driver/ch341.c:1460:18: error: initialization of ‘ssize_t (*)(struct tty_struct *, const u8 *, size_t)’ {aka ‘long int (*)(struct tty_struct *, const unsigned char *, long unsigned int)’} from incompatible pointer type ‘ssize_t (*)(struct tty_struct *, const unsigned char *, int)’ {aka ‘long int (*)(struct tty_struct *, const unsigned char *, int)’} [-Werror=incompatible-pointer-types]
1460 | .write = ch341_tty_write,
| ^~~~~~~~~~~~~~~
/home/donnel/CH341SER_LINUX/driver/ch341.c:1460:18: note: (near initialization for ‘ch341_ops.write’)
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: /home/donnel/CH341SER_LINUX/driver/ch341.o] Error 1
make[2]: *** [/usr/src/linux-headers-6.8.0-40-generic/Makefile:1926: /home/donnel/CH341SER_LINUX/driver] Error 2
make[1]: *** [Makefile:240: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.8.0-40-generic'
make: *** [Makefile:5: default] Error 2
修改驱动文件,ch340.c。
646c646
< static int ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
---
> static ssize_t ch341_tty_write(struct tty_struct *tty, const u8 *buf, size_t count)
再编译安装即可。
make
make -C /lib/modules/6.8.0-40-generic/build M=/home/donnel/CH341SER_LINUX/driver
make[1]: Entering directory '/usr/src/linux-headers-6.8.0-40-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
CC [M] /home/donnel/CH341SER_LINUX/driver/ch341.o
MODPOST /home/donnel/CH341SER_LINUX/driver/Module.symvers
CC [M] /home/donnel/CH341SER_LINUX/driver/ch341.mod.o
LD [M] /home/donnel/CH341SER_LINUX/driver/ch341.ko
BTF [M] /home/donnel/CH341SER_LINUX/driver/ch341.ko
Skipping BTF generation for /home/donnel/CH341SER_LINUX/driver/ch341.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.8.0-40-generic'
sudo make install
make -C /lib/modules/6.8.0-40-generic/build M=/home/donnel/CH341SER_LINUX/driver
make[1]: Entering directory '/usr/src/linux-headers-6.8.0-40-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
make[1]: Leaving directory '/usr/src/linux-headers-6.8.0-40-generic'
rmmod ch341 || true
insmod ch341.ko || true
mkdir -p /lib/modules/6.8.0-40-generic/kernel/drivers/usb/serial/ || true
cp -f ./ch341.ko /lib/modules/6.8.0-40-generic/kernel/drivers/usb/serial/ || true
depmod -a
卸载brltty程序
brltty介绍
brltty 是一款专为盲人设计的屏幕阅读器软件,它能够将文本输出转换为盲文点阵显示器上的触觉反馈。brltty 支持多种类型的盲文点阵显示器,并且能够在多种操作系统上运行,包括 Linux、FreeBSD 和 Mac OS X。
brltty 的主要功能包括:
文本到盲文转换:将计算机屏幕上的文本转换成盲文点阵显示器上的触觉输出。
键盘输入支持:允许用户通过盲文点阵显示器上的按键来输入文本或命令。
语音合成:提供文本到语音的功能,对于没有盲文点阵显示器的用户也可以使用。
Braille Backspace:当用户在盲文点阵显示器上输入时,如果需要删除前面的字符,可以通过特定的键组合实现。
多语言支持:支持多种语言的盲文编码,包括英语、西班牙语等。
集成环境:可以与多种辅助技术工具集成,如其他屏幕阅读器或语音合成引擎。
brltty 软件通常用于教育机构、图书馆以及个人计算机上,以帮助视障人士更好地使用计算机和互联网资源。此外,brltty 还可以与其他辅助技术结合使用,比如支持通过声音反馈来读取屏幕上的信息。
在 Linux 系统中,brltty 通常作为一项服务运行,可以通过系统服务管理工具启动和停止。安装 brltty 可以通过包管理器进行,例如在基于 Debian 的系统中,可以使用 apt-get install brltty 命令来安装。
sudo apt autoremove --purge brltty
重新插拔一次,就可以识别到了。
[ 3837.097423] usb_ch341 1-2.2:1.0: ch341 usb device disconnect.
[ 3840.079302] usb 1-2.2: new full-speed USB device number 10 using uhci_hcd
[ 3840.390310] usb 1-2.2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
[ 3840.390321] usb 1-2.2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 3840.390324] usb 1-2.2: Product: USB Serial
[ 3840.395429] usb_ch341 1-2.2:1.0: ttyCH341USB0: ch341 USB device
ls /dev/ttyCH341USB0
/dev/ttyCH341USB0
到这里CH340和CH341就可以正常识别到了
vscode espidf插件无法选择串口设备节点
问题
上文已经可以识别到串口设备了,但是乌龙的是vscode esp-idf插件居然不能选择。
解决办法
然后经过我的仔细观察,他好像过滤了ttyS开头的串口。
正好刚刚升级驱动时源码还没删,所以可以直接改驱动,把节点改为ttyS开头的即可。
修改ch340.c
646c646
< static int ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
---
> static ssize_t ch341_tty_write(struct tty_struct *tty, const u8 *buf, size_t count)
1271c1271
< dev_info(&intf->dev, "ttyCH341USB%d: ch341 USB device\n", minor);
---
> dev_info(&intf->dev, "ttySCH341USB%d: ch341 USB device\n", minor);
1483c1483
< ch341_tty_driver->driver_name = "ch341_uart", ch341_tty_driver->name = "ttyCH341USB",
---
> ch341_tty_driver->driver_name = "ch341_uart", ch341_tty_driver->name = "ttySCH341USB",
编译安装
make && sudo make install
重新拔插后,发现可以选择了。
如果还出现烧录报错的情况,请检查配置信息是否正确,除了这个也有可能是没有权限读写串口,可以修改串口权限。
sudo chmod 777 /dev/ttySCH341USB0