flashmng.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,302 行 · 第 1/5 页
C
1,302 行
break;
case FLASH_STATUS_NOTUSED: // the block hase not been used. process as prepare block
case FLASH_STATUS_PREPARE: // the block is a prepare block
if(g_uFlashBlockPrepare >= g_pFlashPara->uPrepareBlockNum){
return NFLS_ERR_FORMAT; // too many prepare block
}
g_FlashTablePrepare[g_uFlashBlockPrepare] = i;
g_uFlashBlockPrepare ++;
break;
case FLASH_STATUS_SWAPING: // date is transfering from org block to swap block
// must process with it's swap block
g_uSwapingBlockPhy = i;
g_uSwapingBlockLog = BLOCK_LOGIC(g_pFlashSpareBuf);
break; // do nothing
case FLASH_STATUS_SWAP: // the block is a swap block
if(g_uSwapBlockPhy != 0xffff){
return NFLS_ERR_FORMAT; // very very infrequent
}
g_uSwapBlockPhy = i;
g_uSwapBlockLog = BLOCK_LOGIC(g_pFlashSpareBuf);
break; // do nothing
default:
return NFLS_ERR_FORMAT; // unknown block status
}
}else{ // bad block
if(g_uFlashBlockBadUser + g_uFlashBlockBadNature >= g_pFlashPara->uPrepareBlockNum){
return NFLS_ERR_NOSPACE; // too many bad blocks to use
}
g_FlashTableBad[g_uFlashBlockBadUser + g_uFlashBlockBadNature] = i;
if(attribute == FLASH_ATTRIBUTE_BAD){
g_uFlashBlockBadUser ++;
}else{
g_uFlashBlockBadNature ++;
}
}
}
if((g_uSwapingBlockPhy != 0xffff) || (g_uSwapBlockPhy != 0xffff)){ // need complete the swap function
if((g_uSwapingBlockPhy != 0xffff) && (g_uSwapBlockPhy == 0xffff)){ // put this block to prepare blocks list
if(g_uFlashBlockPrepare >= g_pFlashPara->uPrepareBlockNum){
return NFLS_ERR_FORMAT; // too many prepare block
}
g_FlashTablePrepare[g_uFlashBlockPrepare] = g_uSwapingBlockPhy;
g_uFlashBlockPrepare ++;
}else{
if((g_uSwapingBlockPhy == 0xffff) && (g_uSwapBlockPhy != 0xffff)){ // swap between an org block
g_FlashPhyNum0 = g_FlashTableLog2Phy[g_uSwapBlockLog];
if(g_FlashPhyNum0 == 0xffff){
return NFLS_ERR_FORMAT; // It's impossible
}
}else if((g_uSwapingBlockPhy != 0xffff) && (g_uSwapBlockPhy != 0xffff)){// swap the two block
g_FlashTableLog2Phy[g_uSwapingBlockLog] = g_uSwapingBlockPhy; // put swaping block to table
if(g_uSwapingBlockLog != g_uSwapBlockLog){
return NFLS_ERR_FORMAT; // It's impossible
}
g_FlashPhyNum0 = g_uSwapingBlockPhy;
}
g_FlashPhyNum1 = g_uSwapBlockPhy;
for(i = g_uFlashBlockPrepare; i != 0; i --){ // empty firt prepare block
g_FlashTablePrepare[i] = g_FlashTablePrepare[i-1];
}
g_FlashModify = FALSE;
g_FlashDirty = TRUE;
if(FlashMngBlockUpdate() != NFLS_ERR_NO){
return NFLS_ERR_FORMAT;
}
}
}
if(g_uFlashBlockPrepare < 1)
return NFLS_ERR_NOSPACE; // bad blocks are too many to use
//check the contrast table
for(i = 0; i < g_pFlashPara->uUserBlockNum; i ++){
if(g_FlashTableLog2Phy[i] == 0xFFFF)
return NFLS_ERR_FORMAT; // there are some blocks are lose.
}
g_FlashPhyNum0 = -1;
g_FlashPhyNum1 = -1;
g_FlashModify = FALSE;
g_FlashDirty = FALSE;
return NFLS_ERR_NO; // ok
}
/********************************************************************************/
/* FUNCTION: FlashMngTableCreate */
/* DESCRIPTION:format flash to a mass storage. user can create a callback */
/* function(FP_FORMAT_UI) to display current process. */
/* INPUTS: fpFormatUI created by user. will be called once per */
/* percent one */
/* userParameter user parameter will be transfer to */
/* fpFormatUI */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_NO ok */
/* NFLS_ERR_LOWVOLTAGE battery low */
/* return from FlashMngReadDriver */
/* return from FlashMngEraseDriver */
/* return from FlashMngWriteDriver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngTableCreate(FP_FORMAT_UI fpFormatUI, VOID *userParameter)
{
UINT i;
UINT16 wLogic;
INT retVal;
UINT8 attribute;
//if(SysGetLowVoltageStatus() == TRUE)
// return NFLS_ERR_LOWVOLTAGE;
// format block
wLogic = 0;
for(i = FLASH_RESERVE_BLOCK; wLogic < FLASH_RESERVE_SECTOR / (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE); i++){
// read block spare
if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock,
g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
return retVal;
}
attribute = BLOCK_ATTRIBUTE(g_pFlashSpareBuf);
if(attribute == FLASH_ATTRIBUTE_GOOD){ // this block is a good block
if(BLOCK_LOGIC(g_pFlashSpareBuf) != wLogic){
wLogic = 0;
i = FLASH_RESERVE_BLOCK;
break;
}
wLogic++;
}
}
for( ; i < g_pFlashPara->uBlockSum; i ++){
if(!(i % (g_pFlashPara->uBlockSum/100))){ // increase 1%
if(fpFormatUI != NULL){
fpFormatUI(i/(g_pFlashPara->uBlockSum/100), userParameter); // do something user want
}
}
// read block spare
if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock,
g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
return retVal;
}
if(BLOCK_ATTRIBUTE(g_pFlashSpareBuf) == FLASH_ATTRIBUTE_GOOD){ // this block is a good block
// erase this block
if((retVal = FlashMngEraseDriver(i*g_pFlashPara->uDataPerBlock)) != NFLS_ERR_NO){
return retVal;
}
if(wLogic < g_pFlashPara->uUserBlockNum){ // this block is user block
// write logical number and org block flag
memset(g_pFlashSpareBuf, 0xFF, CURRENT_SPARE_SIZE);
BLOCK_LOGIC(g_pFlashSpareBuf) = wLogic;
BLOCK_STATUS(g_pFlashSpareBuf) = FLASH_STATUS_ORG;
// write to flash spare
if((retVal = FlashMngWriteDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock,
g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
return retVal;
}
wLogic++;
}
}
}
if(fpFormatUI != NULL){
fpFormatUI(100, userParameter); // do something user want
}
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;
dwBlock = dwLogicalPage / (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE); // logical block
if(dwBlock >= g_uFlashBlockUser){
return NFLS_ERR_OVER; // address is out of range
}
dwPhysicalPage = dwLogicalPage % (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE);// page offset in block
dwPhysicalPage += g_FlashTableLog2Phy[dwBlock] * (g_pFlashPara->uDataPerBlock / NORMAL_PAGE_SIZE);
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;
INT retVal;
INT flashPhyNum2; // new prapare block
// get a new prapare block
flashPhyNum2 = g_FlashTablePrepare[1];
if((retVal = FlashMngEraseDriver(flashPhyNum2*g_pFlashPara->uDataPerBlock)) != NFLS_ERR_NO){
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;
}
if((retVal = FlashMngWriteDriver(FLASH_IO_DATASPARE, flashPhyNum2 * g_pFlashPara->uDataPerBlock + g_FlashPageOffset * g_pFlashPara->uDataPerPage,
&g_FlashBuf[0], CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE)) != CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE){
return retVal;
}
// transfering
for(i = 0; i < g_pFlashPara->uPagePerBlock; i++){
if( i != (UINT)g_FlashPageOffset ){
// read page from org block
if((retVal = FlashMngReadDriver(FLASH_IO_DATASPARE, g_FlashPhyNum0 * g_pFlashPara->uDataPerBlock + i * g_pFlashPara->uDataPerPage,
&g_FlashBuf[0], CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE)) != CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE){
return retVal;
}
// read page from swap block
if(!(PAGE_STATUS(g_pFlashSpareBuf) & PAGE_STATUS_AVAILABLE)){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?