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