flashmngl05.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,671 行 · 第 1/5 页
C
1,671 行
// process according to the status of this block
status = BLOCK_STATUS(g_pFlashSpareBuf);
switch (status) {
case FLASH_STATUS_ORG: // the block is a org block.
// establish contrast table.
if (BLOCK_LOGIC(g_pFlashSpareBuf) >= g_pFlashParam->uUserBlockNum)
{
return NFLS_ERR_FORMAT; // illegal logical number
}
if (g_FlashTableLog2Phy[BLOCK_LOGIC(g_pFlashSpareBuf)] != 0xffff)
{
return NFLS_ERR_FORMAT; // It's impossible
}
g_FlashTableLog2Phy[BLOCK_LOGIC(g_pFlashSpareBuf)] = i;
g_uFlashBlockUser ++;
break;
case FLASH_STATUS_NOTUSED: // the block hase not been used.
// process as prepare block
case FLASH_STATUS_PREPARE: // the block is a prepare block
if (g_uFlashBlockPrepare >= g_pFlashParam->uPrepareBlockNum)
{
return NFLS_ERR_FORMAT; // too many prepare block
}
g_FlashTablePrepare[g_uFlashBlockPrepare] = i;
g_uFlashBlockPrepare ++;
break;
case FLASH_STATUS_SWAPING: // date is transfering from org block to swap block
// must process with it's swap block
g_uSwapingBlockPhy = i;
g_uSwapingBlockLog = BLOCK_LOGIC(g_pFlashSpareBuf);
break; // do nothing
case FLASH_STATUS_SWAP: // the block is a swap block
if (g_uSwapBlockPhy != 0xffff)
{
return NFLS_ERR_FORMAT; // very very infrequent
}
g_uSwapBlockPhy = i;
g_uSwapBlockLog = BLOCK_LOGIC(g_pFlashSpareBuf);
break; // do nothing
default:
return NFLS_ERR_FORMAT; // unknown block status
}
}
else // bad block
{
if (g_uFlashBlockBadUser + g_uFlashBlockBadNature
>= g_pFlashParam->uPrepareBlockNum)
{
return NFLS_ERR_NOSPACE; // too many bad blocks to use
}
g_FlashTableBad[g_uFlashBlockBadUser + g_uFlashBlockBadNature] = i;
if (attribute == FLASH_ATTRIBUTE_BAD) {
g_uFlashBlockBadUser ++;
} else {
g_uFlashBlockBadNature ++;
}
}
}
if ((g_uSwapingBlockPhy != 0xffff) || (g_uSwapBlockPhy != 0xffff))
{ // need complete the swap function
if ((g_uSwapingBlockPhy != 0xffff) && (g_uSwapBlockPhy == 0xffff))
{ // put this block to prepare blocks list
if (g_uFlashBlockPrepare >= g_pFlashParam->uPrepareBlockNum)
{
return NFLS_ERR_FORMAT; // too many prepare block
}
g_FlashTablePrepare[g_uFlashBlockPrepare] = g_uSwapingBlockPhy;
g_uFlashBlockPrepare ++;
}
else
{
if ((g_uSwapingBlockPhy == 0xffff) && (g_uSwapBlockPhy != 0xffff))
{ // swap between an org block
g_FlashPhyNum0 = g_FlashTableLog2Phy[g_uSwapBlockLog];
if (g_FlashPhyNum0 == 0xffff)
{
return NFLS_ERR_FORMAT; // It's impossible
}
}
else if ((g_uSwapingBlockPhy != 0xffff) && (g_uSwapBlockPhy != 0xffff))
{ // swap the two block
// put swaping block to table
g_FlashTableLog2Phy[g_uSwapingBlockLog] = g_uSwapingBlockPhy;
if(g_uSwapingBlockLog != g_uSwapBlockLog)
{
return NFLS_ERR_FORMAT; // It's impossible
}
g_FlashPhyNum0 = g_uSwapingBlockPhy;
}
g_FlashPhyNum1 = g_uSwapBlockPhy;
for (i = g_uFlashBlockPrepare; i != 0; i --)
{ // empty firt prepare block
g_FlashTablePrepare[i] = g_FlashTablePrepare[i-1];
}
g_FlashModify = FALSE;
g_FlashDirty = TRUE;
if (FlashMngBlockUpdate() != NFLS_ERR_NO)
{
return NFLS_ERR_FORMAT;
}
}
}
if (g_uFlashBlockPrepare < 1)
{
return NFLS_ERR_NOSPACE; // bad blocks are too many to use
}
// check the contrast table
for (i = 0; i < g_pFlashParam->uUserBlockNum; i ++)
{
if (g_FlashTableLog2Phy[i] == 0xFFFF)
{
return NFLS_ERR_FORMAT; // there are some blocks are lose.
}
}
g_FlashPhyNum0 = -1;
g_FlashPhyNum1 = -1;
g_FlashModify = FALSE;
g_FlashDirty = FALSE;
return NFLS_ERR_NO; // ok
}
void FlashMngTest(void)
{
UINT i, j;
INT retVal;
// format block
for (i = 0; i < g_pFlashParam->uBlockSum; i++){
// read block spare of 1st page
retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
while(1){
#ifndef _WIN32
asm("nop");
#endif
}
}
// this block is a good block, erase this block
if (BLOCK_ATTRIBUTE(g_pFlashSpareBuf) == FLASH_ATTRIBUTE_GOOD)
{
memset(g_pFlashSpareBuf, 0xFF, g_pFlashParam->uSparePerPage);
retVal = FlashMngEraseDriver(i*g_pFlashParam->uDataPerBlock);
if (retVal != NFLS_ERR_NO)
{
goto this_block_is_bad;
}
for(j = 0; j < g_pFlashParam->uPagePerBlock; j++){
// write to flash
retVal = FlashMngWriteDriver(FLASH_IO_ONLYDATA, i * g_pFlashParam->uDataPerBlock + j * g_pFlashParam->uDataPerPage,
(UINT8 *)0xd00000, g_pFlashParam->uDataPerPage);
if (retVal == (INT)g_pFlashParam->uDataPerPage){
retVal = FlashMngReadDriver(FLASH_IO_ONLYDATA, i * g_pFlashParam->uDataPerBlock + j * g_pFlashParam->uDataPerPage,
g_pFlashBuf, g_pFlashParam->uDataPerPage);
if (retVal != (INT)g_pFlashParam->uDataPerPage){
goto this_block_is_bad;
}
}else{
goto this_block_is_bad;
}
}
}
continue;
this_block_is_bad:
// this block is bad,
BLOCK_ATTRIBUTE(g_pFlashSpareBuf) = FLASH_ATTRIBUTE_BAD;
// write to flash spare
retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
while(1){
#ifndef _WIN32
asm("nop");
#endif
}
}
}
return;
}
/********************************************************************************/
/* FUNCTION: FlashMngTableCreate */
/* DESCRIPTION:format flash to a mass storage. user can create a callback */
/* function(FP_FORMAT_UI) to display current process. */
/* INPUTS: fpFormatUI created by user. will be called once per */
/* percent one */
/* userParameter user parameter will be transfer to */
/* fpFormatUI */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_NO ok */
/* NFLS_ERR_LOWVOLTAGE battery low */
/* return from FlashMngReadDriver */
/* return from FlashMngEraseDriver */
/* return from FlashMngWriteDriver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngTableCreate(FP_FORMAT_UI fpFormatUI, VOID *userParameter)
{
UINT i;
UINT16 wLogic;
INT retVal;
UINT8 attribute;
// format block
wLogic = 0;
#ifndef _WIN32
for(i = FLASH_RESERVE_BLOCK; wLogic < FLASH_RESERVE_SECTOR / (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE) + 1; i++){
// read block spare
if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
return retVal;
}
attribute = BLOCK_ATTRIBUTE(g_pFlashSpareBuf);
if(attribute == FLASH_ATTRIBUTE_GOOD){ // this block is a good block
if(BLOCK_LOGIC(g_pFlashSpareBuf) != wLogic){
wLogic = 0;
i = FLASH_RESERVE_BLOCK;
break;
}
wLogic++;
}
}
#else
i = FLASH_RESERVE_BLOCK;
#endif
for( ; i < g_pFlashParam->uBlockSum; i ++)
{
#ifdef FLASH_CREATE_CALLBACK // DennyHan added this
// increase 1%, call user's UI callback function
if (!(i % (g_pFlashParam->uBlockSum/100)))
{
if (fpFormatUI != NULL)
{
// do something user want
fpFormatUI(i/(g_pFlashParam->uBlockSum/100), userParameter);
}
}
#endif
// 检查Block出厂坏块标示,2K/page的在Spare 1st Byte
// 如果是坏块,在6th Byte位置上重新标记
// read block spare of 1st page
retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
return retVal;
}
// read 2nd page
FlashMngReadDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock + g_pFlashParam->uDataPerPage,
g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);
// check 1stB in 1st&2nd page, if not 0xFF, the block is bad
if (BLOCK_ORIGIN(g_pFlashSpareBuf) != FLASH_ATTRIBUTE_GOOD
|| BLOCK_ORIGIN(g_pFlashOnlySpareBuf) != FLASH_ATTRIBUTE_GOOD)
{
// copy bad sign to 6thB
BLOCK_ATTRIBUTE(g_pFlashSpareBuf) = FLASH_ATTRIBUTE_BAD;
// write to flash spare
retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
}
// this block is a good block, erase this block
if (BLOCK_ATTRIBUTE(g_pFlashSpareBuf) == FLASH_ATTRIBUTE_GOOD)
{
retVal = FlashMngEraseDriver(i*g_pFlashParam->uDataPerBlock);
if (retVal != NFLS_ERR_NO)
{
// this block is bad,
memset(g_pFlashSpareBuf, 0xFF, g_pFlashParam->uSparePerPage);
BLOCK_ATTRIBUTE(g_pFlashSpareBuf) = FLASH_ATTRIBUTE_BAD;
// write to flash spare
retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
return retVal;
}
g_uFlashBlockBadUser ++;
continue;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?