Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15497191
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类:

2008-05-22 18:22:19

NAND Flash的坏块

1)为什么会出现坏块

由于NAND Flash的工艺不能保证NAND的Memory Array在其生命周期中保持性能的可靠,因此,在NAND的生产中及使用过程中会产生坏块。
坏块的特性是:
    当编程/擦除这个块时,不能将某些位拉高,这会造成Page Program和Block Erase操作时的错误,相应地反映到Status Register的相应位。

2)坏块的分类
总体上,坏块可以分为两大类
a.固有坏块
这是生产过程中产生的坏块,一般芯片原厂都会在出厂时都会将坏块第一个page的spare area的第6个byte标记为不等于0xff的值。

b.使用坏块
这是在NAND Flash使用过程中,如果Block Erase或者Page Program错误,就可以简单地将这个块作为坏块来处理,这个时候需要把坏块标记起来。为了和固有坏块信息保持一致,将新发现的坏块的第一个page的 spare area的第6个Byte标记为非0xff的值。


3)坏块管理

    根据上面的这些叙述,可以了解NAND Flash出厂时在spare area中已经反映出了坏块信息,因此,如果在擦除一个块之前,一定要先check一下spare area的第6个byte是否是0xff,如果是就证明这是一个好块,可以擦除;如果是非0xff,那么就不能擦除。

当然,这样处理可能会犯一个错误―――“错杀伪坏块”,因为在芯片操作过程中可能由于电压不稳定等偶然因素会造成NAND操作的错误。但是,为了数据的可靠性及软件设计的简单化,我们就要奉行“蒋委员长”的“宁可错杀一千,也决不放过一个”的宗旨。

4)补充
   (1)需要对前面由于Page Program错误发现的坏块进行一下特别说明。如果在对一个块的某个page进行编程的时候发生了错误就要把这个块标记为坏块,首先就要把其他好的page里面的内容备份到另外一个空的好块里面,然后,把这个块标记为坏块。

    当然,这可能会犯“错杀”之误,一个补救的办法,就是在进行完页备份之后,再将这个块擦除一遍,如果Block Erase发生错误,那就证明这个块是个真正的坏块,那就毫不犹豫地将它打个“戳”吧!
(2)可能有人会问,为什么要使用spare area的第六个byte作为坏块标记。这是NAND Flash生产商的默认约定,你可以看到Samsung,Toshiba,STMicroelectronics都是使用这个Byte作为坏块标记的。


//20080522

 xdfc_read读取一个Page不会出问题,如果连续读取1个blocks大小,将会错误!

 volatile UINT32_T   r_es;
volatile UINT32_T   r_os;
int verify_flash_data(FlashBootType_T fbt)
{
    UINT_T Retval;
    P_FlashProperties_T pFlashP = GetFlashProperties(fbt);
    ReadFlash_F read;
    UINT_T tmp_buffer;
#define page_size           (2048)
#define block_size          (64*page_size)
#define read_start_addr    (1*block_size)
#define read_end_addr      (2048*block_size) //waste 1:30
    int i,j;

    read = pFlashP->ReadFromFlash;
    tmp_buffer = 0x80800000;

    r_es = r_os = 0;
    for(i = read_start_addr;i < read_end_addr;i += block_size)
    {
        for(j = 0;j < block_size;j += page_size)
        {
            Retval = read(i + j, tmp_buffer, 2048, fbt);
            if(Retval == NoError)r_os++;
            else r_es++;
        }
    }
}


volatile UINT32_T   w_es;
volatile UINT32_T   w_os;
int write_flash_data(FlashBootType_T fbt)
{
    UINT_T Retval;
    P_FlashProperties_T pFlashP = GetFlashProperties(fbt);
    WriteFlash_F write = pFlashP->WriteToFlash;
    UINT_T tmp_buffer;
#define block_size          (64*2048)
#define write_start_addr    (1*block_size)
#define write_end_addr      (2048*block_size) //waste 1:30
    int i;

    tmp_buffer = 0x80800000;

    {
        char *p = (char*)tmp_buffer;
        for(i = 0;i < block_size;i++)
        {
            *p++ = i;
        }
    }

    w_es = w_os = 0;
    for(i = write_start_addr;i < write_end_addr;i += block_size)
    {
        Retval = write(i, tmp_buffer, block_size, fbt);
        if(Retval == NoError)w_os++;
        else w_es++;
    }
}


阅读(5680) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-01-13 11:22:20

sorry,代码为内部资料,恕不公开,thanks:)

chinaunix网友2009-01-12 22:02:01

有检测坏块的c语言程序 源代码吗?