OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4111|回复: 1

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

[复制链接]

68

主题

165

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-3-2
在线时间
156 小时
发表于 2017-9-18 08:50:08 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 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]





最佳答案

查看完整内容[请看2#楼]

1,拷贝是为了先把原有数据保存起来,然后再写1,写0,校验这个块是否坏了。 2,因为STM32的ECC校验只能检测2bit错误,纠正1bit错误
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2017-9-18 08:50:09 | 显示全部楼层
1,拷贝是为了先把原有数据保存起来,然后再写1,写0,校验这个块是否坏了。
2,因为STM32的ECC校验只能检测2bit错误,纠正1bit错误
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-18 11:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表