现在的位置: 首页 > 综合 > 正文

如何调试nand flash

2018年05月08日 ⁄ 综合 ⁄ 共 6048字 ⁄ 字号 评论关闭
一.简介
本文介绍了如何调试nand flash
二. 背景
   2.1.nandflash 结构分类
   2.1.1 小页
      1block = 32page

1page = 512bytes(datafield) + 16bytes(Spare Field)
需要注意的是,对于flash的读写都是以一个page开始的,但是在读写之前必须进行flash的擦写,而擦写则是以一个block为单位的。同时必须提醒的是,512bytes理论上被分为1st half 和2sd half,每个half各占256个字节。
528个字节按顺序由上而下以列为单位进行排列(1列代表一个Byte。第0行为第0 Byte ,第1行为第1 Byte,以此类推,每个行又由8个位组成,每个位表示1个Byte里面的1bit。
528Bytes按功能分为两大部分,分别是Data Field和Spare Field,其中Spare Field占528Bytes里的16Bytes,这16Bytes是用于在读写操作的时候存放校验码用的,一般不用做普通数据的存储区,除去这 16Bytes,剩下的512Bytes便是我们用于存放数据用的Data Field,所以一个Page上虽然有528个Bytes,但我们只按512Bytes进行容量的计算。

读命令有两个,分别是 Read1,Read2其中Read1用于读取Data Field的数据,而Read2则是用于读取Spare Field的数据。对于Nand Flash来说,读操作的最小操作单位为Page,也就是说当我们给定了读取的起始位置后,读操作将从该位置开始,连续读取到本Page的最后一个 Byte为止(可以包括Spare Field)

2.1.2 大页
参考小页的说明

2.2   NANDFLASH校验
由于NAND Flash的工艺不能保证NAND的Memory Array在其生命周期中保持性能的可靠,因此,在NAND的生产中及使用过程中会产生坏块。为了检测数据的可靠性,在应用NAND Flash的系统中一般都会采用一定的坏区管理策略,而管理坏区的前提是能比较可靠的进行坏区检测。

??如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。

??在NAND Flash处理中,一般使用一种比较专用的校验——ECC。ECC能纠正单比特错误和检测双比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。
ECC一般每256字节原始数据生成3字节ECC校验数据,这三字节共24比特分成两部分:6比特的列校验和16比特的行校验,多余的两个比特置1
当往NAND Flash的page中写入数据的时候,每256字节我们生成一个ECC校验和,称之为原ECC校验和,保存到PAGE的OOB(out-of-band)数据区中。

当从NAND Flash中读取数据的时候,每256字节我们生成一个ECC校验和,称之为新ECC校验和。

校验的时候,根据上述ECC生成原理不难推断:将从OOB区中读出的原ECC校验和新ECC校验和按位异或,若结果为0,则表示不存在错(或是出现了ECC无法检测的错误);若3个字节异或结果中存在11个比特位为1,表示存在一个比特错误,且可纠正;若3个字节异或结果中只存在1个比特位为1,表示OOB区出错;其他情况均表示出现了无法纠正的错误
 
 
 
2.3   NANDFLASH 坏块管理
在进行数据存储的时候,我们需要保证数据的完整性,而NAND Flash存储器芯片由于工艺上问题,不可避免就会出现有的Block中就是某个位或某些位是块的,就是用块擦除命令也是无法擦除的。如果数据存储到这个坏块中,就无法保证该数据存储的完整性。对于坏块的管理首先我们要定义一个坏块管理表:unsigned char BAD_BLOCK_TABLE [128],此数组可以存储1024个Block状态,即每一个字节存储8个Block状态。我们要存储一批数据到NAND Flash中去某个Block时,先执行Block擦除操作,然后分析该Block的1st
Page和2st Page中的每个位是否全是FFH,如果全是FFH,则在BadBlockTable数组当前Block对应的字节位给置0,否则置1。如果是1表示当前的块是不能存储数据的,这时需要更换下一个Block来存储这些数据,这样我们重复上面的动作分析再进行分析是否可以存储数据,该块能存储就存储到该块中去。(详见具体NANDFLASH 手册)

2.4  DMA 传送方式
NAND 控制器包含一个宽度为32 b,深度为4 的缓冲FIFO,用于解决高速总线与低速设备
之间数据传输速度的匹配问题。为提高总线的传输效率,以及控制器设计的便利性,NAND
FLASH 在总线上的数据传输采用DMA 的方式来完成。譬如在读取FLASH 一页数据时,数
据持续写入控制器FIFO,FIFO 满时发出DMA 传输的请求,同时暂停FLASH 的数据读取,
控制信号nRE 拉高,直至DMA 响应请求即FIFO 不满时,FLASH 的数据传输重新开始。
当选择应用的FLASH 位宽为8,页大小为(512+16)B 时,控制器需要发出(32+1)次4 拍字宽
度的DMA 传输请求来完成数据和校验信息的读取。
控制模块的上作主要是将总线接口转换的控制信号,按照NAND FLASH 的接口协议.将片
选、地址、命令、读写使能按照所配置的时序要求,发送到NAND FLASH 中,并且控制数
据的传输个数,以及DMA 请求、数据传输完成中断、数据错误中断等系统信号。
2.5  NANDFLASH 启动
     NANDFLASH 跟NOR FLASH有一个本质的区别就是NANDFLASH不能执行代码,
而在SDRAM中执行程序,所以在系统的启动过程中有步代码从NANDFLASH中搬迁到SDRAM中的过程。随后会在7120的实例中阐明。
 
 调试T3G 7210 NANDFLASH
 
2.1       系统启动
2.1.1            系统启动流程图
     第一步:

说明:硬件的BOOTLOADER执行,执行的目的是把NANDFLASH第一个BLOCK中第一个 16kbytes 内容加载到SCRAM中去执行 相关模块psboot
第二步:

说明:NAND Bootloader 加载到SCRAM中后执行,执行的目的根据分区表把相应分区的内容加载到SCRAM中执行  相关模块psboot
第三步

说明:执行Splashscreen  就是开机动画,由于我们是模块没有屏幕这个模块并没有什么用,
可以把代码屏蔽掉。
第四步:

说明:执行完开机动画后,加载CODE区,开始执行代码。
  相关文件说明:
   修改启动这块代码我们只要关注psboot  psstartup,具体修改文件如下:
   psboot\modules\bootnand\srce\Rest.s  
IF NAND_FLASH_512M_HDW
         ; 32-word ROM Boot loader parameter list
         dcd   0x1234567          ; magic number causes NandFlash boot; 512M flash,
 ELSE
         dcd   0x1234576          ; magic number causes NandFlash boot
 ENDIF
  psboot\modules\bootnand\srce\ link.map
  在实际的调试的过程中,发现在编译bootnand这个模块的时候ZI区会超RAM(请注意UNINIT 这个关键的属性值),为了解决这个问题,需要去掉link.map中相应的几个字段。
#       BUFFER1 0x8000 UNINIT  0x8000
#       {
#                bootnand.o (buffer1)
#       }
#       BUFFER2 0x10000 UNINIT  0x8000
#       {
#                bootnand.o (buffer2)
#       }
psboot\modules\bootnand\output\Makefile
  BLOCK_SIZE                  = 16384
psstartup\modules\conf\incl\ config_bootnand.h
#define NANDFLASH_PAGE_SIZE             512
#define NANDFLASH_SPARE_SIZE            16
#define NANDFLASH_PAGES_PER_BLOCK       32
#define NANDFLASH_N_BLOCKS              4096
上面是设置 NANDFLASH的页与块,这也是大页换小页第一个需要改的。
#define NANDFLASH_READ_COMMAND_2_P    0
这个宏的定义跟读NANDFLASH发的指令有关,大家可以在代码中搜一下就一目了然了。
 
修改如下函数 这个跟NANDFLASH的地址线有关,修改时可用查看一下NANDFLASH手册
static __inline void
platform_page_address (int page, unsigned char address [])
{
#ifdef NAND_FLASH_512M_HDW
    address [0] = 0;
    address [1] = (unsigned char)  ((unsigned) page & 0xff);
    address [2] = (unsigned char) (((unsigned) page >> 8) & 0xff);
    address [3] = (unsigned char) (((unsigned) page >> 16) & 0x01);
#else
    address [0] = 0;
    address [1] = 0;
    address [2] = (unsigned char)  ((unsigned) page & 0xff);
    address [3] = (unsigned char) (((unsigned) page >> 8) & 0xff);
#endif
}
到现在为止BOOTNAND应该可以正常运行了,不过要让系统的正常运行还需要修改一些文件
下面一一道来。
Pstffs\modules\dntf\incl\dntf.hec
#ifdef NAND_FLASH_512M_HDW
#define NAND_PAGE_SIZE        512
#define NAND_SPARE_SIZE       16
#define NAND_ECC_SIZE         10 //original: 10,  fxj,
#define NAND_PAGES_PER_BLOCK  32
#define NAND_BLOCK_SIZE       (NAND_PAGE_SIZE * NAND_PAGES_PER_BLOCK)
#define NAND_NUM_BLOCKS       200  //original 100, fxj,
#define NAND_MIN_VALID_BLOCKS 15
#define NAND_MAX_BAD_BLOCKS   (NAND_NUM_BLOCKS / 10 ) // 10% of size
#else
#define NAND_PAGE_SIZE        2048
#define NAND_SPARE_SIZE       64
#define NAND_ECC_SIZE         10
#define NAND_PAGES_PER_BLOCK  64
#define NAND_BLOCK_SIZE       (NAND_PAGE_SIZE * NAND_PAGES_PER_BLOCK)
#define NAND_NUM_BLOCKS       100
#define NAND_MIN_VALID_BLOCKS 15
#define NAND_MAX_BAD_BLOCKS   (NAND_NUM_BLOCKS / 10 ) // 10% of size
#endif
注意:这个宏跟NXPmgrpaging 这个库文件有直接关系,而我们没有这个库的原文件,所以这宏的修改基本来说是没有用的,需要NXP的支持。
Pstffs\modules\tffsal\input\dntfecc.c
#ifdef NAND_FLASH_512M_HDW
/** The number of bits in ECCs generated by the NFI */
#define NFI_ECC_BITS           22
#define NFI_ECC_CHUNK_SIZE     0x100
#define NAND_FLASH_PAGE_BYTES  0x200
#else
/** The number of bits in ECCs generated by the NFI */
#define NFI_ECC_BITS           22
#define NFI_ECC_CHUNK_SIZE     0x100
#define NAND_FLASH_PAGE_BYTES  0x800
#endif
修改各OPT中的宏定义。
-DNAND_FLASH_PAGE_BYTES
-DNAND_FLASH_SPARE_BYTES
-DNAND_FLASH_BLOCK_BYTES
-DNAND_FLASH_BLOCKS
-DNAND_FLASH_FS_BASE
-DNAND_FLASH_FS_MEM_BASE
-DNAND_FLASH_FS_BLOCKS
添加相应NANDFLASH处理文件,需要填充的几个结构:
llinit_katSDIReConfTab
llinit_katSDIInitTab
llinit_katNFIInitTab
llinit_NFICmd_Config
llinit_NFIDesConf
修改ECC算法 
compute_page_ecc   
原为:for(j=0; j<8; j++)    //8256  大页
改为:for(j=0; j<2; j++)   // 2256   小页
到现在为止,NANDFLASH的驱动也完成,接下来就是文件系统的配置了,主要关注
vman5cfg.c 这个文件
需要注意三个宏:
#define BBM_RESERVED        88   坏块的预留BLOCK
MC_VOLMAN_ADD_DEVICE      添加分区
MC_VOLMAN_ADD_VOLUME     在相应分区上添加根目录
T3G7210分为2个分区,3个跟目录
NANDFLASH  包含 sysv   app
FTL_NAND    包含 share

【上篇】
【下篇】

抱歉!评论已关闭.