eMMC 总线协议基础:命令、响应、数据传输
大家好。这一章我们来聊聊 eMMC 总线上到底在跑什么东西。说白了,Host 和 Device 之间就靠三组信号线打交道——命令线(CMD)、响应线(RESP)、数据线(DAT)。这三条“线”怎么用、什么时候用、用错了会怎样,是入门 HS400 的前提。
我记得刚开始做 eMMC 驱动时,总以为命令和数据是同时跑的。结果一上示波器,发现命令发完好久才等到响应……嗯,这里门道不少。下面我把它们拆开讲清楚。
1. 三根信号线,各司其职
先看一张总图,把这章的脉络印在脑子里:
从图里你能看到:CMD 线是双向的,但绝大多数时候是 Host 在说;RESP 线是单向,Device 回应;DAT 线多条,走实际数据。为什么要画成双向箭头?我遇到过有人以为 CMD 只能 Host 发——其实 Device 也能在 CMD 上发 busy 信号,但规则很严格。
2. 命令(CMD)——Host 的“指令牌”
eMMC 命令的格式很固定。每个命令 48 位,结构如下:
| 位域 | 宽度 | 说明 |
|---|---|---|
| 起始位 | 1 bit | 固定为 0 |
| 传输方向 | 1 bit | Host→Device 为 1 |
| 命令索引 | 6 bits | CMD0 ~ CMD63 |
| 参数 | 32 bits | 具体含义依赖命令 |
| CRC7 | 7 bits | 校验命令本身 |
| 结束位 | 1 bit | 固定为 1 |
你想想看,48 位里真正管事的只有命令索引和参数。比如 CMD1(发送操作条件)的参数就是 OCR 寄存器里的电压信息。我个人习惯把常用命令编个表贴在调试台前,省得每次都翻 spec。
3. 响应(RESP)——Device 的“回执”
Device 收到命令后,必须在 64 个时钟周期内返回响应,否则 Host 就认为超时,重发或报错。响应类型有 R1、R1b、R2、R3、R4、R5 等,最常用的是 R1 和 R2。
咱们拿 R1 举例:它也是 48 位,结构几乎和命令一样,但传输方向位是 0(Device→Host),而且参数区域变成了状态位。R1 的 32 位参数里包含了错误标志(如地址错误、CRC 错误)、当前状态、卡识别等。
- R1(48 位):普通命令响应,带状态信息。
- R1b(48 位 + busy 信号):R1 基础上,Device 拉低 DAT0 表示忙。
- R2(136 位):CID 或 CSD 寄存器内容,发送时实际分 2 个时钟周期。
- R3(48 位):OCR 寄存器内容,仅用于 CMD1。
4. 数据传输——DAT 线上的搬运工
数据流通过 DAT[7:0] 线传输。eMMC 5.1 支持单线、4 线、8 线模式。HS400 强制使用 8 线双沿(DDR)模式,也就是每个时钟沿都传数据。
数据传输分为两种基本类型:
- 块传输(Block Transfer):固定大小块,默认 512 字节,可通过 CMD16 设置。
- 流传输(Stream Transfer):连续数据,无固定块边界(早期 MMC 支持,eMMC 已废弃)。
写数据的典型流程:Host 发写命令(CMD24/CMD25)→ Device 返回 R1 → Host 发数据块(带 CRC16)→ Device 回复 CRC 状态 → 最后 Device 拉低 DAT0 表示忙。
读数据类似:Host 发读命令(CMD17/CMD18)→ Device 返回 R1 + 数据块 + CRC16 → Host 检查 CRC。
5. 信号时序与状态机
eMMC 设备内部有一个有限状态机,从上电 idle 开始,经过初始化、识别、传输等状态。命令只能在特定状态下执行。比如 CMD6(切换功能)只能在 transfer state 下发。我在刚学的时候把 CMD2(获取 CID)在 transfer 状态下发,当然没反应……
不多展开状态机细节,但记住一条:命令和状态是绑定的。调程序时先读一遍状态,再决定发什么命令。
6. 小结几个容易忘的点
- CMD 线是开漏/推挽模式切换的。初始化阶段开漏,之后切换成推挽。
- 响应必须在 64 个时钟内到达,否则视为超时。
- 数据块大小默认为 512 字节,但可以通过 CMD16 改变,不过 HS400 模式下建议用 512 对齐。
- DAT0 线除了传数据,还用于 busy 指示。Device 拉低 DAT0 时,Host 必须等待。
这章基础必须打牢。后面讲 HS400 切换、时钟配置、校准流程时,都会用到这里的命令-响应-数据流模型。嗯,今天就到这儿。