FLASH使用参考

1. 驱动配置

1.1. Hardware Capabilities

当前SigmaStar的Flash相关外设支持硬件相关的属性如表1-1:

表1-1:Flash外设支持属性

功能 描述
RIU mode 通过cpu操作寄存器操作flash
DMA mode 通过dma操作flash过程无需cpu干预
Clock Speed 支持的频率有54MHz 86MHz 104MHz 108MHz
Single mode 标准SPI通讯模式
Dual mode 在标准SPI模式的基础上MISO也作为数据传输线使用
Quad mode 在Dual mode基础上WP HLD也作为数据传输线使用

支持的Flash功能如表1-2:

表1-2:Flash支持功能

功能 描述
Read Data 标准读取(03h)
Fast Read 快速读取(0Bh)
Fast Read Dual Output 快速双线读取(单线发送命令地址 3Bh)
Fast Read Dual I/O 快速双线读取(双线发送命令地址 BBh)
Fast Read Quad Output 快速四线读取(单线发送命令地址 6Bh)
Fast Read Quad I/O 快速四线读取(四线发送命令地址 EBh)
Page Program 页写入(02h)
Quad Input Page Program 四线写入(32h)

注:表格中列举的为常用命令,不同的厂商的flash可能存在差异,命令仅供参考

1.2. 设备树配置

SPINOR驱动的设备树配置如下:

1. flashisp {
2.         compatible = "mtd-flashisp";
3.         status = "ok";
4. };

SPINAND驱动的设备树配置如下:

1. spinandflash {
2.         compatible = "ms-spinand";
3.         status = "ok";
4. };

Flash相关的设定都会从SNI文件中解析,所以设备树文件中的节点仅用于匹配驱动及控制驱动的开启与否。

1.3. 内核配置

不同的启动方式都有对应的配置文件,请使用相对应的配置文件,无需修改。

2. 系统方案

2.1. 分区划分

SPINOR的启动镜像一般包含:CIS、IPL、IPL_CUST和Uboot,以上四个镜像将会被打包为一个完整的二进制文件,一般为boot.bin。

CIS中包含SNI、PNI和Support List。PNI为分区的信息,包括分区的起始地址,分区的大小等信息,IPL、IPL_CUST等软件使用该文件获取分区信息,该文件中的分区信息与mtdparts的信息通过project打包文件保持一致,如果手动修改,可能会无法开机。Support List为当前支持的所有Flash的信息,信息包括操作的命令,时钟的频率,使用单线模式还是四线模式等等信息。系统上电后,软件通过读取Flash的ID匹配到对应的Flash信息,再将匹配到的信息更新到SNI,SNI储存的即当前Flash的信息。

具体分布如图2-1所示:

图2-1:SPINOR分区划分

SPINAND的镜像基本组成单元和SPINOR类似,不同的是由于SPINAND Flash存在坏块的物理特性,导致SPINAND需要有备份分区,且每个分区尾部需要预留备份块用于坏块处理。如图2-2所示:

图2-2:SPINAND分区划分

上述的分区设置需要保证存储CIS与IPL的两个BLOCK为好块,为了优化这个问题Maruko中新增了将IPL与CIS合并,并写至BLOCK 0/2/4/6/8中进行启动,仅需保证包含CIS和IPL的BLOCK存在一个好块即可正常启动,其余特性保持不变。Alkaid的Maruko config中已有对应实现config。其分区示意图如下:

2.2. SPINAND分区调整

由于SPINAND Flash存在坏块的物理特性,当检测到坏块时,需要往后顺移一个块,然后重新调整PNI中的分区信息。当分区可用的备用块不够时,再切换到另外的分区运行。

烧录完成后的第一次开机会重写PNI,并根据BOOT分区是否存在坏块而调整IPL IPL_CUST UBOOT分区的起始位置。

2.3. BBT AND BBM

BBT(Bad Block Table - 坏块表)

坏块表用于记录Flash每个块是否为坏块的状态,系统上电后,IPL会检测block 1、3、5、7、9上是否存在坏块表,如果不存在坏块表,则会扫描整颗Flash确定每个块的坏块状态,并生成坏块表。

BBM:(Bad Block Manage - 坏块管理)

在启动过程中,读取分区数据时,如果发现数据存在被纠正,且纠正的位数超过了设定的阈值,则会将数据进行重写(若无BBM分区则默认不触发)。如图2-5所示:

图2-5:坏块管理

如图2-5所示,在读取的过程中检测到 block n+2 中的某个页已经发生了位翻转,且位翻转的位数大于设定的阈值且小于可纠正的位数(大于可纠正的位数时的数据是不可靠的),则会将存在位翻转的块的数据搬移到备份块中,再将备份分区的数据重新写回发生位翻转的块中,可大大降低位翻转的位数超过可纠正位数的最大值。

3. SNI LIST support

3.1. SNI编辑工具的使用

打开SNI:(需1.0.4版本及其以上)

新增Flash:

删除Flash:

3.2. Nand Flash Sni List Support

3.2.1. 基本属性

Flash的基本属性设定界面如图3-4所示:

图3-4:Flash的基本属性设定界面

图中的参数及对应的描述如下表所示:

参数 描述
ID Bytes Count FLASH ID 对应的字节数
ID Byte FLASH ID 用于识别Flash(ps:read ID command:0x9F)
Spare Size oob区域的长度
Page Size 页长度,单次写入的最大字节数
Page Count 一个block包含几个page
Block Count 一颗Flash包含几个block
Sector Size Flash ECC用来计算ecc校验码的单位长度
Plane Count 部分Flash存在多plane设计,读写时序与单plane的会略有差异,不填写时默认为0
RIU Read 用于选择是DMA数据传输还是RIU数据传输,DMA数据传输更快,0:DMA 1:RIU
Max Freq 选择时钟频率,调试时建议54M,实际应用请根据flash规格书来确认

3.2.2. 特殊设定

Flash的特殊属性设定界面如图3-5所示:

图3-5:Flash的特殊属性设定界面

图中的参数及对应的描述如下表所示:

参数 描述
BIT6 MULTI_DIES,根据Flash规格书填写
BIT5 NEED_QE,Flash在进行quad read,quad write时,需要设置QE bit
BIT4 ECC_RESERVER(预留)
BIT3 ECC_RESERVED_NONE_CORRECTED,当ECC_S1 | ECC_S0为2b’11时,如果表示不可纠正,则勾选
BIT2 EXT_ECC,未使用
BIT1 ALL_LOCK,原本表示会在初始化阶段将Flash unlock,目前无论是否勾选都会执行unlock,无效bit
BIT0 OTP_AVAIL,未使用
MaxWaitTime Flash完成某个动作的最大等待时长,单位us,建议10*(Block erase time)

3.2.3. 寄存器设置

Flash的寄存器设置界面如图3-6所示:

图3-6:Flash的寄存器设置界面

图中的参数及对应的描述如下表所示:

参数 描述
EccEnabled Parameters ECC enable,使能后ecc功能开启,用于数据校验及修复
OtpLock Parameters 锁定Otp区域,锁定后,OTP区域只读
OtpEnabled Parameters OTP enable,使能后,可访问flash otp区域数据
DieCode Parameters Die Code,切换die,(多die结构的flash才需要填写)
Complement Parameters 写保护相关,用于写保护区域的补余
TopBottom Parameters 写保护相关,用于选择写保护开始地址:upper还是lower
Blocks Parameters 写保护相关,用于选定写保护区域
SRP0 Parameters 寄存器保护(未使用)
SRP1 Parameters 寄存器保护(未使用)
QeStatus Parameters QE bit相关信息,使能QE,用于quad read、quad write

3.2.4. 数据操作设定

Flash的数据访问相关设置界面如图3-7所示:

图3-7:Flash的数据访问相关设置界面

图中的参数及对应的描述如下表所示:

参数 描述
Read Parameters 读数据命令配置,用于修改single read、dual read、quad read
Program Parameters 写数据命令配置,用于修改single write、quad write
Random Parameters 写数据命令配置,(与Program相比,Random不会将cache的值重置)
CrMode Parameters Cr mode命令配置,内容较多,不在此处展开,详见:Cr mode配置

所有的Parameter的组成都是一样的,如图3-8所示:

图3-8:Parameter组成字段

Parameter各字段的含义如下表所示:

参数 描述
Command 操作的命令(图中的0x6b即为读操作的命令)
Address 操作的地址,如读写不需要设置地址,读写寄存器命令需要设置地址
Address Bytes 地址长度
Dummy Dummy Cycle数,时序上要求设置的dummy Cycle数
Data bytes 寄存器数据长度,读写寄存器时,需要读出或写入的数据长度
Value 寄存器数据内容,通常要填写对应功能位在寄存器的位置Mask

因为所有的命令数据结构都是共用的,所以有些字段并不是该命令必须的。如读写的命令,只需要设置命令和dummy count,其他的不需要设置。而读写寄存器的命令则需要设置命令、命令地址、命令地址长度、数据掩码(mask),具体可以参考Flash数据手册灵活调整。接下来已一个实例来具体讲解如何新增一个Flash的支持。

3.3. 常规配置示例

接下来以XT26G02E为例,讲解如何从数据手册中查找参数并录入到SNI中。

3.3.1. 添加型号

点击“add”按钮,输入Flash型号,点击“OK”新增空白的配置,操作步骤如图3-9所示:

图3-9:添加型号

3.3.2. 添加基本参数

如图3-10所示,XT26G02E的ID为两字节0x2C 0x24两个字节:

图3-10:XT26G02E的ID字节

在ID Byte Count栏位中填入2,ID Bytes栏位中填入 0x2C 0x24,如图3-11所示:

图3-11:XT26G02E ID Byte填写

如图3-12和图3-13所示,XT26G02E的页大小(Page Size)为2048字节,每一个块(Block)包含64个页(Page),每一页除2048字节有效数据外,还包含128字节空数据区域(Spare Size)。Plane数目为2,总的块数量为2048个。

图3-12:Error Management Details

图3-13:Array Organization

对应修改SNI如图3-14:

图3-14:SNI修改

图3-14中,RIU Read为是否使用RIU模式,设置为零为RIU模式,设置为一为DMA模式,Max Freq为Flash时钟运行频率,根据需求设置。

其他配置暂时未使用,请保持默认。

3.3.3. 添加特殊设定

双击图3-15蓝色区域会弹出图3-16的配置界面:

图3-15:双击蓝色区域

图3-16:弹出配置界面

如图3-16中,7.volatile用于表示状态寄存器(status register)中QE(Quad Enable)位是否为非易失性(non-valatile),如果勾上则为易失性(volatile)的,易失性的状态寄存器QE位的值在系统重新上下电后,数据会丢失,需要重新设置。非易失性的状态寄存器QE位的值在系统重新上下电后还会保留原先设置的值,但非易失性的寄存性有寿命限制,如果频繁写非易失性的状态寄存器会造成状态寄存器失效。

如图3-17中,该型号的Flash不需要设置QE位,所以该位置不需要勾选。

图3-17:Feature Settings

6.MULTI_DIES 代表该型号的Flash是否为多DIE的设计,通过数据手册的描述,未找到关于多DIE的描述,所以该位置不勾选。

5.NEED_QE 代表该型号的Flash在使能四线模式时,是否需要设置QE位,如图3-17中的信息可以知道该型号的Flash不需要设置QE位。

4.ECC_RESERVED_ CORRECTED 表示如果ECC状态寄存器11表示ECC Corrected则需要勾选。

3.ECC_RESERVED_NONE_CORRECTED 表示如果ECC状态寄存器11表示ECC Corrected则需要勾选。

图3-18:ECC Status Register Bit Descriptions

2.EXT_ECC 保留字段。

1.ALL_LOCK 表示芯片默认是否为锁定状态,如果勾选的话,驱动会自动解锁,建议默认勾选。

0.OTP_AVAIL 保留字段。

图3-19:maxWaitTime

图3-19中maxWaitTime表示读写擦最大的等待超时时间,如果在最大的超时时间内没检查到成功的标志,则会退出当前的操作。一般取最大超时时间的10倍,如果查询到成功后会马上返回,所以加大超时时间在正常使用的情况下不会增加启动时间。如图3-20中,最大的超时时间为10ms,工具的时间单位为us,则设置为100000。

图3-20:PROGRAM/READ/ERASE Characteristics

3.3.4. 添加寄存器操作

通过图3-21可以知道该型号的Flash获取状态寄存器的命令为0x0F,因为当前所用的众多Flash的读寄存器的命令都是一样的,所以命令栏可以不填,也可以填。

图3-21:GET FEATURES(0Fh) Timing

寄存器的对应地址及各位代表的意思如图3-22所示:

图3-22:Feature Address Settings and Data Bits

如图3-22可以知道ECC Enable位在地址为0xB0的寄存器的Bit 4,则address填0xB0地址的长度如图3-21为1字节,则addressBytes填0x01,无dummy时钟,则dummy栏位填0x00,寄存器的数据长度为1字节,则dataBytes栏位填0x01,Bit4对应的掩码(Mask)为0x10,则value栏位填0x10。如图3-23所示:

图3-23:参数填写1

图3-24:参数填写2

图3-25:参数填写3

其他参数以此类推。

3.3.5. 添加数据操作

单线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x03(command) + 2byte address(addressBytes) + 8 Dummy Cycles(dummy) + data

  • 读时序为:0x0B + 2byte address + 8 Dummy Cycles + data

四线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x3B + 2byte address + 8 Dummy Cycles + data

  • 读时序为:0xBB + 2byte address + 4 Dummy Cycles + data

四线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x6B + 2byte address + 8 Dummy Cycles + data

  • 读时序为:0xEB + 2byte address + 4 Dummy Cycles + data

单线写入:

由flash规格书所示,可以得到以下信息:

  • PROGRAM写时序为:0x02 + 2byte address + data

  • RANDOM写时序为:0x84 + 2byte address + data

单线写入:

由flash规格书所示,可以得到以下信息:

  • PROGRAM写时序为:0x32 + 2byte address + data

  • RANDOM写时序为:0x34 + 2byte address + data

3.4. Continuous Read示例

Continuous Read目前主要支持的两种类型:without BUFF mode和BUFF mode。

  • Without BUFF mode

    Note:flow已经在driver中实现,只需在Sni中配置BUF bit,及read cache command

    以W25N01GVxxIG为例:

    四线读取:

    由flash规格书所示,可以得到以下信息:

    • BUF bit(address :0xB0 Mask:0x08)

    • RANDOM写时序为:0xEB + 2byte address + 8 Dummy Cycles + data

    Note:

    因driver仍采用command + address + dummy+ data的方式(此处address以2byte计算)

  • BUFF mode

    参数 描述
    NextPage Parameters 读取下一个page使用的command
    LastPage Parameters 读取最后一个page使用的command
    CheckBusy Parameters 读取下一个page或读取最后一个page时需要check busy时填写
    参数 位域 描述
    BLOCK_WITH_LAST BIT4 Continuous read不能超过一个block时,则勾选
    END_WITH_REST BIT3 结束continuous read时,需要执行reset时,则勾选
    BUSY_AFTER_NEXT BIT2 读取下一个page需要check busy时则勾选且CheckBusy Parameters要填
    BUSY_AFTER_READ BIT1 读取最后一个page需要check busy时则勾选且CheckBusy Parameters要填
    NEXT_STATUS BIT0 读取下一个page需要check busy时则勾选(此处check的是OIP)

    以GD5F1GQ4UEYIH为例:

    由flash规格书所示,可以得到以下信息:

    • Next Page command:0x31

    • Last Page command:0x3F

    • 读取下一个page时需要:check OIP

    • Continuous read不能超过一个block

3.5. Nor Flash Sni List Support

3.5.1. 基本属性

参数 描述
FLASH ID 作用于识别flash(如read ID command:0x9F)
Max Clk 选择CLK speed,调试时建议54M,实际应用请根据flash规格书来确认
Page Byte Count 页长度,单次写入的最大字节数
Sector Byte Count Sector erase的字节数
Block Byte Count Block erase的字节数(如command:0xD8)
Capacity Flash 总大小
Max Wait Time flash完成某个动作的最大等待时长,单位us,建议10*(Block erase time)
Options Bit0 用于选择DMA数据传输或RIU数据传输( 0:DMA 1:RIU)

3.5.2. 高级属性

软件的高级属性设置界面如图3-38所示:

图3-38:软件的高级属性设置界面

读取相关的属性的含义如下表所示:

参数 描述
Complement paramers 用于写保护的模式选择
TopBottom paramers 用于写保护选择顶端模式还是底端模式
Blocks paramers 写保护的参数,具体参考数据手册写保护章节
SRP0 paramers 寄存器保护(预留)
SRP1 paramers 寄存器保护(预留)
rQuadEnable paramers 使能四线模式

写入相关的属性的含义如下表所示:

参数 描述
Complement paramers 用于写保护的模式选择
TopBottom paramers 用于写保护选择顶端模式还是底端模式
Blocks paramers 写保护的参数,具体参考数据手册写保护章节
SRP0 paramers 寄存器保护(预留)
SRP1 paramers 寄存器保护(预留)
rQuadEnable paramers 使能四线模式

注意: 有填写rQuadEnable or wQuadEnable需将needQE设置为0x01

参数 描述
ReadData paramers 读数据相关的设置
Program paramers 写数据相关的设置

所有的Parameter的组成都是一样的,如图3-39所示:

图3-39:Parameter的组成字段

Parameter各字段的含义如下表所示:

参数 描述
Command 操作的命令(图中的0x6b即为读操作的命令)
Address 操作的地址,如读写不需要设置地址,读写寄存器命令需要设置地址
Address Bytes 地址长度
Dummy Dummy Cycle数,时序上要求设置的dummy Cycle数
Data bytes 寄存器数据长度,读写寄存器时,需要读出或写入的数据长度
Value 寄存器数据内容,通常要填写对应功能位在寄存器的位置Mask

因为所有的命令数据结构都是共用的,所以有些字段并不是该命令必须的。如读写的命令,只需要设置命令和dummy count,其他的不需要设置。而读写寄存器的命令则需要设置命令、命令地址、命令地址长度、数据掩码(mask),具体可以参考Flash数据手册灵活调整。接下来已一个实例来具体讲解如何新增一个Flash的支持。

3.6. 示例

接下来以XT26G02E为例,讲解如何从数据手册中查找参数并录入到SNI中。

3.6.1. 添加型号

点击“add”按钮,输入Flash型号,点击“OK”新增空白的配置,操作步骤如图3-50所示:

图3-50:添加型号

3.6.2. 添加基本参数

如图3-51所示,XT25F128B的ID为两字节0x0B 0x40 0x18三个字节:

图3-51:XT25F128B的ID字节

如图3-52所示,可以看到Flash的基本大小信息:

图3-52:Flash信息

如图3-53所示,可以获取到最大的超时时间为1.5秒:

图3-53:超时时间

综上可以得出的数据,修改参数设置如图3-54:

图3-54:修改参数

3.6.3. 添加寄存器操作

图3-55:Read Status Register Sequence Diagram

图3-56:Write Status Register Sequence Diagram

图3-57:STATUS REGISTER

与SPINAND Flash相似,通过图3-55、图3-56、图3-57可以得到以下信息:

  • 读S7-0使用command:0x05

  • 读S15-8使用command:0x35

  • 写S15-0使用command:0x01

  • CMP:bit14

  • Block lock:bit6-2

  • SRP1:bit8

  • SRP0:bit7

  • QE:bit9

修改设定如下:

由于SPINOR Flash读取寄存器命令只会返回一个字节,写入时同时写入两个字节,所以在读取时需要知道写入时的两个字节的读取命令是什么,可以通过双击address栏位弹出的对话框配置,如图3-60:

图3-60: 寄存器读取命令配置

3.6.4. 添加数据操作

单线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x0B + 3byte address + 8 Dummy Cycles + data

双线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x3B + 3byte address + 8 Dummy Cycles + data

  • 读时序为:0xBB + 3byte address + 4 Dummy Cycles + data

四线模式:

由flash规格书所示,可以得到以下信息:

  • 读时序为:0x6B + 3byte address + 8 Dummy Cycles + data

单线写入:

由flash规格书所示,可以得到以下信息:

  • PROGRAM写时序为:0x02 + 3byte address + data

四线写入:

由flash规格书所示,可以得到以下信息:

  • PROGRAM写时序为:0x32 + 3byte address + data

4. MTD UTILS

4.1. 源码

源码:http://git.infradead.org/mtd-utils.git

4.2. 常用命令

SPINAND:

命令 描述
nanddump 读取Flash中的数据
nandwrite 向Flash写入数据
flash_erase 擦除Flash指定区域
Flash_otp_info 获取OTP分布信息
Flash_otp_dump 读取OTP区域的数据
Flash_otp_write 向OTP区域写入数据
Flash_otp_lock 锁定OTP区域

SPINOR:

命令 描述
Mtd_debug 读取/写入/擦除Flash中的数据
flash_erase 擦除Flash指定区域
Flash_otp_info 获取OTP分布信息
Flash_otp_dump 读取OTP区域的数据
Flash_otp_write 向OTP区域写入数据
Flash_otp_lock 锁定OTP区域

注意:

  • 命令使用具体请参考help命令

  • user demo可以参考这些命令的源码

  • Flash写日前务必先进行擦除动作