Ubuntu系统安装CH340驱动

 今天在使用USB转UART模块连接设备时发现我的Ubuntu虚拟机无法识别USB设备,这个模块使用的CH340芯片,在Windows主机中可以识别到串口并连接,所以初步判断为虚拟机中缺少ch340驱动。实际上自Linux内核版本2.6.24起,Linux主线内核已内置ch341串行驱动。其位置在:drivers/usb/serial/ch341.c,但是内置驱动无法保持更新,驱动官方建议客户安装使用新的驱动。

安装驱动 

在安装前先查看下内核版本,有些内核版本可能与下载的驱动文件存在不兼容现象:

uname -r

这里我的内核版本是 6.8.0-39-generic

6.8.0-39-generic

随后在官网下载CH340的驱动文件压缩包: 

压缩包下载地址:CH341SER_LINUX.ZIP - 南京沁恒微电子股份有限公司 (wch.cn) 

我的Ubuntu虚拟机是带图形显示的版本,无头模式的系统可以使用FTP或者SSH的方式把下载好的压缩包上传到服务器或虚拟机,也可以尝试下其他方式:

下载完成后cd到压缩包所在的路径,在终端输入命令将压缩包解压缩到/usr/local/src文件夹:

sudo unzip CH341SER_LINUX.ZIP -d /usr/local/src

文件解压后可以看到文件夹内有一个markdown的说明文档和driver文件夹,driver文件夹内存放着ch341的.c文件与.h、Makefile文件,其中Makefile文件主要用于自动化编译和构建程序。

driver文件夹内容如下: 

 编译驱动文件

随后在终端切换到解压后的驱动目录: 

cd /usr/local/src/CH341SER_LINUX/driver

输入make命令构建文件:

sudo make

 这里有可能会报错,因为CH341.C文件中在定义ch341_tty_write函数时与我的内核版本(6.8.0-39-generic)不兼容:

make -C /lib/modules/6.8.0-39-generic/build  M=/usr/local/src/CH341SER_LINUX/driver  
make[1]: 进入目录“/usr/src/linux-headers-6.8.0-39-generic”
warning: the compiler differs from the one used to build the kernel
  The kernel was built by: x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0
  You are using:           gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0
  CC [M]  /usr/local/src/CH341SER_LINUX/driver/ch341.o
/usr/local/src/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 ‘int (*)(struct tty_struct *, const unsigned char *, int)’ [-Werror=incompatible-pointer-types]
 1460 |         .write = ch341_tty_write,
      |                  ^~~~~~~~~~~~~~~
/usr/local/src/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:/usr/local/src/CH341SER_LINUX/driver/ch341.o] 错误 1
make[2]: *** [/usr/src/linux-headers-6.8.0-39-generic/Makefile:1926:/usr/local/src/CH341SER_LINUX/driver] 错误 2
make[1]: *** [Makefile:240:__sub-make] 错误 2
make[1]: 离开目录“/usr/src/linux-headers-6.8.0-39-generic”
make: *** [Makefile:5:default] 错误 2

使用Vim修改下ch341.c文件,这里我的Ubuntu系统并非实际的生产环境,如果是生产环境还得考虑一些其他因素

sudo vi /usr/local/src/CH341SER_LINUX/driver/ch341.c

找到 ch341_tty_write 函数,将函数定义修改一下,原函数定义如下:

int ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)

 修改后的函数定义为:

ssize_t ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, size_t count)

原代码中,count被定义为int类型修改后count被定义为size_t类型。使用size_t作为count的类型,更明确地表示count应该是一个非负整数,表示要处理的数据量的大小。最后函数返回类型是ssize_t,是一个允许函数返回负值以表示错误或特殊情况的有符号类型。

 再次输入make构建命令后构建成功:

 使用modprobe加载模块,modprobe可以自动处理内核模块

sudo modprobe ch341

 使用lsmod命令查看是否加载成功,这个命令可以显示已加载到内核中的模块列表:

lsmod

 模块加载成功:

输入命令让驱动永久生效: 

sudo make install
查看串口设备信息及端口号  

使用lsusb命令查看USB连接设备,可以显示本机USB设备列表及其详细信息: 

lsusb

这里可以看到连接到了一个CH340设备

 输入以下命令可以显示特定USB设备的详细信息和树状结构显示USB设备层次

lsusb -v -d 1a86:7523 // 刚才检查出来的设备ID号
lsusb -t

 

 

 输入命令列出所有以 /dev/ttyUSB 开头的设备文件

ls /dev/ttyUSB*

这里可以看到USB串行设备的端口号了

官方说明文件

 以下内容全部为官方的说明文件:

针对USB转UART芯片ch340、ch341等的USB串行驱动。事实上,自Linux内核版本2.6.24起,Linux主线内核已内置ch341串行驱动。其位置在:drivers/usb/serial/ch341.c,遗憾的是,内置驱动无法保持更新。我们建议客户使用此驱动。

  1. 打开“终端
  2. 切换到“driver”目录
  3. 使用“make”编译驱动,如果成功,你将看到模块“ch341.ko
  4. 输入“sudo make load”或“sudo insmod ch341.ko”动态加载驱动
  5. 输入“sudo make unload”或“sudo rmmod ch341.ko”卸载驱动
  6. 输入“sudo make install”使驱动永久生效
  7. 输入“sudo make uninstall”移除驱动
  8. 你可以参考以下链接获取uart应用程序,你可以使用gcc或交叉编译工具cross-gcc进行编译
    GitHub - WCHSoftGroup/tty_uart: linux tty uart application

在驱动工作之前,你应确保USB设备已插入并正常工作,你可以使用shell命令“lsusb”或“dmesg”进行确认,这些设备的USB VID为[1a86],你可以在“ch341.c”中定义的id表中查看所有ID。

如果设备工作正常,驱动将在/dev目录下创建名为“ttyCH341USBx”的tty设备。

猜你喜欢

转载自blog.csdn.net/m0_73500130/article/details/141091619