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 + -
显示快捷键?