为什么串行NAND Flash不支持XiP?

今天痞子衡给大家介绍的是串行NAND Flash的两大特性导致其在i.MXRT FlexSPI下无法XiP

在嵌入式世界里,当我们提起XiP设备(支持代码原地执行的存储器),首先想到的应该是NOR Flash。比如中低端MCU内部通常会集成小容量并行NOR Flash(一般2MB以内),用于存放应用程序;而高性能MCU,往往内部不会集成Flash,需要在板级设计时外挂一片稍大容量的NOR Flash(大部分是串行NOR,一般8MB以上)。

恩智浦i.MXRT系列属于高性能MCU,需要外挂Flash。i.MXRT本身可以支持串/并行NOR、串/并行NAND四类设备作为启动设备,但在官方参考设计板EVK上,推荐的都是串行NOR Flash型号。官方没有推荐并行NOR/NAND,这是可以理解的,毕竟相比串行接口Flash,引脚占用略多,这对I/O资源紧张的MCU项目来说不太讨喜。那官方为何不推荐串行NAND作为启动设备呢?这主要是串行NAND在i.MXRT下无法XiP,这对项目软件设计来说有一些限制。NAND无法XiP的原因有两点,既跟NAND自身特性有关,也跟FlexSPI外设特性有关,且听痞子衡细说:

一、FlexSPI对于NAND的支持

我们知道在i.MXRT中是FlexSPI外设负责实现串行NOR/NAND Flash设备的读写访问支持,详述了FlexSPI是如何通过lookupTable来支持串行NOR Flash设备XiP启动的(这里主要是读访问支持)。

在lookupTable设计里,其实AHB读访问并不是NOR Flash设备的专利,或者这么说,FlexSPI外设本身并不在乎连接得是什么类型的设备,它就是完全根据用户在lookupTable里填入的命令时序按部就班工作而已。

对于四线QSPI NOR,仅需要在lookupTable里填入一条命令时序(Read有很多种,但都能在一条Sequence里实现)就可以支持AHB读。而HyperFlash、HyperRAM和串行NAND等设备,lookupTable里一条命令时序搞不定完整读操作,需要多条命令时序组合完成。

FlexSPI外设支持在lookupTable中联合多条命令时序去实现AHB读,通过FlexSPI->FLSHxxCR2寄存器里的如下两处功能位来实现。ARDSEQID位指明读访问时序在lookupTable中的起始位置(index),ARDSEQNUM位指明读访问时序共占用几条命令时序(这也意味着几条命令时序要按序放在一起)。

比如Micron MT29FxG01串行NAND系列,就需要如下三条命令时序(Page Read + Get Feature + Random Data Read)组合完成读操作。但是理想很丰满,现实却骨感,即使组合这三条命令时序也无法在FlexSPI下实现NAND的XiP。

实际应用时,对于NAND的读访问,都是在程序代码中先通过IPCMD方式手动发送Page Read和Get Feature命令,然后借助lookupTable中的Random Data Read命令实现仅一个Page空间大小的AHB读,做不到全部NAND空间的自动AHB读(当然如果你觉得一个Page空间的AHB读太鸡肋,完全可以直接用IPCMD方式去读Page数据)。

Note: 关于NAND仅一个Page空间的AHB读支持再作下详细解释。比如NAND的Page大小为2KB,那么系统里仅需给NAND分配0x60000000 - 0x600007FF的AHB映射空间,每次对这个空间进行AHB读之前,都需要先通过IPCMD发送Page Read和Get Feature,确保NAND处于Page数据输出的Ready状态,底下FlexSPI就可以完成这个Page内的任意AHB读访问支持。而一旦切到新Page访问,需要重复上述过程,因此NAND所有Page的访问都可以在这个2KB的映射空间里完成的。

二、串行NAND阻碍XiP的两大特性

到底串行NAND的什么特性阻碍了XiP,下面痞子衡以Micron MT29FxG01型号串行NAND为例介绍其阻碍XiP的两大特性:

2.1 坏块导致的非线性存储

凡是NAND型Flash都绕不开坏块(Bad Block)问题,这也是NAND Flash区别于NOR Flash的一个重要特点。NAND技术上允许坏块的存在,这降低了NAND生产工艺要求,因此NAND单位容量价格比NOR低。

NAND内部按粒度从大到小划分依次为Plane、Block、Page、Byte(如下图所示),因为坏块导致了一些Block无法有效存储数据,这些Block会被标记拉黑,所以从主设备访问角度来看,NAND中的数据并不是按地址连续存储的,坏块占据的地址均为无效地址,这就是所谓的非线性存储,而非线性存储设备显然无法作为XiP设备。

非线性存储器,对于写入操作,无法保证应用程序一定放在指定链接的地址(即在Flash中的对应偏移地址),写入过程中遇到坏块,会跳过坏块,而那些坏块占据的无效地址极有可能就是应用程序实际链接地址。

2.2 ECC校验导致的Page Read等待

我们现在假设一种理想情况,NAND中不存在任何坏块,可以强行把NAND当作线性存储设备,这种情况下是不是就可以被用作XiP设备了呢?很遗憾,FlexSPI外设还是不能正面支持(有替代方法来支持)。

我们来看串行NAND的完整读时序,0x13(Page Read)是FlexSPI发送的第一个命令,用于通知NAND主设备想要访问Page了,随后发送列地址,指明要读的Page位置,此时NAND便会将内部状态寄存器里Busy位标志起来并进入忙状态。

在忙状态时间里,NAND会从内存块里将指定的Page数据全部拷贝到临时缓存区(Cache memory),对这一整个Page数据进行ECC校验,校验完成后将状态寄存器里相应ECC标志起来以及将Busy位清除掉,然后结束忙状态,进入数据输出准备状态。

由于不知道NAND什么时候会结束忙状态,因此FlexSPI需要不断发送0x0F(Get Feature命令)去读取状态寄存器的值,直到状态寄存器里Busy位被清零才能去读取Page数据,这种逻辑判断行为在lookupTable里无法自动实现(NOR读时序里无需逻辑判断)。

如果特意省略读状态寄存器的步骤,避免逻辑判断行为,在lookupTable直接填入Dummy周期来代替行不行呢?理论上倒是可以的。我们来算一下,比如NAND典型的50MHz时钟频率,一个Dummy Cycle周期耗时20ns,NAND Page Read等待典型值是45us,即2250个Dummy Cycle,lookupTable有16条Sequence,每个Seqence支持8个instruction,每个instruction如果都设为DUMMY_SDR,参数设最大255,则9个instruction就能满足这个等待时间。

但即使这么做能勉强实现NAND Flash的XiP,代码实际执行效率也是非常低下的,毕竟涉及到跨Page的指令长跳转(暂不讨论Cache因素)就需要等待45us,这在嵌入式世界里是不短的时间,系统实时性无法保证,又有什么意义呢?

至此,串行NAND Flash的两大特性导致其在i.MXRT FlexSPI下无法XiP痞子衡便介绍完毕了,掌声在哪里~~~

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 1
收藏 2
关注 41
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧