【单片机开发】UFS协议浅析
【单片机开发】UFS协议浅析一、UFS 协议技术
经过固态技术协会(Joint Electron Device Engineering Council,JEDEC)不断对 eMMC 协议的完善,eMMC 5.1 发布后因为无法继续提高其传输速度,JEDEC 于 2011 年发布了 UFS 1.0 协议,尽管 UFS 1.0 相比较同时期的 eMMC 并没有实质上的优势,但由于 UFS 协议基础优秀,随着时代逐步发展,UFS 2.1 相比较 eMMC 已经形成绝对压倒性优势,奠定了 UFS 协议未来成为存储技术主流的地位:UFS 之所以可以如此之快的原因在于:
[*]UFS 使用了差分串行传输;
[*]串行决定了可以使用更快的时钟(时钟信息可以嵌在数据流中);
[*]差分则大大增强其抗干扰能力强(eMMC 后续之所以速度上不去就是因为使用的是并行数据传输,抗干扰能力弱,无法保证在高速时钟时的信号完整性);
[*]UFS 支持多通道数据传输(目前最多支持两个通道),多通道可以让 UFS 在成本、功耗和性能之间做取舍;
[*]全双工(eMMC 是半双工);
要让 UFS 速度快,这些基础设施是必须的。但要充分利用底层高速数据传输通道,还需要上层数据传输协议配合:
[*]UFS 支持命令队列,主机一下可以发很多个命令下去;
[*]UFS 支持异步命令(并行乱序执行,谁先完成谁先返回状态,eMMC 的同步命令处理方式不支持);
UFS 协议更像是一个整合者,重新定义的东西不多,Application Layer 主要是将 SCSI 规范搬过来,下面的 M-PHY 和 UniPro 则直接挪用 MIPI 标准的部分,优点当然显而易见,处理不用担心以往优秀且成熟协议的稳定性外,也同时大大减少重新设计硬件的工作量。
M-PHY 和 UniPro 扩展:图摘自《mipi_M-PHY_specification》L1,M-PHY:专为移动设备开发的一种串行接口技术,时钟频率能够达到 5.8Gbps(高 performance),每个 Upstream Lane 或者 Downstream Lane 只需要两根差分信号线(pin 脚少,方便 PCB 布线),并且具有多种省电模式。M-PHY 是全双工且不要求上行 Lane 和下行 Lane 成对出现,下图就是两个下行 Lane 配一个上行 Lane 的例子。但是注意针对目前的 UFS 上行下行 Lane 还都是成对出现的;UniPro:也是针对 mobile 设备开发的,广泛用于移动设备 AP、协处理器和 modem 之前的通信协议,通常把这层看作是对硬件接口的抽象、管理和负责通信的的软件层来帮助理解;L1.5 PHY Adapter:物理适配层,用于检测双向 Lane 通路的个数,并提供软件支持。允许访问对端 L1.5 层的控制参数和状态,并可以通过原子操作改变对端 Power Mode。下图显示了 L1.5 层的数据是以 Symbol 为单位的,每个 symbol 有 17 个 bits,包含有两个 Byte 和一个 control bit (bit16)。Control bit 是 1 的时候,表明后面跟着的两个 bytes 是控制命令;如果是 0 ,说明后面的两个 bytes 是 data payload;L2 Data Link:数据链路层,主要保证数据通信过程中的可靠性。其中采用 ECC 保证接收数据的准确性,接收端也要留有足够的 buffer 来缓存接收到的数据。一旦接收失败,发送端必须重新发送一次。L 2层的数据单位是 Frame,在原有 L1 层的基础上,把独立的 symbol 打包。每个 Frame 最多可以打包 144 个 symbol,并在 Frame 的头尾处各添加上 Header(ESC_DL+SOF+TC+Reserved) 和 Trailer(ESC_DL+EOF_EVEN+Frame Seq. Number)之后,附上16bits ECC 来侦查纠错。
这层有个比较重要的概念是 TC(Traffic Class),UFS 支持两种优先级的 Data Frame TC0 和 TC1。TC1 的优先级高于 TC0,绝大多数的数据都是在 TC0 这个级别传递的,紧急的数据通过 TC1 来传递。TC1 可以中断、抢占正在发送的 TC0 的数据发送。L3 Network:网络层,负责数据 route 到正确的目标设备,比如下图的 AP#3 这个设备,它不仅能与设备 1、2、5 通信,那么通过 UniPro L3 也允许其与设备 4 和 6 进行通信。L3 的数据的单位是 package,在层 2 的 Frame 的基础上增加了 7bits 的 shorter-header,用来标识数据 route 的目标地址。
L4 Transport:传输层。由于基本通信服务已经在底层处理的差不多了,所以传输层是相对比较简单的一层,它提供对多 device 和多 client 的支持。L4 层的数据的单位是 segment,在 package 的基础上增加了 5bit 的“Cport” identifier,我们在这里可以把它看做是 UFS 的 sub-address。DME(Device Management Entity)与 UniPro 的每层都留有 SAP 接口(Service Access Point),通过 SAP DME 可以访问每个 layer 的控制和状态参数,管理他们的 power 模式,并且可以访问、控制对端设备的 UniPro 模块。
UniPro 的上面就是 UTP 和 SCSI 命令集,由于涉及的 SCSI 命令是很大一块需要单独来讲,所以这里只简单两笔。正如最开始提到的,UTP 和 SCSI 是属于 SCSI 这部分,在 JEDEC 的标准里能找到它们的具体说明。
UTP(UFS Transport Protocol):这层软件主要有两个目的,一是把 UniPro 的 segment 打包成 UFS 直接可以识别的命令格式;二是通过这层可以让 UFS 自己来掌握发送数据的节奏、控制自身的状态等,这样既可以免去 host 端持续的查询 UFS 的状态所带来的系统消耗,也是因为只有 UFS 本身最了解自己的内部状态,能够选择以最佳的方式在最佳时间把数据传递出去。
SCSI 扩展:图摘自《JESD223D》《JESD220E-3.1》
UFS Application Command Layer:这层是 UFS 命令集,分为 UFS 的独有内建命令集和 SCSI(Small Computer System Interface)的命令集。SCSI 命令分为 SBC 和 SPC,分别是 SCSI Block Commands 和 SCSI Primary Command。在 SCSI 架构中,主机上的 SCSI 接口卡称为 Initiator,与其相连接的 SCSI 磁盘等设备称为 Target,在逻辑上,Initiator 和 Target 之间通信的工作模式,与两个网络设备之间的模式相似,他们之间采用 client-server 的“请求-回应”模式:SCSI 的 Initiator 与 Target 共同构成了一个典型的 C/S 模型,每个指令都是“请求/应答”这样的模型来实现:
* Initiator主要任务:发出SCSI请求;
* Target主要任务:回答SCSI请求,通过 LU 提供业务,并通过任务管理器提供任务管理功能;
LU(Logical Unit):逻辑单元,是指一个可被操作系统识别和访问的逻辑存储单元。一个 UFS 设备可以包含多个 LU,每个 LU 可以被视为一个独立的存储设备;
LUs :LU 的复数形式;
LUN(Logical Unit Number):逻辑单元号码,是用来标识不同 LU 的唯一编号。每个 LU 都有一个对应的 LUN,它可以用来在系统中唯一地标识和访问该 LU;
备注:
I_T_L_Q Nexus:唯一地定义了连接到特定 Host Initiator Port (I) 的一个特定 Device Target Port (T) 上的一个特定 Logical Unit (L) 内的一个 command slot (Q)。
二、UFS 重要 Layer2.1 UFS Application Layer
UFS 应用层由基于 SCSI 体系结构模型 (SAM) 的 UFS SCSI 命令集组成:
[*]传输事务使用固定长度的CDB(command descriptor block,命令描述符块)进行;
[*]每个事务都遵循 I_T_L_Q 关系,这意味着 CDB 需要识别与目标中的特定 LUN 通信的发起方。
命令描述符块的长度可以是 6、10 或 16 个字节,一些重要的命令:
* READ / WRITE;
* READ CAPACITY:获取逻辑单元的大小;
* REPORT LUNS:获取所有逻辑单元的列表;
* TEST UNIT READY:检查逻辑单元是否已准备好接受请求;
* START STOP UNIT:开关设备的电源模式;
* INQUIRY:查询有关逻辑单元的更多信息;
2.2 Logical unitUFS 设备有若干个 LU,LU 接收主机发过来的命令或请求可能来自应用层的 SCSI 模块、设备管理器或者任务管理器每个 LU 都是独立的,“独立”表现在下面几个方面:
[*]逻辑地址空间是独立的,都是从LBA0(Logical Block Addressing,逻辑块寻址)开始;
[*]逻辑块大小可以不同,可以为4KB,..;
[*]可以有不同的安全属性,比如可以设置不同的写保护属性;
[*]每个 LU 可以有自己的命令队列;
[*]LU 可以启动代码、应用程序代码和应用数据;
总结来说,划分不同 LU 有以下作用:
[*]外部可寻址;
[*]存储实体(可以单独做 Boot 启动、写保护或 RPMB(Replay Protected Memory Block,重播保护内存块) );
[*]内部任务队列;
一个 UFS 设备最多可以有 32 个逻辑单元用来存储用户数据的,此外可能有 4 个知名逻辑单元 (Well Known LU):各个 LU 相对地址如下:
[*]REPORT LUN
[*]代表设备向主机汇报设备LU清单。主机想知道设备LU的支持情况,就需要发命令或者请求给该LU。UFS其中有个命令“Report LUNS” (和该LU名字一样)用来访问Report LUNS;
[*]UFS Device
[*]当 UFS 主机对整个UFS设备发命令的时候,UFS Device LU 就成为该命令接收的对象,比如格式化UFS设备(FORMAT UNIT命令)、切换UFS设备的功耗模式(START STOP UNIT命令)等;
[*]Boot
[*]用来存储启动代码的LU。不过 BOOT LU 本身是不存储启动代码的,它只是个虚拟的 LU,启动代码物理上是存储在普通LU上的。有两个 Boot LU,LU A 和 LU B,可以用来存储不同启动代码(比如一个新,一个旧),但在启动过程中,只有一个是活跃的(Active)的。32个普通LU中的任意一个可以配成Boot LU A或者Boot LU B;
在下面的例子中,LU 1 充当 Boot LU A,LU 4 充当 Boot LU B。由于有两份启动代码,分别保存在LU 1和LU 4。主机启动时,首先应该通过设备管理器,发送 Query 请求给设备,获取一个叫做“bBootLunEn ”的属性,该属性标识当前活跃(Active)的 Boot LU:如果 bBootLunEn = 01,说明 Boot LU A 是当前活跃的 Boot LU,因此主机会从 LU 1 上读取启动代码完成系统的启动。Boot LU 不是必须的。如果系统的启动代码不是存储在 UFS 设备上,那么 Boot LU就不需要,因此bBootLunEn = 0:
[*]RPMB
[*]UFS 设备会校验主机向 RPMB LU 写数据的合法性,只有特定的主机才能写入;同时,主机在读取数据时,也提供了校验机制,保证了主机读取到的数据是从该 LU 上读的数据,而不是攻击者伪造的数据;
四个 Well Known LU 能接收的命令如下图,绿色命令为他们能接收一些通用的命令,红色命令表示只有该 LU 能执行的命令,注意:一般 LU 的写是 cache 操作的,即主机数据到设备的内部 buffer,设备就会回命令完成状态给主机,但 Boot LU 和 RPMB LU 写操作不支持 cache,数据必须写到闪存中以后才算该命令完成。2.3 UFS Transport LayerUFS 传输层的事务由称为 UFS 协议信息单元 (UPIU) 的数据包组成,主机是启动器,设备是目标。有不同类型的 UPIU 用于处理 SCSI 命令、数据操作、任务管理操作、查询操作等。每笔交易包括:
[*]一个命令 UPIU;
[*]零个或多个数据输入或数据输出 UPIU;
[*]回应 UPIU;
[*]每个 UPIU 包含一个 12 字节的标头,后跟可选字段,具体取决于UPIU的类型;
在这一层中主机和设备的交互如下:
页:
[1]