一文读懂树莓派 Pico USB:硬件原理、外设架构与 MicroPython 软件控制

1.树莓派 Pico 的 USB 外设概要信息

树莓派 Pico 的 RP2040 芯片包含一个 USB 2.0 控制器,可以作为任何一种方式操作:

  • 一个全速设备(12Mbps)
  • 一个可以与低速(1.5Mbps)和全速设备通信的主机,包括连接到一个 USB 集线器的多个下游设备

RP2040 芯片内部集成了一个 USB 1.1 PHY 芯片,USB 控制器与芯片的 DP(D+)和 DM(D-)引脚接口通过 PHY 芯片相连接。USB 控制器的硬件实现了了 USB 物理层、数据链路层和一部分事务层的功能,这意味着程序员不需要手动处理复杂的 USB 协议细节。而是将重心放在以下工作上:

  • 配置控制器参数,如设备地址、端点等
  • 提供数据缓冲区,供控制器收发数据
  • 响应控制器的中断事件,如数据传输完成、端点状态变更

USB 控制器有 4kB 的 DPSRAM,用于存储 USB 设备的配置信息和数据缓冲区。

USB 控制器可以工作于两种工作模式:

  • 设备模式:
    • USB 2.0 兼容的全速设备(12Mbps)
    • 它支持最多 32 个端点(在输入和输出方向上分别为 0 → 15)
    • 该设备支持控制、等时、批量和中断端点类型,并支持双缓冲
    • 在 DPSRAM 中有 3840 字节的可用缓冲空间,相当于 60 × 64 字节的缓冲区
  • 主机模式:
    • 可以与全速(12Mbps)设备和低速(1.5Mbps)设备进行通信
    • 它可以通过 USB 集线器与多个设备进行通信,包括连接到全速集线器的低速设备
    • 设备可以在硬件中轮询多达 15 个中断端点
    • 中断端点由集线器用于通知主机连接/断开事件,鼠标用于通知主机移动等

USB 外设结构如下:

1280X1280.PNG

可以看到,USB 外设主要由以下几个部分组成:

  • 集成的USB​ ​PHY芯片
    • 负责实现 USB 物理层协议,包括电气特性、信号编码、差分传输等
    • 提供了 USB DP 和 DM 引脚与控制器数字逻辑之间的电气接口
    • USB PHY 驱动 DP 和 DM 引脚发送数据,并对任何传入数据进行差分接收
    • USB PHY 向线路状态检测模块提供单端和差分接收数据
  • USB 控制器
    • 负责实现 USB 设备端的协议栈和端点管理
    • 负责数据的接收和发送,以及控制信号的生成和解析
  • 缓冲区存储器
    • DPSRAM 用于存储控制寄存器和数据缓冲区
    • USB 控制器有 4kB(4096 字节)的 DPSRAM(双端口 SRAM)
    • DPSRAM 可以作为 32 位宽度的内存访问,地址为 USB 控制器的地址 0(0x50100000)
    • DPSRAM 支持 8/16/32 位访问,但不支持设置/清除别名
    • 数据缓冲区通常为 64 字节长:
      • 对于 Isochronous 同步传输方式,最大缓冲区大小为 1023 字节
      • 对于其他传输方式,每个缓冲区的最大大小为 64 字节
    • USB 控制器中的 DPSRAM 应被视为异步的,而不是原子的:
      • 它是一个双端口 SRAM,意味着处理器有一个端口来读写内存,USB 控制器也有一个端口来读写内存。这意味着处理器和 USB 控制器可以同时访问同一个内存地址。一个可能正在写入,另一个可能正在读取。如果控制器在读取内存时处理器正在写入内存,可能会得到不一致的数据。必须小心避免这种情况
  • 线路状态检测模块
    • 定义并检测几种线路状态(总线重置、连接、挂起、恢复、数据 1、数据 0 等)
    • 线路状态检测模块有几个状态机来检测这些状态,并将事件信号通知给其他硬件组件
    • USB 中没有共享时钟信号,因此 RX 数据必须由内部时钟采样
    • USB 全速的最大数据速率是 12Mbps。RX 数据以 48MHz 的速度采样,给出 4 个时钟周期来捕获和过滤总线状态,线路状态检测模块将过滤后的 RX 数据分发到串行 RX 引擎
  • 接收引擎
    • 串行接收引擎负责解码由线路状态检测模块捕获的接收数据。它生成以下信息:
      • 入站数据包的 PID(Packet Identifier)
      • 入站数据的设备地址 address
      • 入站数据的设备端点 endpoint
      • 数据字节
    • 串行接收引擎还通过对入站数据进行 CRC 校验来检测 RX 数据中的错误。任何错误都会信号通知其他硬件块,并可能引发中断
    • 如果在主机模式或设备模式下在数据包传输过程中断开 USB 电缆,硬件会引发错误
  • 发送引擎
    • 串行发送引擎是串行接收引擎的镜像。它连接到当前活动的控制器(无论是设备还是主机)。它创建 TOKEN 和 DATA 数据包,包括计算 CRC,并在总线上传输它们

2.软件控制方法

对于 MicroPython 而言,它将 USB 设备划分为以下两种:

  1. "Runtime" USB 设备:
    1. 使用 Python API (USBDevice 类)在 MicroPython 启动后定义;
    2. 需要在运行时配置和激活。
  2. "Built-in" USB 设备:
    1. 编译到 MicroPython 固件中,始终可用;
    2. 通常包括 USB-CDC (串口) 和可选的 USB-MSC (大容量存储);
    3. 开箱即用,无需额外配置。

MicroPython 提供了用于实现 USB 设备驱动的底层 Python API 的 USBDevice 类:

  • 构造函数:
    • USBDevice 是一个单例类,每次调用构造函数都返回相同的对象引用;
  • 主要方法:
    • config() 方法用于配置 USB 设备的描述符和回调函数;
    • active() 方法用于激活和停用 runtime USB 设备;
    • builtin_driver 属性用于获取/设置内置 USB 驱动配置;
    • remote_wakeup() 方法用于唤醒处于挂起状态的 USB 主机;
    • submit_xfer() 方法用于提交非控制传输;
    • stall() 方法用于设置和获取端点的 STALL 状态;
  • 常量:
    • BUILTIN_NONE, BUILTIN_DEFAULT, BUILTIN_CDC, BUILTIN_MSC, BUILTIN_CDC_MSC 代表不同的内置 USB 驱动配置

遗憾的是,根据如下链接中的回答,我们可以看到对树莓派 Pico 来说,无法像使用 STM32 芯片的 PyBoard 一样使用 USBDevice 类控制"Runtime" USB 设备:

https://github.com/micropython/micropython/issues/6811

2.png

但是联想到我们在介绍 REPL 交互式解释器中内容,在树莓派 Pico 上,MicroPython 固件默认包含了内置的 USB-CDC 设备驱动,提供了一个虚拟的串口通信通道,这个 USB-CDC 设备是集成在 MicroPython 固件中的"Built-in"设备,无需额外的配置就可以使用。这意味着,我们可以使用该虚拟串口配合系统输入输出就可以完成 USB 数据传输。

posted @ 2026-09-01 19:18  FreakStudio  阅读(10)  评论(0)    收藏  举报