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 开发环境拓扑

下图展示了本课程使用的开发环境连接关系:

开发环境拓扑图 开发环境拓扑结构 开发主机 Ubuntu 22.04 交叉编译工具链 内核源码 + Buildroot 以太网 (TFTP/NFS) 目标板 STM32MP157D-DK1 Linux 6.1 LTS DWC2 UDC 驱动 USB 线缆 (Gadget) PC Host Windows/Linux ttyACM0 串口终端 ST-Link 虚拟串口 (调试控制台) 说明: 开发主机通过以太网(TFTP/NFS)向目标板传输内核和根文件系统; 目标板通过 USB 线缆模拟 ACM 串口设备,PC Host 端识别为 ttyACM0;ST-Link 虚拟串口提供调试控制台。

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 进行版本管理

1.5 本章小结

本章作为课程导论,完成了以下铺垫:

  • 阐述了 ACM Gadget 在驱动学习中的独特价值——单板可调试、协议标准、代码精简。
  • 对比了 Host 侧与 Device 侧 USB 串口驱动的差异,明确了本课程的聚焦范围。
  • 介绍了 STM32MP157D-DK1 目标板的硬件规格和 Ubuntu 22.04 + Linux 6.1 的软件环境。
  • 给出了开发环境拓扑图和 5 阶段 30 章的学习路径。