【Linux驱动开发】SDIO (Secure Digital Input Output) 设备协议技术详解
本文详细介绍了SDIO(Secure Digital Input Output)设备协议技术。SDIO协议在SD存储卡协议基础上扩展,提供标准化的I/O接口,支持1-bit和4-bit两种总线模式,电压范围2.7V-3.6V,时钟频率最高208MHz。协议栈分为物理层、总线核心层和功能驱动层。SDIO通过CMD52/CMD53命令实现单字节和多字节数据传输,并采用DAT1复用线实现中断机制。文章还
·
SDIO (Secure Digital Input Output) 设备协议技术详解
1. 协议基础架构
SDIO 协议是在 SD 存储卡协议的基础上扩展而来的,旨在为便携式设备提供标准化的 I/O 接口。它不仅继承了 SD 卡的物理特性,还引入了全新的 I/O 读写机制和中断处理能力。
1.1 物理层规范
SDIO 接口复用了 SD 卡的引脚定义,支持 1-bit 和 4-bit 两种总线模式。
| 引脚 | 名称 (1-bit) | 名称 (4-bit) | 描述 |
|---|---|---|---|
| 1 | CD/DAT3 | CD/DAT3 | 卡检测 / 数据线 3 |
| 2 | CMD | CMD | 命令/响应线 (双向) |
| 3 | VSS1 | VSS1 | 地 (GND) |
| 4 | VDD | VDD | 电源 (3.3V / 1.8V) |
| 5 | CLK | CLK | 时钟线 (Host -> Device) |
| 6 | VSS2 | VSS2 | 地 (GND) |
| 7 | DAT0 | DAT0 | 数据线 0 |
| 8 | DAT1 | DAT1/IRQ | 数据线 1 / 中断线 |
| 9 | DAT2 | DAT2 | 数据线 2 |
电气特性:
- 电压范围:
- High Voltage: 2.7V - 3.6V
- Low Voltage (UHS): 1.70V - 1.95V
- 时钟频率:
- Default Speed: 0 - 25 MHz
- High Speed: 0 - 50 MHz
- UHS-I: up to 208 MHz
1.2 协议栈分层
SDIO 协议栈在 Linux 内核中由下至上分为三层:

- 物理层 (Hardware): SDIO 控制器,负责时序产生和信号驱动。
- 总线核心层 (Bus Core):
drivers/mmc/core/sdio*.c。负责设备枚举、CIS 读取、CCCR 配置和中断分发。 - 功能驱动层 (Function Driver):
drivers/net/wireless/等。具体的设备驱动(如 Wi-Fi、GPS),通过sdio_register_driver注册。
2. 通信协议详解
2.1 命令帧结构 (CMD52/CMD53)
SDIO 引入了两个专用的 I/O 命令:CMD52 (单字节读写) 和 CMD53 (多字节/块读写)。

-
CMD52 (IO_RW_DIRECT):
- 用于读写单个 8-bit 寄存器。
- RAW (Read after Write): 写入后立即返回该地址的新值,用于确认写入是否成功。
- 常用于初始化配置(如设置总线宽度、使能中断)。
-
CMD53 (IO_RW_EXTENDED):
- 用于读写大数据块(如网络包)。
- Block Mode: 设置 Block 位,以块为单位传输(效率高)。
- Op Code:
0(Fixed Address): 读写 FIFO(如数据寄存器)。1(Incrementing Address): 读写一段内存区域。
2.2 错误处理机制
SDIO 传输过程中可能出现 CRC 校验错误或超时。
重试策略:
- Command Error: 如果 Host 发送 CMD 后未收到 Response 或 CRC 错误,通常重试 3 次。
- Data Error: 数据传输阶段的 CRC 错误,通常由上层驱动决定是否重发(TCP/IP 协议栈本身有重传机制,底层可能不重传)。
3. 操作模式与中断机制
3.1 中断处理机制 (DAT1 Multiplexing)
SDIO 设备是主动的,需要向主机发送中断请求(如收到 Wi-Fi 数据包)。由于引脚限制,SDIO 复用了 DAT1 线作为中断线。

- 触发条件: 设备将 DAT1 拉低(Low Level)。
- 检测时机:
- 4-bit 模式: 只能在总线空闲(没有数据传输)时检测中断。如果总线正在忙,中断会被挂起,直到传输结束。
- 1-bit 模式: 专用的 IRQ 引脚(DAT1 此时不用作数据传输),可随时检测。
- 服务流程:
- Host 检测到 DAT1 低电平。
- Host 发送 CMD52 读取 Function 0 的 Int Pending 寄存器。
- Host 识别是哪个 Function 触发了中断,调用对应的 ISR。
- ISR 处理完毕,设备释放 DAT1(拉高)。
3.2 DMA 传输配置
为了提高吞吐量,CMD53 通常配合 DMA 使用。
- 构建 Scatterlist: 驱动将数据缓冲区的物理页组织成 sg_list。
- DMA Map: 调用
dma_map_sg将物理地址映射给 DMA 控制器。 - 发送 CMD53: 告知设备准备接收/发送数据。
- 启动 DMA: 配置 Host 控制器启动 DMA 引擎。
- 传输完成: DMA 中断触发,Host 结束命令。
4. 驱动开发指南
4.1 关键数据结构
/* include/linux/mmc/sdio_func.h */
struct sdio_func {
struct mmc_card *card; /* 关联的 SDIO 卡 */
struct device dev; /* 设备结构体 */
unsigned int num; /* Function Number (1-7) */
unsigned int max_blksize;/* 最大块大小 */
unsigned int cur_blksize;/* 当前块大小 */
unsigned int class; /* 标准接口类 (如 WLAN) */
unsigned int vendor; /* 厂商 ID */
unsigned int device; /* 设备 ID */
unsigned irq_handler;/* 中断处理函数 */
};
4.2 驱动注册示例
static const struct sdio_device_id my_sdio_ids[] = {
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, my_sdio_ids);
static struct sdio_driver my_sdio_driver = {
.name = "my_sdio_wifi",
.id_table = my_sdio_ids,
.probe = my_sdio_probe,
.remove = my_sdio_remove,
};
module_sdio_driver(my_sdio_driver);
4.3 性能优化建议
- 最大化 Block Size: 尽量使用 512 字节的 Block Size,减少 CMD53 的头部开销。
- 多块传输 (Multi-Block): 避免单字节读写,尽量聚合数据一次性发送。
- 对齐优化: 确保数据缓冲区地址和长度是 4 字节对齐的,以满足某些 DMA 控制器的要求。
- 异步请求: 使用
mmc_request_done异步回调机制,避免阻塞 CPU。
5. 术语对照表
| 英文 | 中文 | 解释 |
|---|---|---|
| CIA | 公共 I/O 区域 | Function 0 的寄存器空间,用于全局控制 |
| CIS | 卡信息结构 | 存储设备厂商、ID、功能描述的元数据 |
| CCCR | 卡公共控制寄存器 | 控制总线速度、位宽、中断使能的寄存器 |
| FBR | 功能基本寄存器 | 每个 Function 独有的配置寄存器 |
| CMD52 | 直接 I/O 命令 | 读写单个寄存器的命令 |
| CMD53 | 扩展 I/O 命令 | 读写数据块的命令 |
| Block Mode | 块模式 | 以块(通常 512B)为单位传输数据 |
参考文献:
- SDIO Simplified Specification Version 3.00
- Linux Kernel Source:
drivers/mmc/core/sdio.c
更多推荐
所有评论(0)