flashmngl05.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,671 行 · 第 1/5 页
C
1,671 行
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;
}
}
// write page to swap block
if ((PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)
&& (!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_NODIRTY)))
{
address = g_FlashPhyNum1 * 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 g_FlashPhyNum1 to another block
retVal = FlashMngBlockCopy(g_FlashPhyNum1, i);
if(retVal < 0){
return retVal;
}
g_FlashPhyNum1 = retVal;
goto Block_Retry;
}else{
return retVal;
}
}
}
}
// set transfered flag(end transfer)
retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
g_FlashPhyNum1 * 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,
g_FlashPhyNum1 * 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);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
return retVal;
}
for (i = 0; i < g_pFlashParam->uUserBlockNum; i++)
{
if (g_FlashTableLog2Phy[i] == g_FlashPhyNum0)
{
g_FlashTableLog2Phy[i] = g_FlashPhyNum1;
break;
}
}
if(error0 == TRUE){
for(i = 1; i < g_uFlashBlockPrepare; i++){
g_FlashTablePrepare[i - 1] = g_FlashTablePrepare[i];
}
g_uFlashBlockPrepare --;
}else{
g_FlashTablePrepare[0] = g_FlashPhyNum0;
}
}
return NFLS_ERR_NO;
}
/********************************************************************************/
/* FUNCTION: FlashMngPageUpdate */
/* DESCRIPTION:Update buffer to flash */
/* 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 FlashMngPageUpdate(void)
{
INT retVal;//, i;
UINT i;
UINT8 flashSpareBuf[64];
UINT32 address;
Page_Retry:
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 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 Page_Retry;
}else{
return retVal;
}
}
}
}
return NFLS_ERR_NO;
}
/********************************************************************************/
/* FUNCTION: FlashMngReadPhyEraseUnit */
/* DESCRIPTION:updata buffer to flash and load current page to buffer */
/* INPUTS: dwPhysicalPage physical page */
/* dwLogicalPage logical page */
/* OUTPUTS: */
/* RETURN: >=0 page offset in buffer */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-10 create */
/********************************************************************************/
INT FlashMngReadPhyEraseUnit(INT dwPhysicalPage, INT dwLogicalPage)
{
INT curEraseNum, dwOffset;
INT retVal;
UINT32 address;
// get erase unit number which contains "dwPhysicalPage"
curEraseNum = dwPhysicalPage * NORMAL_PAGE_SIZE / g_pFlashParam->uDataPerBlock;
dwOffset = (dwPhysicalPage % (g_pFlashParam->uDataPerBlock / NORMAL_PAGE_SIZE))
/ (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE);
// block update
if (curEraseNum != g_FlashPhyNum0)
{
if (g_FlashPhyNum0 != -1)
{
if ((retVal = FlashMngBlockUpdate()) != NFLS_ERR_NO)
{
return retVal;
}
}
g_FlashPhyNum0 = curEraseNum;
g_FlashPhyNum1 = -1;
g_FlashPageOffset = dwOffset;
g_FlashModify = FALSE;
g_FlashDirty = FALSE;
}
else if (dwOffset != g_FlashPageOffset) // page update
{
if ((retVal = FlashMngPageUpdate()) != NFLS_ERR_NO)
{
return retVal;
}
g_FlashPageOffset = dwOffset;
g_FlashModify = FALSE;
}
else
{
return (dwPhysicalPage % (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE))
* NORMAL_PAGE_SIZE;
}
address = g_FlashPhyNum0 * g_pFlashParam->uDataPerBlock
+ g_FlashPageOffset * 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))
{
return retVal;
}
if ((g_FlashDirty == TRUE)
&& !(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE))
{
address = g_FlashPhyNum1 * g_pFlashParam->uDataPerBlock
+ g_FlashPageOffset * 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))
{
return retVal;
}
}
return (dwPhysicalPage % (g_pFlashParam->uDataPerPage / NORMAL_PAGE_SIZE))
* NORMAL_PAGE_SIZE;
}
/********************************************************************************/
/* FUNCTION: FlashUpdate */
/* DESCRIPTION:Update buffer to flash, incorporate org block and swap block */
/* INPUTS: */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_NO ok */
/* return from FlashMngBlockUpdate */
/********************************************************************************/
/* NAME DATE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?