flashmngl05.c

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

C
1,671 行
字号
    if (retVal != (INT)g_pFlashParam->uSparePerPage)
    {
        return retVal;
    }

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

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

    // update tables and flags
    for(i = 2; i < g_uFlashBlockPrepare; i++){
		g_FlashTablePrepare[i - 2] = g_FlashTablePrepare[i];
    }
	if(error0 == FALSE){
	    g_FlashTablePrepare[i - 2] = g_FlashPhyNum0;
		i++;
	}else{
		g_uFlashBlockPrepare --;
	}
	if(error1 == FALSE){
	    g_FlashTablePrepare[i - 2] = g_FlashPhyNum1;
	}else{
		g_uFlashBlockPrepare --;
	}

    for (i = 0; i < g_pFlashParam->uUserBlockNum; i++)
    {
        if (g_FlashTableLog2Phy[i] == g_FlashPhyNum0)
        {
            g_FlashTableLog2Phy[i] = flashPhyNum2;
            break;
        }
    }

    g_FlashPhyNum0 = flashPhyNum2;
    g_FlashPhyNum1 = -1;
    g_FlashModify = FALSE;
    g_FlashDirty = FALSE;

    return NFLS_ERR_NO;
}



INT FlashMngBlockCopy(INT phyNum, INT pageOffset)		// ret new block's physical number
{
	///INT	i, position;
    INT	position;
    UINT    i;
	INT	retVal;
    UINT32  address;


	if(phyNum == g_FlashTablePrepare[0]){
		position = 1;
	}else{
		position = 0;
	}

	while(1){
	    // get a new prapare block
	    retVal = FlashMngEraseDriver(g_FlashTablePrepare[position]*g_pFlashParam->uDataPerBlock);
	    if (retVal == NFLS_ERR_NO){	// swap
	        for (i = 0; i < g_pFlashParam->uPagePerBlock; i++)
	        {
	        	if((INT)i == pageOffset){
					continue;
	        	}

	            // read page from org block
	            address = phyNum * g_pFlashParam->uDataPerBlock
	                + i * g_pFlashParam->uDataPerPage;

	            FlashMngReadDriver(FLASH_IO_DATASPARE, address, g_pFlashOnlyBuf,
	                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);
				// I ignore the return value, because I can do nothing.

                address = g_FlashTablePrepare[position] * g_pFlashParam->uDataPerBlock
                    + i * g_pFlashParam->uDataPerPage;

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

                if (retVal !=
                    (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
                {
                    break;
                }
	        }

			if(i == g_pFlashParam->uPagePerBlock){	// swap ok
				// label "phyNum" to bad block
			    memset(g_pFlashOnlySpareBuf, 0xff, g_pFlashParam->uSparePerPage);
			    BLOCK_ATTRIBUTE(g_pFlashOnlySpareBuf) = FLASH_ATTRIBUTE_BAD;
		        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
		            phyNum * g_pFlashParam->uDataPerBlock,
		            g_pFlashOnlySpareBuf, g_pFlashParam->uSparePerPage);

				// set return value(new block's physical number)
		    	retVal = g_FlashTablePrepare[position];
				g_uFlashBlockPrepare --;
				for(i = 1; i <= g_uFlashBlockPrepare; i++){
					g_FlashTablePrepare[i-1] = g_FlashTablePrepare[i];
				}
				return retVal;
			}
	    }
		if(retVal == NFLS_ERR_TIMEOUT){	// need swap block
			// label this block to bad block
		    memset(g_pFlashOnlySpareBuf, 0xff, g_pFlashParam->uSparePerPage);
		    BLOCK_ATTRIBUTE(g_pFlashOnlySpareBuf) = FLASH_ATTRIBUTE_BAD;
	        FlashMngWriteDriver(FLASH_IO_ONLYSPARE,
	            g_FlashTablePrepare[position] * 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(i = position + 1; i <= g_uFlashBlockPrepare; i++){
				g_FlashTablePrepare[i-1] = g_FlashTablePrepare[i];
			}
	    }else{
		    return retVal;
	    }
	}
}


/********************************************************************************/
/* FUNCTION:   FlashMngBlockUpdate                                             */
/* DESCRIPTION:Update buffer to flash, incorporate org block and swap block    */
/* INPUTS:                                                                      */
/* OUTPUTS:                                                                    */
/* RETURN:     NFLS_ERR_NO         ok                                          */
/*              return from FlashMngWriteDriver                                 */
/*              return from FlashMngReadDriver                                  */
/*              return from FlashMngBlockSwap                                   */
/********************************************************************************/
/*    NAME        DATE                REMARKS                                   */
/* ==========  ============   ==================================================*/
/*   Victor     2005-05-10      create                                          */
/********************************************************************************/
INT FlashMngBlockUpdate(void)
{
    UINT    i, error0;
    INT     retVal;
    UINT8   flashSpareBuf[64];
    UINT32  address;

Block_Page_Retry:

    // update buffer to flash
    if (g_FlashModify)      // need update buffer to flash
    {
        if (g_FlashDirty)   // update to swap block
        {
            // if current page has been modified, must update block
            address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            FlashMngReadDriver(FLASH_IO_ONLYSPARE, address,
                &flashSpareBuf[0], g_pFlashParam->uSparePerPage);

            if (!(PAGE_STATUS(flashSpareBuf) & PAGE_STATUS_NODIRTY))
            {
                return FlashMngBlockSwap();
            }

            // set dirty flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_NODIRTY;

            // set available flag
            PAGE_STATUS(g_pFlashSpareBuf) |= PAGE_STATUS_AVAILABLE;

            if (g_FlashPageOffset == 0)
            {
                BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAP;
            }

            // write buffer to swap block
            address = g_FlashPhyNum1 * 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 g_FlashPhyNum1 to another block
					retVal = FlashMngBlockCopy(g_FlashPhyNum1, g_FlashPageOffset);
					if(retVal < 0){
						return retVal;
					}
					g_FlashPhyNum1 = retVal;
					goto Block_Page_Retry;
            	}else{
	                return retVal;
            	}
            }

            // abolish page in org block

            // set inavailable flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_AVAILABLE;

            address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
                + g_FlashPageOffset * g_pFlashParam->uDataPerPage;

            retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE, address,
                g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);

            if (retVal != (INT)g_pFlashParam->uSparePerPage)
            {
                return retVal;
            }
        }
        else    // update to org block
        {
            // set dirty flag
            PAGE_STATUS(g_pFlashSpareBuf) &= ~PAGE_STATUS_NODIRTY;

            // set available flag
            PAGE_STATUS(g_pFlashSpareBuf) |= PAGE_STATUS_AVAILABLE;

            // write buffer to org block
            address = g_FlashPhyNum0 * 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 g_FlashPhyNum0 to another block
					retVal = FlashMngBlockCopy(g_FlashPhyNum0, g_FlashPageOffset);
					if(retVal < 0){
						return retVal;
					}
			        for (i = 0; i < g_pFlashParam->uUserBlockNum; i++)
			        {
			            if (g_FlashTableLog2Phy[i] == g_FlashPhyNum0)
			            {
			                g_FlashTableLog2Phy[i] = retVal;
			                break;
			            }
			        }
					g_FlashPhyNum0 = retVal;
					goto Block_Page_Retry;
            	}else{
	                return retVal;
            	}
            }
        }
    }

Block_Retry:

    //incorporate org block and swap block
    if (g_FlashDirty)
    {
	    memset(g_pFlashOnlySpareBuf, 0xff, g_pFlashParam->uSparePerPage);
	    BLOCK_ATTRIBUTE(g_pFlashOnlySpareBuf) = FLASH_ATTRIBUTE_BAD;
		error0 = FALSE;
        // set transfering flag(begin transfer)
        retVal = FlashMngReadDriver(FLASH_IO_DATASPARE,
            g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock, 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;
   			}
        }

        BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAPING;

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

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

        // update first page to swap block
        if (PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)
        {
            BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_SWAP;

            retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE,
                g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock, g_pFlashBuf,
                g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage);

            if (retVal !=
                (INT)(g_pFlashParam->uDataPerPage + g_pFlashParam->uSparePerPage))
            {
            	if(retVal == NFLS_ERR_TIMEOUT){	// need swap g_FlashPhyNum1 to another block
					retVal = FlashMngBlockCopy(g_FlashPhyNum1, 0);
					if(retVal < 0){
						return retVal;
					}
					g_FlashPhyNum1 = retVal;
					goto Block_Retry;
            	}else{
	                return retVal;
            	}
            }
        }

        for (i = 1; i < g_pFlashParam->uPagePerBlock; i++)
        {
            // read page from org block
            address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
                + i * g_pFlashParam->uDataPerPage;

⌨️ 快捷键说明

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