首页/新闻资讯/正文详情

树莓派USB Gadget实战:从ConfigFS到虚拟串口与U盘

发布时间:2026/9/24 10:56:11 来源:云帆数科 栏目:资讯中心
树莓派USB Gadget实战:从ConfigFS到虚拟串口与U盘
说起树莓派多数人想到的是插着SD卡、连着网线、跑着Linux的小板子NAS、路由器、智能家居中枢……但你可能不知道它还能反向操作——把USB-C口切换成“设备模式”让电脑把树莓派识别成一个U盘或者一个虚拟串口。这套玩法叫USB Gadget。我在树莓派4B上装了Ubuntu Server用ConfigFS把它变过U盘也变过USB转串口设备熟练之后从配置到跑通不超过五分钟。这篇文章就从原理讲到落地把每个坑都摊开说清楚适合所有对USB Gadget感兴趣但还没动手的Linux玩家。1. USB Gadget是什么为什么值得折腾1.1 一句话讲透USB Gadget的原理USB协议里设备通常分成两大类角色Host主机和Device从设备。PC是HostU盘、鼠标、键盘是Device。普通Linux板子的USB口几乎都是Host口用来接USB设备但树莓派这类带OTG能力的板子USB口能在软件层面切换成Device从而模拟出各种USB外设这就是USB Gadget。Linux内核从很早就支持Gadget子系统配合ConfigFS可以非常灵活地组装出Mass StorageU盘、CDC ACM虚拟串口、EthernetUSB网卡、HID键鼠等多种功能。简单说USB Gadget把一个小板子变成了一颗“万能USB外设芯片”。用生活类比就是你手里的树莓派平时是“餐厅后厨”负责做菜跑服务但切换成Gadget模式后它变成了一盘菜端出去给“客人”电脑直接用。这个“客人”不需要知道后厨有多复杂它看到的就是一个U盘、一个串口、一张网卡。这个特性在嵌入式调试、无网络环境、系统安装场景里非常有用。1.2 树莓派4B做这件事的优势和坑点树莓派4B相比Zero系列性能强4GB内存跑Ubuntu Server非常流畅还有千兆网口和WiFi做Gadget的同时还能通过网络访问调试起来很舒服。不过4B上有个坑不是所有USB口都支持Device模式只有那个USB-C电源口也兼作OTG支持。也就是说你要用USB-C线把树莓派连到电脑而不是用那四个USB-A口。而且树莓派4B的USB-C口供电逻辑很特殊如果只插数据线且另一端是电脑USB口树莓派可能供电不足导致系统不稳定建议给树莓派接上独立电源。另一个坑是树莓派4B的USB-C口在Device模式下实际跑的是USB 2.0速度480Mbps不是USB 3.x。做存储设备时速度顶多30~40MB/s但做串口、做配置工具绰绰有余。如果你追求USB 3.0级别的吞吐树莓派4B并不合适可能要换其它开发板。不过综合来看树莓派4B仍然是玩USB Gadget性价比很高、资料最多的板子。2. 开工前的硬件与系统准备2.1 你需要准备哪些硬件和工具硬件清单如下树莓派4B建议2GB以上内存1GB也能跑但会紧一些TF卡16GB以上最好Class 10或A1级别写入速度很影响体验一条支持数据传输的USB-C线这条线非常关键很多手机附赠线只支持充电插上去电脑毫无反应一个5V/3A电源适配器给树莓派稳定供电避免USB-C线供电不稳一台PC或者笔记本用来识别U盘/串口软件方面Raspberry Pi Imager烧录系统用免费且官方SSH客户端Windows Terminal自带的ssh、MobaXterm、macOS/Linux自带的终端都行主机端串口工具Linux上用screen或minicomWindows上用SSCOM或PuTTYmacOS用screen即可2.2 刷系统Ubuntu 22.04 Server版实战记录我用的是Ubuntu Server 22.04 LTS。这个版本对树莓派4B支持非常成熟dwc2 overlay能正常加载内核模块也齐全。如果换成树莓派OS步骤也大同小异但Ubuntu Server更轻量、无桌面适合这种纯命令行的小实验。烧录步骤打开Raspberry Pi Imager设备选“Raspberry Pi 4”操作系统选“Ubuntu Server 22.04 LTS (64-bit)”选择目标TF卡点击烧录。烧录完成后重插到树莓派上首次开机建议接HDMI和键盘鼠标进入系统后设置用户名密码启用SSHUbuntu Server默认没开SSH需要执行sudo systemctl enable --now ssh。如果你不想接显示器可以在Raspberry Pi Imager烧录界面点“设置”齿轮提前配置hostname、SSH公钥和WiFi。这个功能非常方便烧录完直接插电同一局域网下用ssh 用户名树莓派IP就能登录省掉一堆外设。2.3 开启DWC2让USB-C口支持Device模式关键步骤是修改/boot/firmware/config.txtUbuntu路径或/boot/config.txt树莓派OS路径在文件末尾添加一行dtoverlaydwc2然后重启。重启后执行ls /sys/class/udc/如果看到fe980000.usb之类的输出说明DWC2控制器已经切换为OTG模式可以进行下一步。如果没有任何输出多半是内核没加载dwc2模块可以手动执行sudo modprobe dwc2或者确认一下config.txt路径是否正确。在树莓派4B上UDC名称通常是fe980000.usbZero系列是1e0000.usb拿不准就ls看结果。提示配置完dwc2后USB-C线先不要插到电脑上等一切就绪再插不然有些系统会过早枚举在dmesg里刷一堆无意义的报错。3. 实战一把树莓派4B变成U盘3.1 制作虚拟磁盘文件把树莓派变成U盘核心是模拟Mass Storage类设备让电脑看到一个“虚拟硬盘”。这个虚拟硬盘本质上就是树莓派内部的一个文件我们把它格式化好再通过Gadget暴露出去。# 创建一个128MB的空白文件 sudo dd if/dev/zero of/home/pi/usbdisk.img bs1M count128 # 格式化成FAT32 sudo mkfs.vfat -F 32 /home/pi/usbdisk.img如果mkfs.vfat提示文件不是块设备而拒绝执行改用loop设备方式更稳sudo losetup /dev/loop0 /home/pi/usbdisk.img sudo mkfs.vfat -F 32 /dev/loop0 sudo losetup -d /dev/loop0镜像大小根据需求定。128MB适合测试如果要存文件建议1GB。格式化完成后可以先把镜像挂载到本机放一个说明文件进去方便验证sudo mkdir /mnt/usbtest sudo mount -o loop /home/pi/usbdisk.img /mnt/usbtest echo Hello from Raspberry Pi USB Gadget | sudo tee /mnt/usbtest/README.txt sudo umount /mnt/usbtest这段操作很直观你之后会看到电脑弹出的U盘里躺着一个README.txt。3.2 使用ConfigFS组装Mass Storage Gadget接着用ConfigFS动态组装Gadget。先加载libcomposite模块sudo modprobe libcomposite然后写一个脚本挂到usb_gadget目录下。ConfigFS的路径是/sys/kernel/config/usb_gadget/需要root权限操作#!/bin/bash # setup_ums.sh modprobe libcomposite GADGET_DIR/sys/kernel/config/usb_gadget/g1 DISK_IMG/home/pi/usbdisk.img if [ -d $GADGET_DIR ]; then echo g1 already exists exit 1 fi mkdir -p $GADGET_DIR cd $GADGET_DIR # 设置USB描述符 echo 0x1d6b idVendor echo 0x0104 idProduct echo 0x0100 bcdDevice echo 0x0200 bcdUSB mkdir -p strings/0x409 echo 1234567890 strings/0x409/serialnumber echo Raspberry Pi strings/0x409/manufacturer echo USB Mass Storage strings/0x409/product # 创建配置 mkdir -p configs/c.1/strings/0x409 echo Mass Storage Config configs/c.1/strings/0x409/configuration echo 120 configs/c.1/MaxPower # 创建mass_storage功能绑定镜像文件 mkdir -p functions/mass_storage.0 echo 0 functions/mass_storage.0/lun.0/cdrom echo 0 functions/mass_storage.0/lun.0/ro echo 0 functions/mass_storage.0/lun.0/nofua echo $DISK_IMG functions/mass_storage.0/lun.0/file # 将功能链接到配置 ln -s functions/mass_storage.0 configs/c.1/ # 绑定UDC UDC$(ls /sys/class/udc/ | head -1) echo $UDC UDC执行sudo bash setup_ums.sh然后插上USB-C线电脑应该会弹出“U盘”。此时用dmesg或事件日志查看如果出现新块设备比如/dev/sdb就说明Gadget工作正常。这里有几个点值得展开为什么不直接绑定物理SD卡分区而是用镜像文件因为绑定物理分区等于把树莓派的系统盘暴露给电脑一方面不安全另一方面电脑一格式化系统就没了。用镜像文件做隔离树莓派本机还能正常读写这个文件。唯一要注意的是两边不要同时挂载使用。lun.0/cdrom和lun.0/ro参数cdrom可以让设备模拟成只读光驱ro则强制只读。如果希望电脑能正常读写U盘两者都保持0即可。MaxPower是设备声明的最大电流单位mA。120就是120mA普通设备足够。设大了没有实际意义不要随意调成一些奇怪值。3.3 开机自启与日常使用建议上面的脚本手动执行重启后会失效。想让树莓派每次开机自动变成U盘可以写一个systemd服务sudo nano /etc/systemd/system/usb-gadget.service内容[Unit] DescriptionUSB Gadget Setup Afternetwork.target [Service] Typeoneshot Userroot ExecStart/usr/local/bin/setup_ums.sh RemainAfterExityes [Install] WantedBymulti-user.target然后sudo systemctl daemon-reload sudo systemctl enable --now usb-gadget日常使用有几个提醒不要在树莓派本机挂载usbdisk.img的同时又把它作为U盘暴露给电脑。两方同时读写同一个文件极容易损坏文件系统。我踩过这个坑曾经一边在树莓派上挂载裸文件一边从电脑往里面拷资料结果FAT表崩了镜像报废。如果你改了镜像里的内容拔掉USB线重新插入即可不用重启树莓派。需要扩大U盘容量时可以用dd重新造一个更大的镜像再格式化或者用truncate -s扩大原文件后重新格式化但注意后者会清空数据。4. 实战二把树莓派4B变成串口设备4.1 配置Serial GadgetCDC ACMU盘只是开胃菜更多时候把它变成虚拟串口才是真正的刚需。比如调试单片机、连接嵌入式设备、或者在没有网线没有WiFi的环境下做应急调试。CDC ACM驱动可以把树莓派模拟成一个标准的USB转串口主机端无需额外安装驱动Linux/macOS内核自带Windows一般会自动识别。配置方式跟mass_storage几乎一样只是把mass_storage.0换成acm.usb0#!/bin/bash # setup_acm.sh modprobe libcomposite GADGET_DIR/sys/kernel/config/usb_gadget/serial if [ -d $GADGET_DIR ]; then echo serial gadget already exists exit 1 fi mkdir -p $GADGET_DIR cd $GADGET_DIR echo 0x1d6b idVendor echo 0x0104 idProduct echo 0x0100 bcdDevice echo 0x0200 bcdUSB mkdir -p strings/0x409 echo 1234567890 strings/0x409/serialnumber echo Raspberry Pi strings/0x409/manufacturer echo USB Serial Gadget strings/0x409/product mkdir -p configs/c.1/strings/0x409 echo Serial Config configs/c.1/strings/0x409/configuration echo 120 configs/c.1/MaxPower mkdir -p functions/acm.usb0 ln -s functions/acm.usb0 configs/c.1/ UDC$(ls /sys/class/udc/ | head -1) echo $UDC UDC跑完脚本树莓派上应该会出现一个/dev/ttyGS0设备节点。注意树莓派端的节点是ttyGS0电脑端才会显示为ttyACM0或COM口。先别急着插线可以在树莓派本机用一个cat进程测试sudo cat /dev/ttyGS0cat会阻塞等待数据。然后插上USB-C线主机端开始通信。4.2 在电脑上连接并实现双向通信在Linux主机上插入后执行dmesg | tail大概率能看到usb 2-1: new full-speed USB device number x cdc_acm 2-1:1.0: ttyACM0: USB ACM device也就是/dev/ttyACM0。如果权限不够无法打开设备需要把当前用户加入dialout组sudo usermod -aG dialout $USER重新登录后用screen打开sudo screen /dev/ttyACM0 115200树莓派端在另一个终端往/dev/ttyGS0写数据echo hello from pi | sudo tee /dev/ttyGS0此时主机的screen里就能看到“hello from pi”。反过来在主机screen里输入“hello from pc”树莓派端的cat /dev/ttyGS0进程会立刻打印出来这就实现了双向通信。波特率选多少其实无所谓虚拟串口不真正依赖波特率只要两边一致就能通我这里习惯用115200。在Windows上测试设备管理器会出现一个新的COM口用串口助手连接后同样可以双向收发数据。4.3 串口Gadget的真正用途用USB线连树莓派和电脑然后互相发字符串看起来有点玩具但实际工作中这个功能有真实价值当电脑没有网口、没有WiFi树莓派又没有显示器时通过USB串口可以进入最原始的调试终端。比如把/dev/ttyGS0挂到getty上电脑连上就能直接登录树莓派的终端效果跟以前用串口线连网络设备一样。配合ppp或slattach甚至可以把USB虚拟串口当低速网络链路在没有网络硬件的情况下传数据。在嵌入式开发中Gadget虚拟串口可以用作主控板与上位机之间的调试通道尤其是目标板只有USB设备口时。做车机、工控机调试时很多设备只留USB口不开串口用Gadget给它补一个虚拟串口是最快的办法。串口Gadget不是玩具是真正能救命的调试手段。5. 进阶玩法复合设备与问题排查实录5.1 同时做U盘和串口配置多功能复合设备有时候想一边让电脑识别成U盘一边又能打开串口调试这完全可以在一个Gadget上同时配置。ConfigFS的configs/c.1/目录下可以挂多个function每个function对应一个USB接口主机端会把它们枚举成一个“复合设备”。#!/bin/bash # setup_combo.sh modprobe libcomposite GADGET_DIR/sys/kernel/config/usb_gadget/combo if [ -d $GADGET_DIR ]; then echo combo gadget already exists exit 1 fi mkdir -p $GADGET_DIR cd $GADGET_DIR echo 0x1d6b idVendor echo 0x0104 idProduct echo 0x0100 bcdDevice echo 0x0200 bcdUSB mkdir -p strings/0x409 echo 1234567890 strings/0x409/serialnumber echo Raspberry Pi strings/0x409/manufacturer echo USB Combo Device strings/0x409/product mkdir -p configs/c.1/strings/0x409 echo Combo Config configs/c.1/strings/0x409/configuration echo 120 configs/c.1/MaxPower # 功能1U盘 mkdir -p functions/mass_storage.0 echo /home/pi/usbdisk.img functions/mass_storage.0/lun.0/file # 功能2虚拟串口 mkdir -p functions/acm.usb0 # 两个功能都放进同一个config ln -s functions/mass_storage.0 configs/c.1/ ln -s functions/acm.usb0 configs/c.1/ UDC$(ls /sys/class/udc/ | head -1) echo $UDC UDC这样插到电脑上Windows设备管理器会看到一个大容量存储设备和一个COM口Linux主机上既能看到/dev/sdb或/dev/sdc也能看到/dev/ttyACM0。需要注意的是某些老Windows系统对多接口复合设备支持不好可能只识别其中一个功能这时候换Linux主机测试更稳。5.2 常见问题排查速查表现象可能原因排查/解决插上USB线电脑完全没反应USB-C线是充电线不支持数据换一根支持数据传输的USB-C线dmesg里没有新USB设备dtoverlay没生效或UDC没绑定成功检查config.txtls /sys/class/udc/看控制器重新跑setup脚本echo $UDC UDC报Device or resource busy上次gadget没清理删除/sys/kernel/config/usb_gadget下旧目录或重启后再配置U盘能识别但打不开提示格式化镜像文件格式被破坏重新mkfs.vfat格式化镜像避免本机挂载和Gadget同时占用串口识别成功但打不开权限问题将用户加入dialout组或用sudo打开树莓派连上电脑后频繁重启供电不稳给树莓派单独接5V/3A电源复合设备只显示一个功能主机OS兼容性问题换Linux主机测试或移除不用的功能开机后gadget配置没生效服务没开或脚本没执行权限检查systemd服务状态确认ExecStart脚本有可执行权限排查时有个通用思路先看树莓派端/sys/class/udc/有没有控制器再看/sys/kernel/config/usb_gadget/下结构是否完整最后看主机端dmesg有没有枚举信息。三步定位绝大部分问题都能找到方向。5.3 个人经验和后续扩展思路最后分享几条踩坑后的心得。第一USB-C线的选择比你想的重要。我刚开始用一根手机充电线插上去电脑一点反应都没有排查了一个小时最后换线秒解决。买线时挑标注“支持数据传输”的别贪便宜拿线充上电就以为能用。第二ConfigFS的层次结构不复杂但一定要按顺序创建先描述符、再strings、再config、再function最后link和绑定UDC。顺序反了虽然不一定报错但主机端枚举容易出问题。多跑几次脚本后就会有肌肉记忆。第三树莓派4B的USB-C口既是电源口又是OTG口所以连接时要注意电脑端是USB-A口就用USB-C转USB-A数据线树莓派端插USB-C电脑端是Type-C口就用双Type-C线。新手最容易犯的错误是把线插到USB-A口然后百思不得其解。第四开机自启的systemd服务里我没有加网络依赖因为gadget跟网络无关启动越早越好。但脚本里如果引用文件路径得确认对应文件系统已经挂载。RemainAfterExityes这个参数别漏否则systemd会认为服务早已退出后续管理起来很别扭。扩展空间还有很多可以用g_ether模块把树莓派变成USB网卡电脑和树莓派之间就是一条本地网络SSH直连可以做HID Gadget模拟键盘鼠标做自动化按键脚本可以在U盘镜像里放一个Linux发行版实现“从树莓派启动电脑”还可以配合systemd实现插上USB-C线自动切换Gadget模式、拔线恢复Host模式。总之掌握USB Gadget之后树莓派的USB-C口就是一块自由度极高的“万能接口”等着按你的想法去捏。

相关推荐

Formily Vue VoidField 组件完全指南:虚拟布局字段的桥接、显隐控制与状态恢复机制
Formily Vue VoidField 组件完全指南:虚拟布局字段的桥接、显隐控制与状态恢复机制

前端UI组件 【免费下载链接】formily 📱🚀 🧩 Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3 项目地址: https://gitcode.com/gh_mirrors… · 2026/9/24 10:56:11

ISO/SAE 21434与TARA落地:汽车网络安全工程实践与风险矩阵解析
ISO/SAE 21434与TARA落地:汽车网络安全工程实践与风险矩阵解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:56:03

Umi-OCR离线OCR实战指南:高鲁棒性文档识别工作流
Umi-OCR离线OCR实战指南:高鲁棒性文档识别工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:56:03

STM32H750VBT6+LAN8720A+LWIP以太网开发实战与避坑指南
STM32H750VBT6+LAN8720A+LWIP以太网开发实战与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:05:38

linux系统SSL证书自动续签,使用 Certbot 为 Nginx 配置 Let’s Encrypt 自动续签
linux系统SSL证书自动续签,使用 Certbot 为 Nginx 配置 Let’s Encrypt 自动续签

本文适用于已经通过 Nginx 对外提供 HTTPS 服务的网站。示例以以下占位符表示实际值,执行前必须替换:- example.com:主域名 - www.example.com:附加域名 - /etc/nginx/conf.d/example.conf:网站的 Nginx 配置文件本文采… · 2026/9/24 12:05:32

跨境ERP闭环检查:订单-库存-物流-财务四链路诊断指南
跨境ERP闭环检查:订单-库存-物流-财务四链路诊断指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:05:31

Linux内核参数调优实战:从sysctl机制到四组核心调优与避坑指南
Linux内核参数调优实战:从sysctl机制到四组核心调优与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:05:19

入侵检测系统设计与实现:从架构选型到落地避坑
入侵检测系统设计与实现:从架构选型到落地避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:05:07

Ubuntu 22.04 下移远 RM520N-GL 5G 模块从接线到开机自启全攻略
Ubuntu 22.04 下移远 RM520N-GL 5G 模块从接线到开机自启全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:05:01

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码