浅析NAND FLASH的命令调度机制

NAND FLASH是一种常见的外部存储设备,它具有非易失性、存储密度高等特性。相对于NOR FLASH而言,其容量大,价格低廉,读写速度都比较快,因而得到广泛应用。随着近年来SSD设备的兴起,NAND FLASH的容量变得越来越大,性能也越来越高。针对NAND FLASH的读写时间差异,成块写入和有限次数擦除等特性,人们提出了各种算法,包括坏块管理、块映射、磨损均衡等,以此来进一步提高NAND FLASH的性能及寿命。

与此同时,存储设备的带宽也一直是计算机系统的瓶颈之一,所以对NAND FLASH的带宽提升也成为最近人们研究的热点之一。从NAND FLASHIO接口来说,接口本身的带宽已经可以达到400-600MB/s的速度。为了增大存储设备的容量,并充分利用NAND FLASH总线接口的带宽,一个NAND FLASH通道可能连接多个NAND FLASH die(或者称为LUN)

host过来的访问命令可能访问该通道上的任何一个die,而且新的存储协议都支持乱序执行,即从host过来的命令,我们可以以任意顺序执行并返回结果。因此,为了尽可能提高总带宽,在一个NAND FLASH通道对访问命令的调度会极大的影响带宽性能。

NAND FLASH主要有3种命令:1.擦除。它没有数据传输,完成一次擦除操作需要时间较长,大概在1-10毫秒这个量级;它的操作如下所示:

1)发送页写入命令0x60

2)发送页地址;

3)发送要写入的数据;

4)发送写入确定命令0xD0

5)检测忙信号;

2.编程。它至少有一页的数据传输(现在一页一般为16KB多),完成一次编程的操

作比擦除快大约在百微秒这个量级;

它的操作如下所示:

1)发送页写入命令0x80

2)发送页地址;

3)发送要写入的数据;

4)发送写入确定命令0x10

5)检测忙信号;

3. 页读。它有数据传输,数据传输量由host决定,有可能从512B16KB不等。完成一次读操作在几十微秒这个量级。

1)发送页读取命令0x00

2)发送页地址;

3)发送页读取确认命令0x30

4)检测忙信号

同一通道的一次可以接收多条请求,我们对这些请求的调度应该使NAND FLASH的前后请求尽可能扩大交叠时间,以提高存储系统的吞吐量。每个请求的处理时间根据其类型分为三类:

A: 无需数据传输,擦除操作和读状态操作.对于这类操作,我们应该使它们具有最高的优先级,以使同一通道内的多个DIE同时active起来。

B: 编程操作,执行前需要通过NAND FLASH总线将数据写入,需要占用大量的总线带宽.

C: 读数据操作.需要占用中等的总线带宽。

我们上面提到,对于A类操作,它们应该有最高的优先级。而对于B类操作和C类操作,我们可以通过自定义的方式调整他们的优先级(比如使用带权重的调度方案),不过根据我们自己的经验,令C类操作优先级高一些,会对整体性能的提高有帮助。

另外,对于读命令来说,它分为两个部分,

一个是命令阶段,只是给NAND FLASH die发送命令,通知它开始从FLASH阵列里读取数据到页缓存中,它只有简单几个命令和地址,并不传输数据,所以这个阶段属于A类操作,而不是C类操作。它跟擦除操作和读状态操作一样,都是高优先级的,尽快将这个命令发给NAND FLASH可以尽可能大地扩大交叠时间。

第二个是数据阶段,当NAND FLASH die结束读取以后,返回readystatus,这时host从页缓存中将数据读取出来,这涉及到数据传输,占用NAND FLASH总线,这个操作属于C类操作。

以上的调度策略可以初步解决多种命令类型占用NAND总线资源的调度问题。但与此同时,NAND FLASH die也是一个调度资源,多个命令可能访问同一个FLASH die,而NAND FLASH die在某一时刻只能服务一个命令。为此,我们需要为每个NAND FLASH die建立自己的一个状态机,它要追踪这个die的工作状态:这个die处于什么阶段?处于繁忙还是空闲?它执行的是哪类操作?它是否需要进行读状态操作?读状态操作返回的状态要如何进行解析?

因为每个NAND FLASH die只能服务一个操作,因此可以为每个die建立一个操作队列。当这个die处于空闲状态时,从操作队列中取出一个操作,申请占用NAND总线资源。在某一时刻,可能有多个dieNAND总线资源,此时按照上述的调度策略根据命令类型来决定谁来占用NAND总线资源。当这个die处于繁忙状态时,则状态机处于等待状态,并不申请NAND总线资源。

另外,这个状态机还可以负责发起读状态操作。对于普通的读写擦操作,都是由Host发起的命令,但读状态操作需要由NAND FLASH控制器自己发起。因为每个命令执行的时间并不是绝对的,我们可能需要多次读状态,才会返回ready的状态。也就是说,读状态操作要根据NAND FLASH die反馈回来的状态来发起。这正适合由这个状态机来决定。从操作队列中取得一个读写擦命令,并将其发送给NAND FLASH die以后,等一段时间以后,这个状态机可以发起一个读状态操作,并申请占用NAND FLASH总线,等NAND FLASH返回状态以后,这个状态机负责判断NAND FLASH是否空闲。如果空闲,则从操作队列中取下一个读写擦命令。如果繁忙,则再等一段时间后,再发起读状态操作,直到NAND FLASH返回空闲状态。

综上所述,对于NAND FLASH命令的调度,可以通过下图的结构来表示:

图中有2种调度机制:

1. 四个FLASH die共享同一个总线,我们根据命令类型来进行调度。占用总线时间少的拥有更高优先级,这有利于扩大交叠时间。

2. 多个命令访问同一个NAND FLASH die。此时控制器针对每个die维护一个命令队列,同时针对这个die建立一个状态机用以维护这个die的状态,并发起读状态操作,以实现跟NAND FLASH的状态互动

猜你喜欢

转载自blog.csdn.net/weixin_38233274/article/details/80907128