首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

嵌入式系统中的FLASH(7)

嵌入式系统中的FLASH(7)

static int NF_IsBadBlock(U32 block)             //检测坏块
{
    int i;
    unsigned int blockPage;
    U8 data;
   
    blockPage=(block       // For 2'nd cycle I/O[7:5]
   
    NF_nFCE_L();   
    NF_CMD(0x50);       // Spare array read command
    NF_ADDR(517&0xf);   // Read the mark of bad block in spare array(M addr="5")
[q6]

    NF_ADDR(blockPage&0xff);    // The mark of bad block is in 0 page
    NF_ADDR((blockPage>>8)&0xff);   // For block number A[24:17]
    NF_ADDR((blockPage>>16)&0xff); // For block number A[25]
   for(i=0;i               // wait tWB(100ns) //?????
   
    NF_WAITRB();                    // Wait tR(max 12us)
   
    data=NF_RDDATA();
    NF_nFCE_H();   
    if(data!=0xff)
    {
        Uart_Printf("[block %d has been marked as a bad block(%x)]\n",block,data);
        return 1;
    }
    else
    {
        return 0;
    }
}
static int NF_MarkBadBlock(U32 block)                       //标记坏块
{
    int i;
    U32 blockPage=(block
    seBuf[0]=0xff;
    seBuf[1]=0xff;   
    seBuf[2]=0xff;   
   seBuf[5]=0x44;                              // Bad blcok mark="0"
[q7]

   
   NF_nFCE_L();
    NF_CMD(0x50);                               //????
    NF_CMD(0x80);                               // Write 1st command
   
    NF_ADDR(0x0);                               // The mark of bad block is
    NF_ADDR(blockPage&0xff);                    // marked 5th spare array
    NF_ADDR((blockPage>>8)&0xff);               // in the 1st page.
    NF_ADDR((blockPage>>16)&0xff);            
   
    for(i=0;i
    {
    NF_WRDATA(seBuf);                        // Write spare array
    }
    NF_CMD(0x10);                               // Write 2nd command
   
    for(i=0;i                         //tWB = 100ns. ///???????
    NF_WAITRB();                                // Wait tPROG(200~500us)
    NF_CMD(0x70);
   
    for(i=0;i                          //twhr=60ns////??????
   
    if (NF_RDDATA()&0x1)                        // Spare arrray write error
    {   
        NF_nFCE_H();
        Uart_Printf("[Program error is occurred but ignored]\n");
    }
    else
    {
        NF_nFCE_H();
    }
    Uart_Printf("[block #%d is marked as a bad block]\n",block);
    return 1;
}
int search_logic_block(void)                    //建立物理地址到逻
//辑地址的映射表
{
    unsigned int block,i,blockPage,logic_no,zone,zone_i;
    U8 SE[16];
    for(i=0;i                         //初始化全局变量
        lg2ph=space_block=0xffff;
    logic_number=0;
    space_nr=0;
    NF_nFCE_L();
    zone=BLOCK_NR/1024;                             //确定NAND设备中zone
//的个数
    for(zone_i=0;zone_i
    {
        //搜索每个zone 内逻辑地址和物理地址的映射关系
        for(block=0;block
        {
            blockPage=((block+zone_i*1024)
        NF_WATIRB();                                //等待R/B#信号有效
        
        NF_CMD(0x50);                               // 读取每个block内部第
//0个Page内冗余的16个字节
        NF_ADDR(0);                                 // Column 0
        NF_ADDR(blockPage&0xff);        
        NF_ADDR((blockPage>>8)&0xff);               // Block & page num.
        NF_ADDR((blockPage>>16)&0xff);
        NF_WATIRB();                                //等待R/B#信号有效
        for(i=0;i se=NF_RDDATA();       // Write spare array
        NF_WATIRB();
        if(se[5]!=0xff)
[q8]
                              //检测是否存在坏块
            printk("\n\rphysic block %d is bad block\n\r",block);
        else if(se[7]!=se[12]
[q9]
)
            printk("block address1:%d!=block address2 %d\n\r",se[7],se[12]);
        else if((se[6]
[q10]
&0xf8)==0x10)
        {
            //计算该block对应的逻辑地址
            logic_no=((0x7&se[6])>1)+zone_i*1000;
            if(lg2ph[logic_no]!=0xffff)             //说明有2个block拥有相
//同的逻辑地址
                printk("physical block %d and block %d have the same logic number %d\n",lg2ph[logic_no],block,logic_no);
            else lg2ph[logic_no]=block;             //将该block的逻辑地址
//关系记入lg2ph表
            logic_number++;                        
        }
        else if(se[7]==0xff)                        //说明该block尚未编号
        {space_block[space_nr]=block;
        space_nr++;
        }
        }
    }
    printk("there are totally %d logic blocks\n\r",logic_number);
    NF_nFCE_H();
    return logic_number;
}
这段代码的主要作用就是产生数组lg2ph[],这个数组的含义就是“块物理地址=lg2ph[逻辑地址]”。
继承事业,薪火相传
返回列表