nand_util.c

来自「u盘MCU端源代码,开发U盘的可以参考.」· C语言 代码 · 共 1,556 行 · 第 1/4 页

C
1,556
字号
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x02,
  0xff, 0xff, 0xff, 0x10, 0x02, 0xaa, 0xaa, 0x97
};



void util_create_bad_128mb_media(void) reentrant
{
  trace0(0, util, 0, "Creating bad 128 mb media...") ;
  // safe-erase media
  util_safe_erase_media() ;

  // allocate a write block
  g_addr_rd_phy_blk = k_block_free ;
  g_addr_zone = 0 ;
  g_addr_log_blk = 0;
  g_addr_page=0 ;
  _media_data(sector_buffer) = g_sector_buffer ;
  
  map_alloc_wr_blk() ;

  // write log 0 pg 0
  memcpy(g_sector_buffer, k_tbl_sm_log_0_pg_0, 512) ;
  memcpy(x_sm_redt_data, k_tbl_sm_log_0_pg_0+512, 16) ;
  trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
  _media_write_sector() ;
  util_trace_buffer(g_sector_buffer, 512) ;
  util_trace_buffer(x_sm_redt_data, 16) ;

  // clear extra data and write log 0 pg 1-end of block
  memset(g_sector_buffer, 0xff, 512) ;
  _media_clear_extra_data() ;
  _media_bind_log2phy() ;
  for(g_addr_page=1;g_addr_page<_media_data(pages_per_block);g_addr_page++)
  {
    trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
    _media_write_sector() ;
    util_trace_buffer(g_sector_buffer, 512) ;
    util_trace_buffer(x_sm_redt_data, 16) ;
  }

  // write log 1 pg 0-14
  g_addr_log_blk=1 ;
  
  map_alloc_wr_blk() ;
  _media_clear_extra_data() ;
  _media_bind_log2phy() ;
  for(g_addr_page=0; g_addr_page<15; g_addr_page++)
  {
    trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
    _media_write_sector() ;
    util_trace_buffer(g_sector_buffer, 512) ;
    util_trace_buffer(x_sm_redt_data, 16) ;
  }

  // write log 1 pg 15
  memcpy(g_sector_buffer, k_tbl_sm_log_1_pg_15, 512) ;
  memcpy(x_sm_redt_data, k_tbl_sm_log_1_pg_15+512, 16) ;
  g_addr_page=15 ;
  trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
  _media_write_sector() ;
  util_trace_buffer(g_sector_buffer, 512) ;
  util_trace_buffer(x_sm_redt_data, 16) ;

  // write log 1 pg 16
  memcpy(g_sector_buffer, k_tbl_sm_log_1_pg_16, 512) ;
  memcpy(x_sm_redt_data, k_tbl_sm_log_1_pg_16+512, 16) ;
  g_addr_page=16 ;
  trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
  _media_write_sector() ;
  util_trace_buffer(g_sector_buffer, 512) ;
  util_trace_buffer(x_sm_redt_data, 16) ;

  memset(g_sector_buffer, 0x00, 512) ;
  _media_clear_extra_data() ;
  _media_bind_log2phy() ;
  for(g_addr_page=17; g_addr_page<_media_data(pages_per_block);g_addr_page++)
  {
    trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
    _media_write_sector() ;
    util_trace_buffer(g_sector_buffer, 512) ;
    util_trace_buffer(x_sm_redt_data, 16) ;
  }

  // write log 2,3 pgs 0-31
  for(g_addr_log_blk=2;g_addr_log_blk<=3;g_addr_log_blk++)
  {
    map_alloc_wr_blk() ;
    _media_bind_log2phy() ;
    for(g_addr_page=0 ;g_addr_page < _media_data(pages_per_block);g_addr_page++)
    {
      trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
      _media_write_sector() ;
      util_trace_buffer(g_sector_buffer, 512) ;
      util_trace_buffer(x_sm_redt_data, 16) ;
    }
  }

  // done
  trace0(0, util, 0, "create bad media:  done") ;
  trace0(0, util, 0, "dumping phy blocks 0-5") ;
  for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<5; g_addr_rd_phy_blk++)
  {
    util_trace_phy_block() ;
  }

  trace0(0, util, 0, "done") ;
}
#endif // ghosting an optimized format onto blank media
// --------------------------------------------------------------------
// --------------------------------------------------------------------

#define kbm_map_soft_l2p_binding (0x8000)
#define kbm_map_l2p_bits         (0x03FF)
#if 0 

void map_debug(uint8 zone) reentrant
{
  _l2p_map = _log_map(zone);
  _a_map = _assign_map(zone);
#ifdef k_opt_erase_cache
  if( _media_data(options)&kbm_media_data_opt_erase_cache)
  {
    _e_map = _erase_cache(zone);
  }
  else
#endif
  {
    // this simplifies the clearing of the data below
    _e_map = _a_map;
  }

  trace1(0, map, 0, "&_l2p_map    :%04x", ((uint16)_l2p_map)); 
  trace1(0, map, 0, "&_a_map      :%04x", ((uint16)_a_map));
  trace1(0, map, 0, "&_e_map      :%04x", ((uint16)_e_map));

  for(g_addr_wr_phy_blk=0;g_addr_wr_phy_blk<1024;g_addr_wr_phy_blk++)
  {
    g_addr_rd_phy_blk=k_block_free;
    for(g_addr_log_blk=0;g_addr_log_blk<1000;g_addr_log_blk++)
    {
      if( (_l2p_map[g_addr_log_blk]&kbm_map_l2p_bits) ==g_addr_wr_phy_blk)
      {
        g_addr_rd_phy_blk=g_addr_log_blk; 
        break;
      }
    }
    trace4(0, map, 0, "phy_blk:%d - in_use:%c in_cache:%c log_binding:%d", g_addr_wr_phy_blk, (_map_is_phy_blk_used(_a_map,g_addr_wr_phy_blk)?'Y':'N'), (_map_is_phy_blk_used(_e_map,g_addr_wr_phy_blk)?'Y':'N'), g_addr_log_blk);
    for(g_addr_log_blk++;g_addr_log_blk<1000;g_addr_log_blk++)
    {
      if((_l2p_map[g_addr_log_blk]&kbm_map_l2p_bits)==g_addr_wr_phy_blk)
      {
        trace1(0, map, 0, "           - *** also bound to log:%d", g_addr_log_blk);
      }
    }
  }
}
#endif




void util_read_lba(uint32 lba) reentrant
{
  map_lba2addr_rd(lba) ;
  _media_data(sector_buffer)=g_sector_buffer;
  _media_read_sector();
}

xdata _tmp_buf[16];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_write_lba(uint32 lba) reentrant
{
  memcpy(_tmp_buf, x_sm_redt_data, 16);
  map_write_begin(lba);
  _media_data(sector_buffer)=g_sector_buffer;
  memcpy(x_sm_redt_data, _tmp_buf, 16);
  _media_write_sector();
  map_write_flush();
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_test_hardware_ecc(uint32 lba, uint16 ix_bit) reentrant
{
  trace2(0, util, 0, "util_test_hardware_ecc() - creating 1-bit error in lba %d bit %d", lba, ix_bit) ;
  util_read_lba(lba);
  // there's a bug in _flipbit that won't go higher than 256 bytes.  should be a non-issue for mapper
  if(ix_bit<2048)
  {
    _flpbit((g_sector_buffer), ix_bit);
  }
  else
  {
    _flpbit(((g_sector_buffer)+100), ix_bit);
  }
  util_write_lba(lba);
}

void util_create_2bit_error(uint32 lba) reentrant
{
  util_read_lba(lba);
  _flpbit(g_sector_buffer,0);
  _flpbit(g_sector_buffer,1);
  util_write_lba(lba);
}

void util_create_1bit_error(uint32 lba) reentrant
{
  util_read_lba(lba);
  _flpbit(g_sector_buffer,0);
  util_write_lba(lba);
}


#if 0 
xdata uint8 buffer1[528];
xdata uint8 buffer2[528];
void util_compare_blocks(uint16 blk1, uint16 blk2) reentrant
{
  uint16 offset;

  trace0(0, util, 0, "Compare Block Data") ;
  trace1(0, util, 0, "block 1: %d",blk1) ;
  trace1(0, util, 0, "block 2: %d",blk2) ;
  for(g_addr_page=0;g_addr_page<_media_data(pages_per_block);g_addr_page++)
  {
    trace1(0, util, 0, "--- page %d ---", g_addr_page);
    g_addr_rd_phy_blk=blk1;
    _media_data(sector_buffer)=buffer1;
    _media_read_sector();
    memcpy(buffer1+512, x_sm_redt_data, 16);

    g_addr_rd_phy_blk=blk2;
    _media_data(sector_buffer)=buffer2;
    _media_read_sector();
    memcpy(buffer2+512, x_sm_redt_data, 16);

    if(memcmp(buffer1, buffer2, 512))
    {
      for(offset=0; offset<512;offset++)
      {
        if(buffer1[offset]!=buffer2[offset])
        {
          trace5(0, util, 0, "page data difference at offset %d -- block %d:%02X block %d:%02X", offset, blk1, buffer1[offset], blk2, buffer2[offset]);
        }
      }
    }
    else
    {
      trace0(0, util, 0, "page data identical") ;
    }
    if(memcmp(buffer1+512, buffer2+512, 16))
    {
      trace0(0, util, 0, "extra data differs");
      for(offset=0;offset<16;offset++)
      {
        if(buffer1[offset+512]!=buffer2[offset+512])
        {
          trace5(0, util, 0, "extra data difference at offset %d -- block %d:%02X block %d:%02X", offset, blk1, buffer1[offset+512], blk2, buffer2[offset+512]);
        }
      }
    }
    else
    {
      trace0(0, util, 0, "extra data identical") ;
    }
  }

}




//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_test_copy_double_bit_ecc(uint32 lba) reentrant
{
  uint16 first_rd_blk;
  uint16 org_rd_blk;
  uint16 err_rd_blk;
  trace0(0, util, 0, "------------ 2-bit during copy head (copy before starting user data)") ;
  
  
  map_lba2addr_rd(lba) ;
  trace5(0, util, 0, "------------ creating 2-bit error on block %d:%d[r%d|w%d]:%d", g_addr_zone, g_addr_log_blk, g_addr_rd_phy_blk, g_addr_wr_phy_blk, g_addr_page);
  trace0(0, util, 0, "------------ original data/redundant") ;
  first_rd_blk=org_rd_blk = g_addr_rd_phy_blk;
  util_trace_page();
  
  util_create_2bit_error(lba);

  trace0(0, util, 0, "------------ compare org blk to err blk to verify only difference is 2-bit error");
  map_lba2addr_rd(lba);
  err_rd_blk=g_addr_rd_phy_blk;
  util_compare_blocks(org_rd_blk, err_rd_blk);

  // read n write a block back to simulate "user" data
  trace0(0, util, 0, "------------ writing 'user data'") ;
  util_read_lba(lba+1);
  util_write_lba(lba+1);
  
  trace0(0, util, 0, "------------ compare err blk w/ new blk(verify blk status 'bad' in err blk, verify data status 'bad' in error page, verify ecc data updated in error page, verify page data identical for ALL pages)"); 
  map_lba2addr_rd(lba);
  util_compare_blocks(err_rd_blk, g_addr_rd_phy_blk);

  trace0(0, util, 0, "------------ compare org blk w/ new blk (verify only differnce is in page that has error)") ;
  map_lba2addr_rd(lba);
  util_compare_blocks(org_rd_blk, g_addr_rd_phy_blk);
  

  map_lba2addr_rd(lba+2) ;
  trace5(0, util, 0, "------------ creating 2-bit error on block %d:%d[r%d|w%d]:%d", g_addr_zone, g_addr_log_blk, g_addr_rd_phy_blk, g_addr_wr_phy_blk, g_addr_page);
  org_rd_blk = g_addr_rd_phy_blk;

  util_create_2bit_error(lba+2);

  trace0(0, util, 0, "------------ compare org blk to err blk to verify only difference is 2-bit error");
  map_lba2addr_rd(lba);
  err_rd_blk = g_addr_rd_phy_blk;
  util_compare_blocks(org_rd_blk, err_rd_blk);


  trace0(0, util, 0, "------------ causing copy-tail 2-bit ecc error") ;
  // do a read/write before the 2-bit error to cause problem in copy-tail
  util_read_lba(lba+1);
  util_write_lba(lba+1);
  
  trace0(0, util, 0, "------------ compare err blk w/ new blk(verify blk status 'bad' in err blk, verify data status 'bad' in error page, verify ecc data updated in error page, verify page data identical for ALL pages)"); 
  map_lba2addr_rd(lba+2);
  util_compare_blocks(err_rd_blk, g_addr_rd_phy_blk);

  trace0(0, util, 0, "------------ compare org blk w/ new blk (verify only differnce is in page that has error)") ;
  map_lba2addr_rd(lba+2);
  util_compare_blocks(org_rd_blk, g_addr_rd_phy_blk);

  trace0(0, util, 0, "------------ dump of Final Logical Block") ;
  util_trace_phy_block();
  
  trace0(0, util, 0, "------------ dump of First Logical Block") ;
  g_addr_rd_phy_blk=first_rd_blk;
  util_trace_phy_block();


  if( _media_data(options)&kbm_media_data_opt_erase_cache)
  {
    trace0(0, nand, 0, "flushing erase cache()") ;
    map_erase_cache_flush_all();
  }
  
  mcu_halt();
}

#endif



⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?