SDIO 控制器是什么?
SDIO 控制器(Secure Digital Input Output Controller)是嵌入式系统中连接非存储类外设的关键模块。它基于扩展的 SD 主机控制器,遵循 SDIO 协议标准,专门用于与 Wi-Fi、蓝牙、FPGA 或自定义从设备进行数据通信。
与传统存储卡不同,SDIO 面向的是外设设备通信。其通信机制采用 命令(CMD)+ 数据(DAT0~DAT3)+ 时钟(CLK) 的组合,支持中断、寄存器访问及异步数据传输等功能。
在实际项目中,如果你需要比 SPI 或 UART 更高带宽且稳定性更好的通信方式,SDIO 是一个非常值得考虑的方案。下面我们从架构、RK3588 平台配置以及 FPGA 实现三个方面展开说明。
SDIO 通信架构
典型的 SDIO 通信链路如下所示:
+-------------------+ +--------------------+
| RK3588 (Host) | <---->| FPGA (Slave) |
| | | |
| SDIO Controller | | SDIO Slave Logic |
+-------------------+ +--------------------+
- 主设备(Host):通常是 ARM SoC(如 RK3588),负责发起命令和时序控制。
- 从设备(Slave):FPGA 模拟 SDIO 设备,响应命令并返回数据。
- 典型线数:CMD、CLK、DAT0~DAT3,可选中断线。
SDIO 控制器的主要功能
| 功能类型 | 说明 |
|---|---|
| 命令控制 | 向设备发送 CMD0~CMD53 等命令 |
| 块/字节传输 | 支持多块(multi-block)与字节级传输 |
| 总线宽度 | 1-bit / 4-bit 模式可选 |
| 中断支持 | 支持设备发起中断(IRQ)到主控 |
| DMA 支持 | 部分 SoC 支持 DMA,可显著提升吞吐量 |
RK3588 的 SDIO 控制器支持
RK3588 内置多个 SDMMC/SDIO 控制器,部分通道可配置为 SDIO 模式。要在实际工程中跑通,通常涉及三个层面:
1. 硬件连线
确保 CMD、CLK、DAT0~DAT3 正确连接到 FPGA 或 WiFi/BT 模块。如果业务需要,还可以添加 CD(卡检测)和 WP(写保护)引脚。
2. 设备树配置 (Device Tree)
在 DTS 中指定该通道为 sdio 模式,而非默认的 mmc 存储设备模式。同时根据硬件情况启用中断、DMA 和总线宽度参数。
3. Linux 驱动开发
Linux 内核中 SDIO 设备走的是 mmc core 框架。主控通过 mmc host 驱动访问 SDIO 设备。如果 FPGA 侧是自定义设备,你需要配套开发 sdio function 驱动,这通常是项目中的难点之一。
FPGA 实现 SDIO 从设备
在 FPGA 中实现 SDIO 从机逻辑,核心在于理解协议栈。主要模块包括:
| 模块 | 功能 |
|---|---|
| SDIO 命令解析器 | 识别 CMD52(寄存器访问)/CMD53(数据传输)等命令 |
| 寄存器接口 | 映射一些'逻辑地址'用于与 Host 通信 |
| 数据收发模块 | 支持 block/byte 读写 |
| CRC/校验模块 | SDIO 有严格的 CRC 校验,需兼容 |
SDIO 典型使用场景
除了常见的存储卡,SDIO 在以下场景应用广泛:
| 场景 | 描述 |
|---|---|
| WiFi 模块 | 如 802.11n WiFi 芯片(ESP32、Realtek 等) |
| 蓝牙模块 | 如 BCM20702、RTL8723 等 |
| FPGA 通信 | FPGA 伪装 SDIO 设备,与主控定制通信 |
| 工业 IO 扩展设备 | 如 GPIO/ADC 采集模块 |
结论
SDIO 控制器是 RK3588 中标准而强大的外设接口,非常适合与 FPGA 等定制设备通信。虽然相比 SPI/UART 需要更复杂的协议栈支持,但其高带宽和稳定性优势明显。如果你正在设计高性能嵌入式系统,不妨将其纳入方案选型。
附录:SDIO 命令集参考
以下是 SDIO(Secure Digital Input Output)命令(CMD)0–53 的完整表格。命令通常以 CMD 开头,编号从 CMD0 到 CMD53,其中 CMD52 和 CMD53 是特定的 IO 命令。
| CMD 编号 | 命令名称 | 类型 | 描述 |
|---|---|---|---|
| 0 | GO_IDLE_STATE | Basic | 复位所有卡到 Idle 状态。 |
| 1 | SEND_OP_COND | SDIO | 启动初始化过程,查询卡是否已准备好(仅 MMC/SDIO)。 |
| 2 | ALL_SEND_CID | Broadcast | 获取卡的 CID 寄存器(卡识别码)。 |
| 3 | SEND_RELATIVE_ADDR | Addressed | 分配并获取卡的 RCA(相对地址)。 |
| 4 | SET_DSR | I/O | 设置设备状态寄存器(极少使用)。 |
| 5 | IO_SEND_OP_COND | SDIO | 检查卡是否为 SDIO 类型,同时启动初始化过程。 |
| 6 | SWITCH_FUNC | SD | 设置或查询卡功能组(如切换速度模式)。 |
| 7 | SELECT/DESELECT_CARD | Addressed | 选择或取消选择卡。 |
| 8 | SEND_IF_COND | SD | 检查电压范围、接口条件(用于识别 SD v2.0+)。 |
| 9 | SEND_CSD | Addressed | 获取 CSD 寄存器(卡的容量、速度等参数)。 |
| 10 | SEND_CID | Addressed | 获取 CID 寄存器。 |
| 11 | READ_DAT_UNTIL_STOP | Deprecated | 已废弃。读取数据直到发送 STOP。 |
| 12 | STOP_TRANSMISSION | Addressed | 停止多块读/写操作。 |
| 13 | SEND_STATUS | Addressed | 获取卡的状态寄存器。 |
| 14 | BUSTEST_R | Test | 总线测试读取(用于制造测试)。 |
| 15 | GO_INACTIVE_STATE | Broadcast | 将卡切换为 Inactivate 状态。 |
| 16 | SET_BLOCKLEN | Addressed | 设置块长度(默认 512 字节)。 |
| 17 | READ_SINGLE_BLOCK | Addressed | 读取单个块数据。 |
| 18 | READ_MULTIPLE_BLOCK | Addressed | 连续读取多个块。 |
| 19 | BUSTEST_W | Test | 总线测试写入(用于制造测试)。 |
| 20 | WRITE_DAT_UNTIL_STOP | Deprecated | 已废弃。写入数据直到 STOP。 |
| 21 | Reserved | 保留命令。 | |
| 22 | Reserved | 保留命令。 | |
| 23 | SET_BLOCK_COUNT | Addressed | 设置将要传输的块数(预写命令)。 |
| 24 | WRITE_BLOCK | Addressed | 写入一个块数据。 |
| 25 | WRITE_MULTIPLE_BLOCK | Addressed | 连续写入多个块数据。 |
| 26 | PROGRAM_CID | Manufacturer | 编程 CID 寄存器(一次性写入)。 |
| 27 | PROGRAM_CSD | Manufacturer | 编程 CSD 寄存器(极少使用)。 |
| 28 | SET_WRITE_PROT | Addressed | 设置写保护。 |
| 29 | CLR_WRITE_PROT | Addressed | 清除写保护。 |
| 30 | SEND_WRITE_PROT | Addressed | 查询写保护状态。 |
| 31 | SEND_WRITE_PROT_TYPE | Addressed | 查询写保护类型(永久/临时)。 |
| 32 | ERASE_WR_BLK_START | Addressed | 指定擦除操作的起始地址。 |
| 33 | ERASE_WR_BLK_END | Addressed | 指定擦除操作的结束地址。 |
| 34 | Reserved | 保留命令。 | |
| 35 | ERASE_GROUP_START | Addressed | 指定擦除组起始地址(大容量卡)。 |
| 36 | ERASE_GROUP_END | Addressed | 指定擦除组结束地址(大容量卡)。 |
| 37 | Reserved | 保留命令。 | |
| 38 | ERASE | Addressed | 执行擦除操作。 |
| 39 | FAST_IO | SDIO | 单位寄存器级别写操作(用于寄存器 IO,极少使用)。 |
| 40 | GO_IRQ_STATE | SDIO | 用于中断处理状态控制。 |
| 41 | Reserved | 保留(用于旧版兼容性)。 | |
| 42 | LOCK_UNLOCK | Addressed | 启用卡锁功能。 |
| 43–49 | Reserved | 保留命令。 | |
| 50 | General Command | SDIO | 保留供未来 SDIO 使用。 |
| 51 | IO_RW_DIRECT | SDIO | SDIO 直接读写命令(CMD52)别名。 |
| 52 | IO_RW_DIRECT | SDIO | 直接读写单字节寄存器,用于配置。 |
| 53 | IO_RW_EXTENDED | SDIO | 用于读写多个字节(块/流)数据。 |
补充说明:
- CMD52 和 CMD53 是 SDIO 通信中最关键的命令:
- CMD52(IO_RW_DIRECT):用于访问单字节寄存器(如功能寄存器、配置寄存器等)。
- CMD53(IO_RW_EXTENDED):用于批量读写,可以是块模式或字节流模式,适用于高速数据传输。
- 广播命令(Broadcast) 作用于总线上所有卡,而非特定卡。
- Addressed 命令 作用于已分配相对地址(RCA)的单个卡。

