flashmngl05.c

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

C
1,671 行
字号
            // this block is user block
            if (wLogic < g_pFlashParam->uUserBlockNum)
            {
                // write logical number and org block flag
                memset(g_pFlashSpareBuf, 0xFF, g_pFlashParam->uSparePerPage);
                BLOCK_LOGIC(g_pFlashSpareBuf) = wLogic;
                BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_ORG;

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

                wLogic++;
            }
        }
    }

#ifdef FLASH_CREATE_CALLBACK
    // user's UI callback
    if (fpFormatUI != NULL)
    {
        fpFormatUI(100, userParameter);    // do something user want
    }
#endif

    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;


#ifndef FLASH__MNG_OPTIMIZE
    // logical block
    dwBlock = dwLogicalPage / (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE);
    if (dwBlock >= g_uFlashBlockUser)
    {
        return NFLS_ERR_OVER;       // address is out of range
    }

    // page offset in block
    dwPhysicalPage  = dwLogicalPage % (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE);

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

#else
    register UINT32 i;

    i = (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE);

    // logical block
    dwBlock = dwLogicalPage / i ;
    if (dwBlock >= g_uFlashBlockUser)
    {
        return NFLS_ERR_OVER;       // address is out of range
    }

    // page offset in block
    dwPhysicalPage  = dwLogicalPage % i;

    dwPhysicalPage  += g_FlashTableLog2Phy[dwBlock] * i;

#endif

    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, j;
	UINT	error0, error1;
    INT     retVal;
    INT     flashPhyNum2;           // new prapare block
    UINT32  address;

    memset(g_pFlashOnlySpareBuf, 0xff, g_pFlashParam->uSparePerPage);
    BLOCK_ATTRIBUTE(g_pFlashOnlySpareBuf) = FLASH_ATTRIBUTE_BAD;

Swap_Retry:

	error0 = FALSE;
	error1 = FALSE;
	while(1){
	    // get a new prapare block
	    flashPhyNum2 = g_FlashTablePrepare[1];
	    retVal = FlashMngEraseDriver(flashPhyNum2*g_pFlashParam->uDataPerBlock);
	    if (retVal == NFLS_ERR_NO){
			break;
	    }else if(retVal == NFLS_ERR_TIMEOUT){	// need swap block
			// label this block to bad block
	        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
	                            flashPhyNum2 * g_pFlashParam->uDataPerBlock,
	                            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);

			// delete this block from prepare block list
	        g_uFlashBlockPrepare --;
			if(g_uFlashBlockPrepare < 3){
				return NFLS_ERR_NOSPACE;	// bad blocks are too many to use
			}
			for(j = 2; j <= g_uFlashBlockPrepare; j++){
				g_FlashTablePrepare[j-1] = g_FlashTablePrepare[j];
			}
	    }else{
		    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;
    }
    address = flashPhyNum2 * g_pFlashParam->uDataPerBlock
        + g_FlashPageOffset * g_pFlashParam->uDataPerPage;
    retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
        g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);
    if (retVal != (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
    {
    	if(retVal == NFLS_ERR_TIMEOUT){		// need swap block
			// label this block to bad block
	        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
	        	flashPhyNum2 * g_pFlashParam->uDataPerBlock,
	            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);

			// delete this block from prepare block list
	        g_uFlashBlockPrepare --;
			if(g_uFlashBlockPrepare < 3){
				return NFLS_ERR_NOSPACE;	// bad blocks are too many to use
			}
			for(j = 2; j <= g_uFlashBlockPrepare; j++){
				g_FlashTablePrepare[j-1] = g_FlashTablePrepare[j];
			}
			goto Swap_Retry;
    	}

        return retVal;
    }

    // transfering
    for (i = 0; i < g_pFlashParam->uPagePerBlock; i++)
    {
        if (i != (UINT)g_FlashPageOffset)
        {
            // read page from org block
            address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
                + i * g_pFlashParam->uDataPerPage;

            retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

            if (retVal !=
                (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
            {
            	if((retVal == NFLS_ERR_TIMEOUT) || (retVal == NFLS_ERR_ECC)){	// We must go ahead in spite of this block has some error
					// label this block to bad block
			        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
				        g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock,
			            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);
					error0 = TRUE;
					// Perhaps we should reset the flash at this time
					// ???????????????????????????
       			}else{
	                return retVal;
       			}
            }

            // read page from swap block
            if (!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE))
            {
                address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
                    + i * g_pFlashParam->uDataPerPage;

                retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashBuf,
                    g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

                if (retVal !=
                    (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
                {
	            	if((retVal == NFLS_ERR_TIMEOUT) || (retVal == NFLS_ERR_ECC)){	// We must go ahead in spite of this block has some error
						// label this block to bad block
				        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
					        g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock,
				            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);
						error1 = TRUE;
						// Perhaps we should reset the flash at this time
						// ???????????????????????????
	       			}else{
		                return retVal;
	       			}
                }
            }

            // write page to the new prepare block
            if (i == 0)
            {
                if (PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)
                {
                    BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAP;

                    address = flashPhyNum2 * g_pFlashParam->uDataPerBlock
                        + i * g_pFlashParam->uDataPerPage;

                    retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE,
                        address, g_pFlashBuf,
                        g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

				    if (retVal !=
						(INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
				    {
				    	if(retVal == NFLS_ERR_TIMEOUT){		// need swap block
							// label this block to bad block
					        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
					        	flashPhyNum2 * g_pFlashParam->uDataPerBlock,
					            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);

							// delete this block from prepare block list
					        g_uFlashBlockPrepare --;
							if(g_uFlashBlockPrepare < 3){
								return NFLS_ERR_NOSPACE;	// bad blocks are too many to use
							}
							for(j = 2; j <= g_uFlashBlockPrepare; j++){
								g_FlashTablePrepare[j-1] = g_FlashTablePrepare[j];
							}
							goto Swap_Retry;
				    	}

				        return retVal;
				    }
                }
            }
            else
            {
                if ((PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)
                    && (!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_NODIRTY)))
                {
                    address = flashPhyNum2 * g_pFlashParam->uDataPerBlock
                        + i * g_pFlashParam->uDataPerPage;

                    retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE,
                        address, g_pFlashBuf,
                        g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);



				    if (retVal !=
						(INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
				    {
				    	if(retVal == NFLS_ERR_TIMEOUT){		// need swap block
							// label this block to bad block
					        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
					        	flashPhyNum2 * g_pFlashParam->uDataPerBlock,
					            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);

							// delete this block from prepare block list
					        g_uFlashBlockPrepare --;
							if(g_uFlashBlockPrepare < 3){
								return NFLS_ERR_NOSPACE;	// bad blocks are too many to use
							}
							for(j = 2; j <= g_uFlashBlockPrepare; j++){
								g_FlashTablePrepare[j-1] = g_FlashTablePrepare[j];
							}
							goto Swap_Retry;
				    	}

				        return retVal;
				    }
                }
            }
        }
    }

    // set transfered flag(end transfer)
    retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
        flashPhyNum2 * g_pFlashParam->uDataPerBlock,
        g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

    if (retVal != (INT)g_pFlashParam->uSparePerPage)
    {
        return retVal;
    }

    BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_ORG;

    retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
        flashPhyNum2 * g_pFlashParam->uDataPerBlock,
        g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

    if (retVal != (INT)g_pFlashParam->uSparePerPage)
    {
        return retVal;
    }

    BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_PREPARE;

    retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
        g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock,
        g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

⌨️ 快捷键说明

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