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 内核中由下至上分为三层:

在这里插入图片描述

  1. 物理层 (Hardware): SDIO 控制器,负责时序产生和信号驱动。
  2. 总线核心层 (Bus Core): drivers/mmc/core/sdio*.c。负责设备枚举、CIS 读取、CCCR 配置和中断分发。
  3. 功能驱动层 (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 校验错误或超时。

重试策略:

  1. Command Error: 如果 Host 发送 CMD 后未收到 Response 或 CRC 错误,通常重试 3 次。
  2. Data Error: 数据传输阶段的 CRC 错误,通常由上层驱动决定是否重发(TCP/IP 协议栈本身有重传机制,底层可能不重传)。

3. 操作模式与中断机制

3.1 中断处理机制 (DAT1 Multiplexing)

SDIO 设备是主动的,需要向主机发送中断请求(如收到 Wi-Fi 数据包)。由于引脚限制,SDIO 复用了 DAT1 线作为中断线。

在这里插入图片描述

  • 触发条件: 设备将 DAT1 拉低(Low Level)。
  • 检测时机:
    • 4-bit 模式: 只能在总线空闲(没有数据传输)时检测中断。如果总线正在忙,中断会被挂起,直到传输结束。
    • 1-bit 模式: 专用的 IRQ 引脚(DAT1 此时不用作数据传输),可随时检测。
  • 服务流程:
    1. Host 检测到 DAT1 低电平。
    2. Host 发送 CMD52 读取 Function 0 的 Int Pending 寄存器。
    3. Host 识别是哪个 Function 触发了中断,调用对应的 ISR。
    4. ISR 处理完毕,设备释放 DAT1(拉高)。

3.2 DMA 传输配置

为了提高吞吐量,CMD53 通常配合 DMA 使用。

  1. 构建 Scatterlist: 驱动将数据缓冲区的物理页组织成 sg_list。
  2. DMA Map: 调用 dma_map_sg 将物理地址映射给 DMA 控制器。
  3. 发送 CMD53: 告知设备准备接收/发送数据。
  4. 启动 DMA: 配置 Host 控制器启动 DMA 引擎。
  5. 传输完成: 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 性能优化建议

  1. 最大化 Block Size: 尽量使用 512 字节的 Block Size,减少 CMD53 的头部开销。
  2. 多块传输 (Multi-Block): 避免单字节读写,尽量聚合数据一次性发送。
  3. 对齐优化: 确保数据缓冲区地址和长度是 4 字节对齐的,以满足某些 DMA 控制器的要求。
  4. 异步请求: 使用 mmc_request_done 异步回调机制,避免阻塞 CPU。

5. 术语对照表

英文 中文 解释
CIA 公共 I/O 区域 Function 0 的寄存器空间,用于全局控制
CIS 卡信息结构 存储设备厂商、ID、功能描述的元数据
CCCR 卡公共控制寄存器 控制总线速度、位宽、中断使能的寄存器
FBR 功能基本寄存器 每个 Function 独有的配置寄存器
CMD52 直接 I/O 命令 读写单个寄存器的命令
CMD53 扩展 I/O 命令 读写数据块的命令
Block Mode 块模式 以块(通常 512B)为单位传输数据

参考文献:

  1. SDIO Simplified Specification Version 3.00
  2. Linux Kernel Source: drivers/mmc/core/sdio.c
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐