1. 课程导论:ACM Gadget 背景、USB串口设备驱动概述、开发环境与目标板介绍
1.1 为什么选择 ACM Gadget?—— 背景与动机
在嵌入式 Linux 开发中,USB 设备驱动是最常见也最易出错的子系统之一。传统的 USB 串口驱动开发通常需要两块开发板(一块作为 Host,一块作为 Device),或者依赖昂贵的 USB 分析仪进行调试。这给初学者和原型验证阶段带来了极高的门槛。
ACM Gadget(Abstract Control Model Gadget)是 Linux USB Gadget 子系统中的一个标准功能驱动,它允许一块开发板通过 USB 接口模拟成一个标准的串口设备(如 /dev/ttyACM0)。这意味着:
- 单板即可开发调试:开发板自身作为 Device,PC 作为 Host,无需第二块开发板。
- 无需硬件串口线:通过 USB 线缆即可完成数据收发,简化硬件连接。
- 协议标准通用:ACM 是 USB CDC(Communication Device Class)标准的一部分,Windows/Linux/macOS 均原生支持。
- 驱动代码精简:核心驱动代码仅约 800 行,非常适合作为驱动开发入门案例。
课程定位:本课程以 ACM Gadget 为切入点,从零开始搭建驱动开发环境,逐步深入到 USB 协议栈、Gadget 框架、URB 处理、并发控制、调试技巧等核心内容。适合有一定 C 语言和 Linux 基础,希望系统掌握 USB 设备驱动开发的工程师。
1.2 USB 串口设备驱动概述
USB 串口设备驱动在 Linux 内核中分为两大阵营:Host 侧驱动和Device 侧驱动。本课程聚焦于 Device 侧,即 Gadget 驱动。
| 对比维度 | Host 侧驱动(如 pl2303、cp210x) | Device 侧驱动(ACM Gadget) |
|---|---|---|
| 运行位置 | USB Host 控制器(如 PC、树莓派) | USB Device 控制器(如开发板) |
| 功能角色 | 识别并驱动外接 USB 串口设备 | 将开发板模拟为 USB 串口设备 |
| 用户接口 | /dev/ttyUSB0 | /dev/ttyACM0 |
| 协议栈深度 | USB Core → Host Controller Driver → tty 层 | Gadget Framework → UDC Driver → tty 层 |
| 调试难度 | 中等(需外接设备) | 中等(单板即可,但需理解 Gadget 框架) |
ACM Gadget 驱动在内核中的源码路径为 drivers/usb/gadget/function/f_acm.c。它通过 Linux Gadget 框架与底层的 UDC(USB Device Controller)驱动交互,向上注册一个 tty 设备。整个数据流路径如下:
用户空间 (echo "hello" > /dev/ttyACM0)
↓
tty 层 (drivers/tty/)
↓
ACM Gadget 函数驱动 (f_acm.c)
↓
Gadget 框架 (drivers/usb/gadget/)
↓
UDC 驱动 (如 dwc2, musb, chipidea)
↓
USB Device 控制器硬件
↓
USB 线缆 → Host 端
关键概念:ACM Gadget 驱动本质上是一个 tty 驱动 + USB 函数驱动 的复合体。它既要处理 tty 层的打开、关闭、读写、线路设置,又要处理 USB 层的端点配置、URB 传输、控制请求。
1.3 开发环境与目标板介绍
1.3.1 硬件平台
本课程选用 STM32MP157D-DK1 开发板作为目标硬件。该板卡基于 STM32MP157 双核 Cortex-A7 + Cortex-M4 异构处理器,集成 USB OTG 控制器,支持 Gadget 模式。
| 硬件参数 | 规格说明 |
|---|---|
| SoC | STM32MP157DAC (双核 A7 @ 800MHz + M4 @ 209MHz) |
| USB 控制器 | DWC2 控制器,支持 OTG/Device/Host 模式 |
| 内存 | 1GB DDR3L |
| 存储 | MicroSD 卡槽 + 4GB eMMC |
| 调试接口 | ST-Link/V2-1 虚拟串口 + USB Type-C OTG |
| 网络 | 千兆以太网 |
1.3.2 软件环境
开发主机使用 Ubuntu 22.04 LTS,目标板运行 Linux 内核 6.1 LTS。工具链采用 Linaro GCC 12.2 交叉编译器。
| 软件组件 | 版本/说明 |
|---|---|
| 主机操作系统 | Ubuntu 22.04.3 LTS (x86_64) |
| 交叉编译工具链 | arm-linux-gnueabihf-gcc 12.2.1 |
| 目标内核版本 | Linux 6.1.76 (LTS) |
| 内核源码 | git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git |
| 根文件系统 | Buildroot 2023.11 (基于 glibc) |
| 调试工具 | kgdb、ftrace、trace-cmd、USBMon |
1.3.3 开发环境拓扑
下图展示了本课程使用的开发环境连接关系:
1.4 课程知识体系与学习路径
本课程共 30 章,分为 5 个阶段,循序渐进地覆盖 ACM Gadget 驱动开发的完整流程:
| 阶段 | 章节范围 | 核心内容 |
|---|---|---|
| 基础准备 | 第 1-4 章 | 环境搭建、内核编译、Gadget 框架初探、第一个 ACM 设备 |
| 驱动核心 | 第 5-12 章 | f_acm.c 源码解析、URB 管理、tty 操作、线路编码、并发控制 |
| 调试进阶 | 第 13-20 章 | USBMon 抓包、ftrace 追踪、kgdb 断点调试、性能分析 |
| 实战优化 | 第 21-26 章 | 批量传输优化、DMA 集成、电源管理、多实例支持 |
| 项目交付 | 第 27-30 章 | 自定义 ACM 驱动、兼容性测试、文档与补丁提交 |
前置要求:学习本课程前,建议具备以下基础:
• 熟练使用 C 语言,理解指针、链表、回调函数
• 了解 Linux 内核模块编写基础(module_init、module_exit)
• 熟悉基本的 USB 概念(端点、传输类型、描述符)
• 能够使用 Git 进行版本管理
• 熟练使用 C 语言,理解指针、链表、回调函数
• 了解 Linux 内核模块编写基础(module_init、module_exit)
• 熟悉基本的 USB 概念(端点、传输类型、描述符)
• 能够使用 Git 进行版本管理
1.5 本章小结
本章作为课程导论,完成了以下铺垫:
- 阐述了 ACM Gadget 在驱动学习中的独特价值——单板可调试、协议标准、代码精简。
- 对比了 Host 侧与 Device 侧 USB 串口驱动的差异,明确了本课程的聚焦范围。
- 介绍了 STM32MP157D-DK1 目标板的硬件规格和 Ubuntu 22.04 + Linux 6.1 的软件环境。
- 给出了开发环境拓扑图和 5 阶段 30 章的学习路径。