SD及eMMC调试和性能优化
SD/eMMC调试和性能优化
内容:
eMMC存储器的调试、关于协议规范的总结以及MMC驱动分析
eMMC架构分析
简单来说,eMMC = Nand Flash闪存 + controller闪存控制器 + 标准封装接口;而eMMC设备和主机系统的连接通常由三部分组成:eMMC主机控制器(一般是嵌入式SOC中某个模块)、eMMC总线、eMMC设备
eMMC协议规定的设备引脚
CLK:主机提供给设备的时钟信号;SDR模式下,一个时钟周期传输1bit信号;DDR模式下,一个时钟周期传输2bit信号;
CMD:主机与设备之间用于双向传输的命令线,有开漏和推挽两种模式,分别用来应对初始化和应对快速的命令传输。
Reset:主机发送给设备的复位信号。
DAT0~DAT7:用于主机和设备间数据通信的双向数据总线,但是在某一时刻只能支持单向传输
Data Strobe:数据锁存线,HS400模式下用于锁存输出信号
eMMC供电
VCC/VCC-eMMC:给eMMC device或者闪存供电
VCCQ:给eMMC闪存控制器及I/O接口供电
SD与eMMC
SD/SDIO的总线模式
SD/SDIO支持1/4 bit线宽模式,只有DDR50是双边沿采样,其余模式为单边沿采样;SD/SDIO 2.0协议支持3.3V电压,SD/SDIO 3.0协议支持3.3V和1.8V电压。
eMMC的总线模式
eMMC支持1/4/8 bit线宽模式,支持5种速度模式
模式名 |
数据速率模式 |
I/O电压 |
总线位宽 |
时钟频率 |
最大数据传输速率 |
---|---|---|---|---|---|
兼容MMC模式 |
single |
3/1.8/1.2V |
1/4/8 bit |
0~26MHz |
26 MB/s |
HS SDR模式 |
single |
3/1.8/1.2V |
1/4/8 bit |
0~52MHz |
52 MB/s |
HS DDR模式 |
dual |
3/1.8/1.2V |
4/8 bit |
0~52MHz |
104 MB/s |
HS200模式 |
single |
1.8/1.2V |
4/8 bit |
0~200MHz |
200 MB/s |
HS400模式 |
dual |
1.8/1.2V |
8 bit |
0~200MHz |
400 MB/s |
single速率模式即所有信号采用单边沿采样(上升沿采样)
dual速率模式的Response信号采用单边沿采样,数据采用双边沿采样(CLK上升下降沿采样)
HS400模式的Response信号采用单边沿采样,读写操作时数据线采样方式:
读操作时数据线上的Data、CRC16为双边沿采样,通过DS信号上升下降沿采样;读操作时数据线上的Start bit和End bit为单边沿采样,通过DS信号上升沿采样
写操作时数据线DAT0上CRC status token为单边沿采样,在DS信号上升沿采样
eMMC内部寄存器
eMMC内部寄存器一共有6中。它们可以得到设备的相关内容以及设置工作时的控制对象,在读写数据前的步骤操作相对应的寄存器实现。因此协议中明确定义所用寄存器的含义。
名称 |
大小(bits) |
描述 |
---|---|---|
CID |
128 |
只读寄存器,包含厂商信息,产品号,串号以及生产日期设备唯一识别号 |
RCA |
16 |
相关设备地址,在初始化过程中由主机控制器动态分配的系统地址 |
DSR |
16 |
驱动等级寄存器,配置设备的输出驱动 |
OCR |
32 |
操作状态寄存器,通过广播命令获取寄存器信息,包含设备的供电类型 |
CSD |
128 |
设备具体的数据寄存器,包含了设备操作状态的具体信息 |
EXT_CSD |
512*8 |
扩展设备具体数据寄存器,包含设备的容量和当前模式信息 |
eMMC数据通信
Host与eMMC device之间的通信都是由Host以一个Command开始发起的,eMMC device在完成command所指定的任务后,则返回一个reponse。
对eMMC device读写数据都是以Block为单位,Block大小由host设定,或者固定为512 Bytes,不同的速率模式下有所不同。
No Data : 部分Host与eMMC device的交互不需要进行数据交互,有些甚至不需要eMMC Device的response
Read Data:读数据流程分为单块读和多块读,在多块读时,如果指定了block count则不需要主机处理直到数据读取完成,若没有指定block count则eMMC Device会持续发送数据,直到Host发送Stop command停止数据传输。
Write Data:单块写会将一个block的数据写入寄存器;多块写会写入设定block count的数据到寄存器,若没有设定block count则需要等到Host发送Stop command停止数据传输;eMMC device在接收到一个Block的数据后,会进行CRC校验,然后将校验结果通过CRC Token发送给Host,若CRC校验成功,eMMC Device会将数据写入到内部寄存器,此时DAT0信号拉低,作为Busy信号。Host会持续检测DAT0信号,直到为高电平时,才会接着发送下一个Block的数据。若CRC校验失败,则数据不会写入,此次传输后续的数据都会被忽略。
eMMC命令编码
Command:eMMC command由48 bits组成,各个bits的解析如下:
Start Bit固定为 “0”,在没有数据传输的情况下,CMD信号保持高电平,当Host将Start Bit发送到总线上时,eMMC Device可以很方便检测到该信号,并开始接收command
Transmission Bit固定为 “1”,指示了该数据包的传输方向为Host发送到eMMC Device
Command Index和Argument为具体Command的内容
CRC7是包含Start Bit、Transmission Bit、Command Index和Argument内容的CRC校验值
End Bit为结束标志位,固定为1
CRC校验:简单来说,就是发送方将需要传输的数据“除于”(模2除)一个约定的数,并将得到的余数附在数据上一并发送出去。接收方收到数据后,再做同样的“除法”,然后校验得到余数是否与接收的余数相同。
Response
eMMC Response有两种长度的数据包,分别为48bits和136bits
Start Bit固定为 “0”,在没有数据传输的情况下,CMD信号保持高电平,当eMMC device将Start Bit发送到总线上时,Host可以很方便检测到该信号,并开始接收reponse
Transmission Bit固定为 “0”,指示了该数据包的传输方向为eMMC Device发送到Host
Content为Reponse的具体内容,不同的Command会有不同的Content
CRC7是包含Start Bit、Transmission Bit和Content内容的CRC校验值
End Bit为结束标志位,固定为1
Data Block
Data block由start bit、data、CRC16(data的16bit CRC校验值)、End bit组成
1Bit Bus SDR
4 Bits Bus SDR
8 Bits Bus SDR
4 Bits Bus DDR
8 Bits Bus DDR
在 DDR 模式下,Data Line 在时钟的上升沿和下降沿都会传输数据,其中上升沿传输数据的奇数字节 (Byte 1,3,5 …),下降沿则传输数据的偶数字节(Byte 2,4,6 …)。
此外,在 DDR 模式下,1 个 Data Line 上有两个相互交织的 CRC16,上升沿的 CRC 比特组成 odd CRC16,下降沿的 CRC 比特组成 even CRC16。odd CRC16 用于校验该 Data Line 上所有上升沿比特组成的数据,even CRC16 则用于校验该 Data Line 上所有下降沿比特组成的数据。
CRC Status Token
在写数据传输中,eMMC Device接收到Host发送的一个Data Block后,会进行CRC校验,如果校验成功,eMMC会在对应的Data Line上向Host发回一个Positive CRC status token(010),如果校验失败,则会在对应的Data Line上发送一个Negative CRC status token(101)
eMMC总线测试
当eMMC Device处于SDR模式时,Host可以发送CMD19命令,触发总线测试过程(Bus testing procedure),测试总线硬件上的连通性。如果eMMC Device支持总线测试,那么eMMC Device在接受到CMD19后,会发回对应的Response,接着eMMC Device会发送一组固定的测试数据给Host。Host接收到数据后,检查数据正确与否,即可得知总线是否正确联通。(总线测试在DDR模式下不支持)
由于芯片制造工艺、PCB走线、电压、温度等因素的影响,数据信号从eMMC Device到达Host端的时间是存在差异的,Host接收数据时采样的时间点也需要相应的进行调整。而Host端最佳采样时间点,则是通过Sampling Tuning流程得到,在eMMC标准中,定义了在HS200模式下可以进行Sampling Tuning,流程如下:
Host将采样时间点重置为默认值
Host 向 eMMC Device 发送 Send Tuning Block 命令
eMMC Device 向 Host 发送固定的 Tuning Block 数据
Host 接收到 Tuning Block 并进行校验
Host 修改采样时点,重新从第 2 步开始执行,直到 Host 获取到一个有效采样时间点区间
Host 取有效采样时间点区间的中间值作为采样时间点,并退出 Tuning 流程
Tuning 流程执行的时机、频率和具体的步骤是由 Host 端的 eMMC Controller 具体实现而定的。
Tuning Block是专门为了Tuning而设计的一组特殊数据。相对于普通的数据,这组特殊数据在传输过程中,会更高概率的出现 high SSO noise、deterministic jitter、ISI、timing errors 等问题。这组数据的具体内容如下所示:
eMMC命令
eMMC工作模式
eMMC Device在Power On、HW Reset或者SW Reset时,Host可以触发eMMC Boot,让eMMC进入Boot Mode,在此模式下,eMMC Device会将Boot Data发送给Host,这部分内容通常为系统的启动代码,如bootloader
如果Host没有触发Boot流程完成后,eMMC Device会进入Device Identification Mode在此模式下,eMMC Device将进行初始化,Host会为eMMC Device设定工作电压、协商寻址模式以及分配RCA设备地址
Device Identification Mode结束后,就会进入Data Transfer Mode,在此模式下,Host可以发起数据读写请求
进入Data Transfer Mode后,Host可以发起命令,让eMMC Device进入Interrupt Mode。在此模式下,eMMC Device会等待内部的中断事件,例如,写数据完成等。eMMC Device在收到内部中断事件时,会向Host发送reponse,然后切换到Data Transfer mode,等待Host后续的数据读写命令。
命令名称 |
描述 |
命令类型 |
---|---|---|
CMD0 |
rest设备,是设备进入Idle状态 |
基本命令class 0 & class 1 |
CMD1 |
同步命令,用来协商操作电压范围以及查看设备是否仍处于power-up序列 |
基本命令class 0 & class 1 |
CMD2 |
从device端获取CID |
基本命令class 0 & class 1 |
CMD3 |
设置设备的RCA |
基本命令class 0 & class 1 |
CMD4 |
设置DSR寄存器 |
基本命令class 0 & class 1 |
CMD5 |
切换到sleep state或standby state |
基本命令class 0 & class 1 |
CMD6 |
切换设备的操作模式或者修改EXT_CSD寄存器 |
基本命令class 0 & class 1 |
CMD7 |
当设备处在Stand-by状态,CMD7把设备从Stand-by State切换到Transfer State;也可以把设备从Transfer State切换回Stand-by State |
基本命令class 0 & class 1 |
CMD8 |
请求设备发送它的EXT_CSD寄存器,通过数据块的方式发送 |
基本命令class 0 & class 1 |
CMD9 |
请求设备发送CSD到CMD line上 |
基本命令class 0 & class 1 |
CMD10 |
请求设备发送CID到CMD line |
基本命令class 0 & class 1 |
CMD12 |
终止传输命令 |
基本命令class 0 & class 1 |
CMD13 |
发送设备状态寄存器 |
基本命令class 0 & class 1 |
CMD14 |
主机从设备端读取测试模式数据 |
基本命令class 0 & class 1 |
CMD15 |
设置设备状态为inactive |
基本命令class 0 & class 1 |
CMD19 |
Host发送总线测试模式数据到device |
基本命令class 0 & class 1 |
CMD16 |
设置block大小 |
面向读命令class 2 |
CMD17 |
单块读命令 |
面向读命令class 2 |
CMD18 |
多块读命令 |
面向读命令class 2 |
CMD21 |
HS200模式专用,用来优化HOST采样点,HOST发送CMD21命令,device发送tuning模式数据块。Host会在不同采样点采集数据,找到最佳采样点 |
面向读命令class 2 |
CMD23 |
设置读写block数目 |
面向写命令class 4 |
CMD24 |
单块写 |
面向写命令class 4 |
CMD25 |
多块写 |
面向写命令class 4 |
CMD26 |
编写CID |
面向写命令class 4 |
CMD27 |
编写CSD |
面向写命令class 4 |
CMD49 |
设置时钟 |
面向写命令class 4 |
CMD28 |
设置指定地址的写保护位 |
面向块的写保护命令class 6 |
CMD29 |
清除指定地址的写保护位 |
面向块的写保护命令class 6 |
CMD30 |
请求设备发送写保护位状态 |
面向块的写保护命令class 6 |
CMD31 |
请求设备发送写保护类型 |
面向块的写保护命令class 6 |
CMD35 |
设置擦除操作的首地址 |
擦除命令class 5 |
CMD36 |
设置擦除操作的尾地址 |
擦除命令class 5 |
CMD38 |
擦除所设置地址 |
擦除命令class 5 |
CMD39 |
用来读写8bit寄存器数据 |
IO模式命令class 9 |
CMD40 |
设置设备进入中断模式 |
IO模式命令class 9 |
eMMC调试
典型问题排查步骤
检查原理图和PCB(硬件器件是否有问题)
检查供电电源(是否存在倒灌电和上下电时序不满足的问题)
检查设备端是否有问题,一般通过异常打印判断然后分信息
一般通过抓取波形进行分析,从CMD、CLK、DATx 、GND进行引线,线长不超过2~3cm
一般打印错误类型有RE(Response Error)、RCE(Reponse CRC Error)、RTO(Response Time out)、DCE(Data CRC Error)、EBE(Data End-bit Error)、DTO(Data Time Out)、SBE(Start Bit Error)、FRE(FIFO Request Error)
排查方向:
检查驱动中的配置,像超时的时间是否符合协议和数据手册的要求规定
存器方向去检查是否可以收到相关数据,确认主机控制器端是否的收发是否正常
从硬件上使用逻辑分析仪抓取异常波形,对照相应的异常进行分析,比如reponse波形是否符合协议规定等
eMMC驱动
MMC/SD卡的驱动程序位于drivers/mmc目录下,框架如下:
区块层:按照Linux块设备驱动框架实现一个卡的块设备驱动,block.c实现块设备操作函数,queue.c提供块设备请求队列的封装
核心层:封装了MMC/SD卡的命令,诸如存储卡的识别,设置,读写。core.c将MMC卡、SD卡的共性抽象出来,他们的差别由sd.c和sd_ops.c、mmc.c和mmc_ops.c来完成
主控驱动层:主机控制器驱动实现依赖于不同的平台,针对不同的产商控制器来实现,主要是中断以及其他硬件资源申请获取配置控制器,然后行core层注册一个host
eMMC性能优化与功耗管理
eMMC的性能测试与性能优化?
基于平台(Android)使用AndroBench,PC端使用CDM软件测试eMMC性能。
性能优化一般是抓取波形,查看命令空闲的情况,对于驱动层来说就是对于命令的处理方式,是否能保证命令的满载状态,在性能测试时不出现空闲的情况。
eMMC的功耗管理?
对于底层设备端而言,功耗管控就是闪存控制器flash频率的配置,就是闪存控制器闲时flash需不需要进行数据处理。对于驱动层来说就是对eMMC卡的休眠唤醒的处理流程。