依JEDEC eMMC及经验辛苦整理,原创保护,禁止转载。
专栏 《元带你学:eMMC协议》
全文 3200 字, 主要内容
目录
前言
1 Packed Commands 有什么用处?
2 Packed Commands 怎么实现?
Packed Write Flow
Packed Read Flow
3 Packed Command Header 要怎么填?
4 Packed Commands Error Handling 异常怎么定位?
5. Q/A
参考
前言
现实中,对 eMMC Device 随机读写的地址往往都不是连续的,每一个随机读写都需要通过一个独立的读写流程来实现,通常随机读写很慢。有没有好的办法呢?
1 Packed Commands 有什么用处?
eMMC 引入了 Packed Commands 机制,将多个地址不连续的数据写入请求封装到一个 Multiple Block Write 流程中,同时将多个地址不连续的数据读取请求封装的一个 Multiple Block Read 流程中,以此减少读写请求命令数量,减少host 和 eMMC 沟通次数, 提高数据读写的效率。
参考[EMMC Packed Command_emmc cmd23]
Packed Command 是 eMMC 4.5 引入的, 当时还是满有用的。但很可惜, 后面eMMC 引入的 Command Queue Read/Write 速度优势更明显,实现也更友好。所以支持 Packed Command 只是一个过渡期的功能, 就像当年的 Vista 操作系统, 只是昙花一现(介于XP 和 Window7 之间)。
我见过的平台其实都没有用过 packed command, 不是几乎没有,是真的没有。
如果你是host 端人员, 你的平台有这个功能, 你可以继续往下看, 如果没有就不用太花时间了解。细节很多, 但然而不实用。如果是设备端人员, 不好意思, 这个功能是必须的功能, 别人可以不用,你不能不支持,再不情愿也了解清楚吧。
2 Packed Commands 怎么实现?
怎么区分命令是packed command R/W还是 基本R/W?
如果 CMD23的参数的 bit30 置 1,就是打包命令了,未置1,就是普通R/W 的cmd23命令。
图 Packed Command CMD23 和 普通 CMD23 区别
Packed Write Flow?
CMD23(块count N+1) + CMD25 + Data(N)
(1) 打包写命令可以使用设置了打包标志的SET_BLOCK_COUNT命令(CMD23)对几个写多块命令进行分组。
(2) 然后,WRITE_MULTIPLE_BLOCK (CMD25)应该紧随其后,第一个块包含如下所述的packkedcommand头。
(3) 然后,按照在 header中出现的顺序,将各个打包命令的所有数据扇区附加在报头之后发送。在这种情况下,CMD23中指定的块计数应该是各个写操作的所有块计数之和加上 heaer 的1。
Packed Read Flow
CMD23(块count 1) + CMD25 + Data(Header) + CMD23(块count N) + CMD18 + Data(N 块)
第二个CMD23 也可不下, 就变成
CMD23(设置count 1) + CMD25 + Data(Header) + CMD18 + Data
打包读命令可以使用SET_BLOCK_COUNT命令(CMD23)将几个读取多个块命令分组,该命令设置了Packed标志,块计数为1。
然后,WRITE_MULTIPLE_BLOCK (CMD25)应该只跟在报头后面。
然后,CMD23可以再次发送,并设置打包标志,块计数等于单个读取的所有块计数之和(这里的CMD23是可选的-允许开放式读取)。
然后是READ_MULTIPLE_BLOCK (CMD18)来读取打包的数据。主机不应该发送任何其他命令(除了CMD13 SEND_STATUS),直到打包的读命令序列完成(即不允许在发送头和读取数据之间插入命令),否则设备行为未定义。
Command 带的地址怎么设?
在读和写的两种情况下,CMD25的参数(对于打包写和打包读的头)和CMD18的参数应该是由打包组中的第一个单独的读或写命令指定的相同地址。如果参数与第一个单独命令的地址不匹配,则未定义设备行为。
最多可以打包多少读写命令?
单个打包命令中可以打包的最大读或写命令数由设备分别在EXT_CSD的MAX_PACKED_READS和MAX_PACKED_WRITES字段中报告。
3 Packed Command Header 要怎么填?
图 Packed command Header Format
打包的命令头在数据的第一个块(DATA_SECTOR_SIZE[61]- 0x00)上发送,如果是打包的写命令,则在数据的前8个块(DATA_SECTOR_SIZE[61]=0x01)上发送,如果是打包的读命令,则在读取打包的数据之前发送一个单独的写命令。该结构包含:
- 结构的版本-一个字节来指示未来兼容性的版本;应设置为Ox01
- R/W标志-Ox01为打包读,Ox02为打包写
- 表中的表项数
- 然后,对于每个条目:
(1) 单个命令的CMD23参数(4字节),格式化为CMD23,包括"count "字段和各种标志字段(高 位),'打包'位总是'0'(除了'打包'位,所有其他CMD23参数位仍然允许在报头中)。每个单独的读写命令不应是开放式的。如果头中cmd23参数的[15:0]位被设置为0,则设备行为未定义。
(2) CMD18或CMD25的参数(4字节)-由单个命令读取/写入的地址
4 Packed Commands Error Handling 异常怎么定位?
如果发生错误, 后面命令还会执行吗?
不会的,如果单个命令中的一个导致失败,则不会执行同一打包命令中的后面的单个命令。
如果出错了, 还会继续和 host 传数据吗?
对于打包读取,设备可能会为未执行的命令传输一些数据(可能是随机的),以完成指定的块数量(因为主机正在等待所有块)。或者,它可以在故障点停止传输数据,从而导致超时。对于打包写,设备应该忽略未执行命令的传输。
在任何失败的情况下,EXT_CSD中的PACKED_COMMAND_STATUS字段中的通用错误标志被设置(例如,错误的头,包中的命令多于设备支持的命令等)。
如果在打包命令中的单个命令期间出现任何错误,则应设置“错误索引”标志以及通用错误,并且EXT_CSD中的PACKED_FAILURE_INDEX字段应报告失败命令的头块中的索引, 即heaer 中哪一条 Command 出错。
如果发生异常, 在Command 的 response 能侦测到吗?
此外,如果主机通过向EXCEPTION_EVENTS_CTRL写入一个值'1'来启用PACKED_COMMAND_STATUS,则异常事件位可能会在PACKED_COMMAND_STATUS中报告一个非零状态。一旦使能,如果PACKED_COMMAND_STATUS不为零,则设备状态中的异常位(在每个R1响应中报告)将被设置。
当使用打包命令时,命令响应中的错误报告可能会延迟到实际打包读/写传输(传输打包数据的CMD25或CMD18)之后的命令。例如,如果一个打包的命令访问了超出范围的地址。ADDRESS_OUT_OF_RANGE错误可能会延迟.
5. Q/A
哪些分区不能用 Packed Command?
Boot 和 RPMB 不能用, 其他分区可以用。
Packed Command 可以用于做 FFU 吗?
不可以
Packed Command 支持 Cache ON 吗?
支持
Packed Command reliable write 和 force program 吗?
支持
有更多问题,可在评论区留言给我。
参考
[1] JEDEC eMMC 5.1
[2] EMMC Packed Command_emmc cmd23_申小白的博客-CSDN博客
免责声明:
本文根据公开信息整理,旨在介绍更多的存储知识,所载文章仅为作者观点,不构成投资或商用建议。本文仅用于学习交流, 不允许商用。若有疑问或有侵权行为请联系作者处理。