3. SDIO协议栈
做 SDIO 吞吐性能测试,首先得把协议栈吃透。你说你调驱动调了两年,但吞吐就是上不去——问题八成出在对协议层次的理解上。这一章我们就把物理层、传输层、命令与响应拆开揉碎,一个个讲清楚。
我个人习惯把协议栈比作“快递公司三层架构”:物理层是马路和货车,传输层是快递员的派送规则,命令与响应则是快递单上的收发地址和回执。你想想看,如果马路坑坑洼洼、货车限速、快递员乱送、单子又看不清,吞吐能高才怪。
3.1 物理层(Physical Layer)
物理层就是最底层的硬件信号。SDIO 使用 SD 总线协议,但命令集和时序略有不同。物理层的关键参数有四个:
| 参数 | 说明 | 我踩过的坑 |
|---|---|---|
| CLK 频率 | 25 MHz(默认)/ 50 MHz(高速) | 有次客户板子信号质量差,50MHz 跑不通,降频到 40MHz 才稳定,但吞吐少了 20% |
| 电压范围 | 1.8V / 3.0V 两档 | 切换电压时如果电平转换芯片延迟没算好,命令会超时 |
| 总线宽度 | 1-bit / 4-bit | 很多新手只用 1-bit,白白浪费 4 倍带宽 |
| 上电时序 | 74 个 CLK 初始化周期 | 我曾经在 FPGA 上少给了 10 个时钟,卡在识别阶段半天 |
物理层瓶颈自查清单:
- 示波器看 CLK 边沿是否干净(过冲 < 0.5V)
- 确认板级走线差分布局,SDIO 对串扰敏感
- 测一下 50MHz 下数据线建立时间是否满足 3ns
3.2 传输层(Transport Layer)
传输层负责把上层命令打包成总线事务。SDIO 没有专门的传输层头部,它复用 SD 的“命令—响应—数据”序列。说白了就是三段式握手:
- CMD 阶段:主机发送 48-bit 命令帧(含 CRC7)
- Resp 阶段:从机返回 48-bit 或 136-bit 响应(含 CRC7)
- Data 阶段:数据块(1~512 字节)加 CRC16,可多块连续传输
这里要注意一个参数:命令响应超时(NCR)。我曾在某国产 WiFi 模块上遇到过,它从收到 CMD52 到返回 R1 响应会拖到 20 个 CLK 以上,而 SD 主机默认 NCR 上限是 64 CLK。虽然没超,但每次都卡在临界值,导致后续数据块准备不足、吞吐骤降。后来我调了驱动程序里的 max_busy_timeout 才解决。
| 传输模式 | 数据线利用率 | 适合场景 |
|---|---|---|
| 单块 | 低(CMD+Resp 开销大) | 寄存器读写、控制命令 |
| 多块(预定义长度) | 高(只需一次 CMD) | 大文件传输、DMA |
| 无限多块(ACMD) | 最高(流式传输) | 音视频流、WiFi 数据包 |
性能测试技巧:想测极限吞吐就选无限多块模式,配合 4-bit 总线、50MHz 时钟、512 字节块大小。我曾用这个组合跑出过 104 MB/s 的原始带宽,接近理论极限。
3.3 命令与响应(CMD & Resp)
SDIO 定义了 6 类命令(CIM、IO、ACMD、应用相关等),最常用的是 CMD52(直接 IO 读写)和 CMD53(扩展 IO 读写)。
CMD52 像 GPIO 操作:一次读/写一个字节,常用于配置寄存器。地址空间 0x000~0x1FF 是公共区域,0x200 以上留给设备自定义。
CMD53 才是吞吐主力。它支持块模式和字节模式,可读写多达 512 字节。响应类型是 R5(48-bit),附带数据线电压切换状态位。
我曾经在一个项目里犯过一个低级错误:用 CMD53 读 512 字节,但块大小设置成了 1 字节。结果每个数据块前面都加了一次 CMD+Resp,吞吐直接砍到 4 MB/s。改成 512 字节块后立刻跳到 85 MB/s。你看,细节决定成败。
命令响应超时避坑指南:
- 调试时先查
cmd_timeout_ms驱动参数,缺省 100ms 可能不够 - 用逻辑分析仪抓 CMD 与 RESP 之间的时钟间隔(NCR 应 < 64 CLK)
- 如果频繁出现
Command timeout日志,八成是物理层不稳定
3.4 协议栈整体结构图
下面这张 SVG 图把三层关系和关键流程画清楚了。建议保存下来当桌面的参考图——我当初就是看着类似的图才理清 SDIO 吞吐瓶颈的。
核心记忆口诀:
物理层看波形,传输层看开销,命令看超时,吞吐就能高。
总结一下本章:
- 物理层是地板,频率、电压、总线宽度缺一不可
- 传输层是传输策略,多块模式是吞吐的关键
- 命令与响应是控制通道,CMD53 要配大块、CMD52 要注意地址范围
- 排查路径:先看物理层信号,再调传输层参数,最后检查响应超时
我的实战建议:刚接手一个 SDIO 设备时,先用逻辑分析仪抓一次 CMD + Resp + Data 的完整波形,看看 NCR、块大小、CRC 是否正常。这一步能节省你至少 3 天的调试时间。