flashmng.c

来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,302 行 · 第 1/5 页

C
1,302
字号
                    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_pFlashPara->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_pFlashPara->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_pFlashPara->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
                g_FlashTableLog2Phy[g_uSwapingBlockLog] = g_uSwapingBlockPhy;       // put swaping block to table
                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_pFlashPara->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
}

/********************************************************************************/
/* 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;

    //if(SysGetLowVoltageStatus() == TRUE)
    //    return NFLS_ERR_LOWVOLTAGE;

    // format block
    wLogic = 0;
    for(i = FLASH_RESERVE_BLOCK; wLogic < FLASH_RESERVE_SECTOR / (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE); i++){
        // read block spare
        if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->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++;
        }
    }

    for( ; i < g_pFlashPara->uBlockSum; i ++){

        if(!(i % (g_pFlashPara->uBlockSum/100))){          // increase 1%
            if(fpFormatUI != NULL){
                fpFormatUI(i/(g_pFlashPara->uBlockSum/100), userParameter);    // do something user want
            }
        }

        // read block spare
        if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock, 
            g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
            return retVal;
        }
        
        if(BLOCK_ATTRIBUTE(g_pFlashSpareBuf) == FLASH_ATTRIBUTE_GOOD){  // this block is a good block

            // erase this block
            if((retVal = FlashMngEraseDriver(i*g_pFlashPara->uDataPerBlock)) != NFLS_ERR_NO){
                return retVal;
            }

            if(wLogic < g_pFlashPara->uUserBlockNum){     // this block is user block
            
                // write logical number and org block flag
                memset(g_pFlashSpareBuf, 0xFF, CURRENT_SPARE_SIZE);
                BLOCK_LOGIC(g_pFlashSpareBuf) = wLogic;
                BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_ORG;
    
                // write to flash spare
                if((retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock, 
                    g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
                    return retVal;
                }
                
                wLogic++;
            }
        }
    }

    if(fpFormatUI != NULL){
        fpFormatUI(100, userParameter);    // do something user want
    }
    return NFLS_ERR_NO;
}

/********************************************************************************/
/* FUNCTION:   FlashMngGetPhysicalPage                                         */
/* DESCRIPTION:from logical page to physical page                              */
/* INPUTS:      dwLogicalPage       logical page                                */
/* OUTPUTS:                                                                    */
/* RETURN:     >=0                 physical page                               */
/*              NFLS_ERR_OVER       address is out of range                     */
/********************************************************************************/
/*    NAME        DATE                REMARKS                                   */
/* ==========  ============   ==================================================*/
/*   Victor     2005-05-10      create                                          */
/********************************************************************************/
INT FlashMngGetPhysicalPage(INT dwLogicalPage)
{
    UINT32  dwBlock;
    UINT32  dwPhysicalPage;

    dwBlock = dwLogicalPage / (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE);        // logical block
    if(dwBlock >= g_uFlashBlockUser){
        return NFLS_ERR_OVER;                               // address is out of range
    }
    dwPhysicalPage  = dwLogicalPage % (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE);// page offset in block

    dwPhysicalPage  += g_FlashTableLog2Phy[dwBlock] * (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE);

    return dwPhysicalPage;
}

/********************************************************************************/
/* FUNCTION:   FlashMngBlockSwap                                               */
/* DESCRIPTION:If current page is overwriten, must Update block content to a   */
/*              new prepare block                                               */
/* INPUTS:                                                                      */
/* OUTPUTS:                                                                    */
/* RETURN:     NFLS_ERR_NO         ok                                          */
/*              return from FlashMngWriteDriver                                 */
/*              return from FlashMngReadDriver                                  */
/*              return from FlashMngEraseDriver                                 */
/********************************************************************************/
/*    NAME        DATE                REMARKS                                   */
/* ==========  ============   ==================================================*/
/*   Victor     2005-05-27      create                                          */
/********************************************************************************/
INT FlashMngBlockSwap(void)
{
    UINT    i;
    INT     retVal;
    INT     flashPhyNum2;           // new prapare block

    // get a new prapare block
    flashPhyNum2 = g_FlashTablePrepare[1];
    if((retVal = FlashMngEraseDriver(flashPhyNum2*g_pFlashPara->uDataPerBlock)) != NFLS_ERR_NO){
        return retVal;
    }

    // update buffer to the new prepare block
    PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_NODIRTY;      // set dirty flag
    PAGE_STATUS(g_pFlashSpareBuf) |= PAGE_STATUS_AVAILABLE;     // set available flag
    if(g_FlashPageOffset == 0){
        BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAP;
    }
    
    if((retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE, flashPhyNum2 * g_pFlashPara->uDataPerBlock + g_FlashPageOffset * g_pFlashPara->uDataPerPage, 
        &g_FlashBuf[0], CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE)) != CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE){
        return retVal;
    }

    // transfering
    for(i = 0; i < g_pFlashPara->uPagePerBlock; i++){
        if( i != (UINT)g_FlashPageOffset ){
            // read page from org block
            if((retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, g_FlashPhyNum0 * g_pFlashPara->uDataPerBlock + i * g_pFlashPara->uDataPerPage, 
                &g_FlashBuf[0], CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE)) != CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE){
                return retVal;
            }
    
            // read page from swap block
            if(!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)){

⌨️ 快捷键说明

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