📄 fmd.c
字号:
return TRUE;
}
}
OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD]CreateNv : no enough good block.\r\n")));
return FALSE;
}
/*******************************************************************************
Function: InitNv
Description: 本接口用于初始化NV项区域
Input: none
Output: NV区域信息
Return: TRUE/FALSE
History:
1. Created by c56450 on 2006/04/09
2. .....
*******************************************************************************/
BOOL InitNv(void)
{
DWORD i = 0;
DWORD j = 0;
SectorInfo stSectorInfo;
g_stFlashChipInfo.bNvInitialFlag = FALSE;
memset(g_stFlashChipInfo.dwNvAddr, 0, sizeof(g_stFlashChipInfo.dwNvAddr));
memset(&stSectorInfo, 0xFF, sizeof(SectorInfo));
for(i=NV_START_BLOCK; i<(NV_START_BLOCK+NV_MAX_BLOCK); i++)
{
if (FMD_GetBlockStatus(i) & BLOCK_STATUS_BAD)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]InitNv : find a bad block = %d.\r\n"), i));
continue;
}
if(!FMD_ReadSector(i*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfo, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]InitNv : Error while FMD_ReadPhySector,Sector = %d.\r\n"), i*g_stFlashChipInfo.SectorsPerBlock));
return CreateNv();
}
if(stSectorInfo.dwReserved1 >= NV_BLOCK_NUM)
{
return CreateNv();
}
else
{
g_stFlashChipInfo.dwNvAddr[stSectorInfo.dwReserved1] = i;
}
if(++j == NV_BLOCK_NUM)
{
if(g_stFlashChipInfo.dwNvAddr[0]&&g_stFlashChipInfo.dwNvAddr[1]&&g_stFlashChipInfo.dwNvAddr[2]&&g_stFlashChipInfo.dwNvAddr[3])
{
g_stFlashChipInfo.bNvInitialFlag = TRUE;
return TRUE;
}
else
{
return FALSE;
}
}
}
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]InitNv : no enough good block.\r\n")));
return FALSE;
}
/*******************************************************************************
Function: ReplaceNvBlock
Description: 本接口用于创建一块NV项代替已坏的块
Input: none
Output: none
Return: TRUE/FALSE
History:
1. Created by c56450 on 2006/04/09
2. .....
*******************************************************************************/
BOOL ReplaceNvBlock(DWORD dwBlock)
{
DWORD i = 0;
SectorInfo stSectorInfo;
g_stFlashChipInfo.bNvInitialFlag = FALSE;
memset(&stSectorInfo, 0xFF, sizeof(SectorInfo));
for(i=NV_START_BLOCK; i<(NV_START_BLOCK+NV_MAX_BLOCK); i++)
{
if (FMD_GetBlockStatus(i) & BLOCK_STATUS_BAD)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReplaceNvBlock : find a bad block = %d.\r\n"), i));
continue;
}
if(!FMD_ReadSector(i*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfo, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReplaceNvBlock : Error while FMD_ReadPhySector,Sector = %d.\r\n"), i*g_stFlashChipInfo.SectorsPerBlock));
return CreateNv();
}
if(stSectorInfo.dwReserved1 >= NV_BLOCK_NUM)
{
if(FMD_SUCCESS != NF_BlockErase(i))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReplaceNvBlock : NF_BlockErase find a bad block = %d.\r\n"), i));
FMD_SetBlockStatus(i, BLOCK_STATUS_BAD);
continue;
}
stSectorInfo.dwReserved1 = dwBlock;
if(!FMD_WriteSector(i*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfo, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReplaceNvBlock : Error while FMD_WritePhySector, Sector = %d.\r\n"), i*g_stFlashChipInfo.SectorsPerBlock));
FMD_SetBlockStatus(i, BLOCK_STATUS_BAD);
continue;
}
g_stFlashChipInfo.dwNvAddr[dwBlock] = i;
g_stFlashChipInfo.bNvInitialFlag = TRUE;
return TRUE;
}
}
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReplaceNvBlock : no enough good block.\r\n")));
return FALSE;
}
/*******************************************************************************
Function: WriteNv
Description: 本接口用于写NV项
Input: 1、dwAddress写入地址
2、pDatabuf 缓冲区地址
3、dwLength 写入长度
Output: pBytesReturned实际写入长度
Return: TRUE/FALSE
History:
1. Created by c56450 on 2006/04/09
2. .....
*******************************************************************************/
BOOL WriteNv(DWORD dwAddress, PBYTE pDatabuf, DWORD dwLength, PDWORD pBytesReturned)
{
DWORD i = 0;
DWORD ret = 0;
DWORD dwReturnLength = 0;
DWORD dwSectNum = 0;
DWORD dwBlock = 0;
DWORD dwPhyBlock = 0;
DWORD dwBlockOffset = 0;
DWORD dwBlockNeedOper = 0;
SectorInfo stSectorInfoBuff;
//NKDbgPrintfW(TEXT("[INFO BOOTFMD]WriteNv : dwAddress = %d, dwLength = 0x%x.\r\n"), dwAddress, dwLength);
if((NULL == pDatabuf)||(0 != (dwAddress%g_stFlashChipInfo.SectorSize))||((dwAddress+dwLength) > IMG_START_ADDR)||(dwAddress < PARA_START_ADDR)||(dwLength > g_stFlashChipInfo.BlockSize))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : bad parameter.\r\n")));
return FALSE;
}
if(!g_stFlashChipInfo.bNvInitialFlag)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : NV region is not ready.\r\n")));
return FALSE;
}
dwBlockOffset = dwAddress%g_stFlashChipInfo.BlockSize;
dwBlock = (dwAddress - dwBlockOffset)/g_stFlashChipInfo.BlockSize - NV_START_BLOCK;
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
dwBlockNeedOper = (dwLength + dwBlockOffset + g_stFlashChipInfo.BlockSize - 1)/g_stFlashChipInfo.BlockSize;
for(i = 0;i < dwBlockNeedOper;)
{
if((dwLength + dwBlockOffset - dwReturnLength) > g_stFlashChipInfo.BlockSize)
{
dwSectNum = g_stFlashChipInfo.SectorsPerBlock - dwBlockOffset/g_stFlashChipInfo.SectorSize;
}
else
{
dwSectNum = ((dwLength - dwReturnLength) + (g_stFlashChipInfo.SectorSize - 1))/g_stFlashChipInfo.SectorSize;
}
if(!FMD_ReadSector(dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock, g_stFlashChipInfo.pNvBlock, NULL, g_stFlashChipInfo.SectorsPerBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while FMD_ReadPhySector,Sector = %d.\r\n"), dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
return FALSE;
}
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
continue;
}
if(!FMD_ReadSector(dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfoBuff, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while FMD_ReadPhySector,Sector = %d.\r\n"), dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
return FALSE;
}
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
continue;
}
ret = NF_BlockErase(dwPhyBlock);
if(FMD_SUCCESS != ret)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : NF_BlockErase find a bad block = %d,errno = 0x%x.\r\n"), dwPhyBlock, ret));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
return FALSE;
}
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
continue;
}
if(!FMD_WriteSector(dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfoBuff, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while FMD_WritePhySector, Sector = %d.\r\n"), dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
return FALSE;
}
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
continue;
}
memcpy(g_stFlashChipInfo.pNvBlock + dwBlockOffset, pDatabuf+dwReturnLength, MIN((dwLength - dwReturnLength), (dwSectNum*g_stFlashChipInfo.SectorSize)));
if(!FMD_WriteSector(dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock, g_stFlashChipInfo.pNvBlock, NULL, g_stFlashChipInfo.SectorsPerBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while FMD_WritePhySector, Sector = %d.\r\n"), dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]WriteNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
return FALSE;
}
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
continue;
}
i ++;
dwReturnLength += dwSectNum*g_stFlashChipInfo.SectorSize;
dwBlockOffset = 0;
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[++dwBlock];
}
if(pBytesReturned)
{
*pBytesReturned = dwLength;
}
return TRUE;
}
/*******************************************************************************
Function: ReadNv
Description: 本接口用于读NV项
Input: 1、dwAddress读取地址
2、pDatabuf缓冲区地址
3、dwLength读取长度
Output: pBytesReturned实际读取字节数
Return: TRUE/FALSE
History:
1. Created by c56450 on 2006/04/09
2. .....
*******************************************************************************/
BOOL ReadNv(DWORD dwAddress, PBYTE pDatabuf, DWORD dwLength, PDWORD pBytesReturned)
{
DWORD i = 0;
DWORD dwReturnLength = 0;
DWORD dwSectNum = 0;
DWORD dwBlock = 0;
DWORD dwPhyBlock = 0;
DWORD dwBlockOffset = 0;
DWORD dwBlockNeedOper = 0;
//NKDbgPrintfW(TEXT("[INFO BOOTFMD]ReadNv : dwAddress = %d, dwLength = 0x%x.\r\n"), dwAddress, dwLength);
if((NULL == pDatabuf)||(0 != (dwAddress%g_stFlashChipInfo.SectorSize))||((dwAddress+dwLength) > IMG_START_ADDR)||(dwAddress < PARA_START_ADDR)||(dwLength > g_stFlashChipInfo.BlockSize))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReadNv : bad parameter.\r\n")));
return FALSE;
}
if(!g_stFlashChipInfo.bNvInitialFlag)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReadNv : NV region is not ready.\r\n")));
return FALSE;
}
dwBlockOffset = dwAddress%g_stFlashChipInfo.BlockSize;
dwBlock = (dwAddress - dwBlockOffset)/g_stFlashChipInfo.BlockSize - NV_START_BLOCK;
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[dwBlock];
dwBlockNeedOper = ((dwLength + dwBlockOffset) + (g_stFlashChipInfo.BlockSize - 1))/g_stFlashChipInfo.BlockSize;
for(i = 0;i < dwBlockNeedOper;)
{
if((dwLength + dwBlockOffset - dwReturnLength) > g_stFlashChipInfo.BlockSize)
{
dwSectNum = g_stFlashChipInfo.SectorsPerBlock - dwBlockOffset/g_stFlashChipInfo.SectorSize;
}
else
{
dwSectNum = ((dwLength - dwReturnLength) + (g_stFlashChipInfo.SectorSize - 1))/g_stFlashChipInfo.SectorSize;
}
if(!FMD_ReadSector(dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock + dwBlockOffset/g_stFlashChipInfo.SectorSize, g_stFlashChipInfo.pNvBlock+dwReturnLength, NULL, dwSectNum))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReadNv : Error while FMD_ReadPhySector,Sector = %d.\r\n"), dwPhyBlock*g_stFlashChipInfo.SectorsPerBlock+dwBlockOffset/g_stFlashChipInfo.SectorSize));
FMD_SetBlockStatus(dwPhyBlock, BLOCK_STATUS_BAD);
if(!ReplaceNvBlock(dwBlock))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]ReadNv : Error while ReplaceNvBlock not enough good block.\r\n")));
g_stFlashChipInfo.bNvInitialFlag = FALSE;
}
return FALSE;
}
i ++;
dwReturnLength += dwSectNum*g_stFlashChipInfo.SectorSize;
dwBlockOffset = 0;
dwPhyBlock = g_stFlashChipInfo.dwNvAddr[++dwBlock];
}
if(pBytesReturned)
{
*pBytesReturned = dwLength;
}
memcpy(pDatabuf, g_stFlashChipInfo.pNvBlock, dwLength);
return TRUE;
}
BOOL CheckNV(void)
{
DWORD i = 0, j = 0;
SectorInfo stSectorInfo;
for(i=NV_START_BLOCK; i<(NV_START_BLOCK+NV_MAX_BLOCK); i++)
{
if (FMD_GetBlockStatus(i) & BLOCK_STATUS_BAD)
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]InitNv : find a bad block = %d.\r\n"), i));
continue;
}
if(!FMD_ReadSector(i*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfo, 1))
{
OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]InitNv : Error while FMD_ReadPhySector,Sector = %d.\r\n"), i*g_stFlashChipInfo.SectorsPerBlock));
continue;
}
if(stSectorInfo.dwReserved1 != j)
{
return FLASH_IS_NO_NV;
}
if(++j >= NV_BLOCK_NUM)
{
return FLASH_IS_VALID_NV;
}
}
OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD]CheckNV : no enough good block.\r\n")));
return FLASH_IS_INVALID_NV;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -