NAND例程里有个地方不太明白

2019-07-20 11:55发布

本帖最后由 kokoromi 于 2017-9-18 08:51 编辑

下面的代码是 NAND 的例程,31、36和51行的注释部分不太明白,有几个疑问:

1、读取数据的时候也会导致坏块吗?

2、既然读取时出现ECC错误,那么拷贝这些数据还有意义吗,反正都是错误的数据?

3、为什么出现 1bit错误就判断可能是坏块?而2bit错误却不处理?

希望原子大神解答~


[mw_shl_code=c,true]//读扇区(支持多扇区读),FATFS文件系统使用
//pBuffer:数据缓存区
//SectorNo:起始扇区号
//SectorSize:扇区大小
//SectorCount:要写入的扇区数量
//返回值:0,成功
//          其他,失败
u8 FTL_ReadSectors(u8 *pBuffer,u32 SectorNo,u16 SectorSize,u32 SectorCount)
{
    u8 flag=0;
        u16 rsecs;                //单次读取页数
    u32 i=0;
    u32 LBNNo;      //逻辑块号
    u32 PBNNo;      //物理块号
    u32 PhyPageNo;  //物理页号
    u32 PageOffset; //页内偏移地址
    u32 BlockOffset;//块内偏移地址
    for(i=0;i<SectorCount;i++)
    {
      LBNNo=(SectorNo+i)/(nand_dev.block_pagenum*(nand_dev.page_mainsize/SectorSize));//根据逻辑扇区号和扇区大小计算出逻辑块号
      PBNNo=FTL_LBNToPBN(LBNNo);                                        //将逻辑块转换为物理块
      if(PBNNo>=nand_dev.block_totalnum)return 1;        //物理块号大于NAND FLASH的总块数,则失败.

      BlockOffset=((SectorNo+i)%(nand_dev.block_pagenum*(nand_dev.page_mainsize/SectorSize)))*SectorSize;//计算块内偏移
      PhyPageNo=PBNNo*nand_dev.block_pagenum+BlockOffset/nand_dev.page_mainsize;        //计算出物理页号
      PageOffset=BlockOffset%nand_dev.page_mainsize;                                             //计算出页内偏移地址

                  rsecs=(nand_dev.page_mainsize-PageOffset)/SectorSize;                                                //计算一次最多可以读取多少页
                  if(rsecs>(SectorCount-i))rsecs=SectorCount-i;                                                                //最多不能超过SectorCount-i
                  flag=NAND_ReadPage(PhyPageNo,PageOffset,pBuffer,rsecs*SectorSize);                        //读取数据
                  if(flag==NSTA_ECC1BITERR)                                                                                                        //对于1bit ecc错误,可能为坏块
                  {
                          flag=NAND_ReadPage(PhyPageNo,PageOffset,pBuffer,rsecs*SectorSize);                //重读数据,再次确认
                          if(flag==NSTA_ECC1BITERR)
                          {
                                   FTL_CopyAndWriteToBlock(PhyPageNo,PageOffset,pBuffer,rsecs*SectorSize);        //搬运数据
                                  flag=FTL_BlockCompare(PhyPageNo/nand_dev.block_pagenum,0XFFFFFFFF);                //全1检查,确认是否为坏块
                                  if(flag==0)
                                  {
                                          flag=FTL_BlockCompare(PhyPageNo/nand_dev.block_pagenum,0X00);                //全0检查,确认是否为坏块
                                          NAND_EraseBlock(PhyPageNo/nand_dev.block_pagenum);                                        //检测完成后,擦除这个块
                                  }
                                  if(flag)                                                                                                                                //全0/全1检查出错,肯定是坏块了.
                                  {
                                          FTL_BadBlockMark(PhyPageNo/nand_dev.block_pagenum);                                        //标记为坏块
                                          FTL_CreateLUT(1);                                                                                                        //重建LUT表
                                  }
                                  flag=0;
                          }
                  }
                  if(flag==NSTA_ECC2BITERR)flag=0;        //2bit ecc错误,不处理(可能是初次写入数据导致的)
                  if(flag)return 2;                                        //失败
                  pBuffer+=SectorSize*rsecs;                        //数据缓冲区指针偏移
                  i+=rsecs-1;
    }
    return 0;
}[/mw_shl_code]





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。