news 2026/4/16 10:51:14

在RK3588的ELF 2开发板上为CH341 USB转串口模块手动编译与部署驱动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在RK3588的ELF 2开发板上为CH341 USB转串口模块手动编译与部署驱动

1. 环境准备与驱动源码获取

最近在RK3588的ELF 2开发板上折腾CH341 USB转串口模块时,发现系统默认没有这个驱动。Ubuntu 22.04系统虽然对硬件支持已经很完善,但遇到这种小众芯片还是得自己动手。好在整个过程比想象中简单,实测下来从编译到加载成功只用了不到半小时。

首先需要准备好交叉编译环境。因为RK3588是ARM64架构,而我们通常是在x86电脑上开发,所以必须使用交叉编译工具链。ELF 2开发板配套的SDK里已经包含了完整的工具链,路径一般在prebuilts/gcc/linux-x86/aarch64/目录下。我用的版本是gcc-arm-10.3-2021.07,这个要和内核版本匹配。

驱动源码可以从几个渠道获取:

  1. 官方GitHub仓库(https://github.com/juliagoda/CH341SER)
  2. 内核源码树中的drivers/usb/serial目录(如果内核版本较新)
  3. 第三方维护的驱动包

我建议直接用官方仓库的代码,因为更新更稳定。下载后解压到虚拟机里,建议放在和内核源码同级的目录,方便后续编译。解压后的目录结构大致是这样的:

ch341_driver/ ├── ch341.c ├── Makefile ├── readme.txt └── ...

2. 内核配置与交叉编译

2.1 内核头文件准备

编译驱动最关键的是内核配置要正确。很多人在这一步踩坑,就是因为内核配置不匹配。ELF 2开发板的内核源码通常随SDK一起提供,路径类似/home/user/elf/work/ELF2-linux-source/kernel

首先确认内核已经编译过,并且.config文件存在。如果之前清理过编译中间文件,可能需要重新编译内核:

cd /path/to/kernel/source make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- elf2_defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- -j8

2.2 修改驱动Makefile

驱动目录里的Makefile需要针对开发板环境进行修改。这是我调整后的版本:

CONFIG_MODULE_SIG=n KERNELDIR := /home/yyn/elf/work/ELF2-linux-source/kernel PWD := $(shell pwd) obj-m := ch341.o build: kernel_modules kernel_modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules \ ARCH=arm64 \ CROSS_COMPILE=/home/yyn/elf/work/ELF2-linux-source/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

关键参数说明:

  • KERNELDIR:指向开发板内核源码路径
  • CROSS_COMPILE:指定交叉编译工具链前缀
  • ARCH=arm64:指定目标架构
  • CONFIG_MODULE_SIG=n:禁用模块签名验证(开发阶段建议关闭)

2.3 执行交叉编译

进入驱动目录执行编译:

make clean make

如果一切顺利,会在当前目录生成ch341.ko文件。常见的编译错误及解决方法:

  1. 找不到内核头文件:检查KERNELDIR路径是否正确
  2. 函数未定义:可能是内核配置选项没开,需要重新配置内核
  3. 类型不匹配:驱动代码和内核版本不兼容,需要调整代码

3. 驱动部署与测试

3.1 手动加载驱动

将编译好的.ko文件拷贝到开发板,可以通过scp或者U盘:

scp ch341.ko user@192.168.x.x:/home/user/

在开发板上加载驱动:

sudo insmod ch341.ko dmesg | grep ch341 # 查看内核日志 ls /dev/tty* # 检查设备节点

如果看到/dev/ttyUSB0之类的设备,说明驱动加载成功。可以用minicom或者screen测试串口通信:

sudo apt install minicom sudo minicom -D /dev/ttyUSB0

3.2 常见问题排查

遇到驱动加载失败时,可以按以下步骤排查:

  1. 检查内核日志dmesg,看是否有错误信息
  2. 确认USB设备被识别:lsusb应该能看到"1a86:7523"(CH341的VID:PID)
  3. 检查内核配置是否包含USB串口支持:
    zcat /proc/config.gz | grep USB_SERIAL
  4. 尝试不同版本的驱动代码

4. 开机自动加载配置

4.1 系统级安装

为了让驱动每次开机自动加载,需要将驱动安装到系统目录:

sudo cp ch341.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/ sudo depmod -a

4.2 配置自动加载

创建systemd模块加载配置文件:

echo "ch341" | sudo tee /etc/modules-load.d/ch341.conf

验证配置是否生效:

sudo systemctl restart systemd-modules-load lsmod | grep ch341

4.3 udev规则配置(可选)

如果需要固定设备节点名称,可以创建udev规则:

echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyCH341"' | sudo tee /etc/udev/rules.d/99-ch341.rules sudo udevadm control --reload-rules

这样无论插哪个USB口,设备都会固定为/dev/ttyCH341,方便脚本调用。

5. 进阶配置与优化

5.1 驱动参数调整

CH341驱动支持一些可调参数,查看当前参数:

modinfo ch341

常用的可调参数包括:

  • write_timeout:写操作超时时间
  • read_timeout:读操作超时时间
  • baudrate_base:基准波特率

可以在加载时指定参数:

sudo insmod ch341.ko baudrate_base=921600

5.2 性能优化建议

  1. 提高缓冲区大小:修改驱动源码中的CH341_TX_QUEUE_SIZECH341_RX_QUEUE_SIZE
  2. 调整内核调度策略:对实时性要求高的应用可以设置FIFO调度
  3. 关闭终端回显:减少不必要的数据传输

5.3 多设备管理

当连接多个CH341设备时,可以通过以下方式区分:

ls /sys/bus/usb-serial/devices/ # 查看所有USB串口设备 udevadm info -a -p /sys/class/tty/ttyUSB0 # 查看设备详细信息

可以在udev规则中使用序列号等属性进行区分。

整个流程走下来,最大的感受是嵌入式Linux开发虽然有时候需要折腾驱动,但一旦掌握了方法,其实很有规律可循。关键是要理解内核模块的编译加载机制,以及systemd和udev的工作原理。记得第一次成功加载驱动时,看到串口设备出现的那种成就感,这就是嵌入式开发的乐趣所在吧。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:51:12

点云配准技术演进:从传统算法到深度学习

1. 点云配准技术的前世今生 第一次接触点云配准是在2015年做无人机三维重建项目时。当时为了把几百帧激光雷达扫描的碎片化点云拼接成完整场景,我和团队连续熬了三个通宵调试ICP算法参数。看着屏幕上终于对齐的点云模型,那种成就感至今难忘。点云配准技术…

作者头像 李华
网站建设 2026/4/16 10:50:12

深入解析深思API在加密狗数据安全读写中的关键应用

1. 加密狗与深思API的基础认知 第一次接触加密狗时,我完全不明白这个U盘大小的设备为什么能卖到上千元。直到某次项目需要保护核心算法,才真正理解它的价值——它不仅是硬件密钥,更是移动的安全堡垒。深思API就是这座堡垒的智能管家&#xf…

作者头像 李华
网站建设 2026/4/16 10:47:12

从自相关函数看噪声本质:平稳与非平稳噪声的实战鉴别指南

1. 噪声分析的基础:为什么自相关函数是利器 第一次接触信号处理时,我盯着屏幕上那些杂乱无章的波形直发懵。直到导师扔给我一句:"看噪声别只用眼睛,要用自相关函数这个放大镜。"后来在工业振动监测项目中,这…

作者头像 李华
网站建设 2026/4/16 10:45:12

K8s 单节点 Java 微服务 OOM Kill 循环排查实战 — MaxRAMPercentage=100% 的坑

测试环境 14 个 Java 微服务频繁异常,每次都要手动重启整台机器才能恢复。排查发现是 JVM MaxRAMPercentage=100% + 容器内存限制严重超卖导致的 OOM Kill 循环。 前言 运维同事反馈:测试环境的一台 K8s 节点"老是异常,手动重启才好"。每隔一两天就要重启一次,重…

作者头像 李华
网站建设 2026/4/16 10:44:30

Python实战:用分支定界法解决0-1背包问题(附完整代码)

Python实战:用分支定界法解决0-1背包问题(附完整代码) 当你面对一个装满价值不菲物品的背包,却只能带走有限重量的东西时,如何做出最优选择?这就是经典的0-1背包问题。作为算法设计中的"常青树"…

作者头像 李华