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写日前务必先进行擦除动作