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