⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmd.c

📁 windows mobile 6.13 dnldr下载源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            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 + -