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

📄 fmd.c

📁 windows mobile 6.13 dnldr下载源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
        return BLOCK_STATUS_BAD;
    }
    /*调用BMM_TranslateInfo转换读取的SpareArea成SECTOR信息;*/
    ret = BMM_TranslateInfo(&(g_stFlashChipInfo.stSectorInfo), g_stFlashChipInfo.pucSpareArea, SPAREAREA_TO_BLOCKINFO);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_GetBlockStatus]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
        return BLOCK_STATUS_BAD;
    }
    /*SECTOR信息中块状态是STATUS_READONLY*/
    if(g_stFlashChipInfo.stSectorInfo.bBadBlock != 0xFF)
    {
        return BLOCK_STATUS_BAD;
    }

    /*SECTOR信息中块状态是STATUS_READONLY*/
    if(!(g_stFlashChipInfo.stSectorInfo.bOEMReserved & OEM_BLOCK_READONLY))
    {
        dwStatus |= BLOCK_STATUS_READONLY;
    }
    /*SECTOR信息中块状态是STATUS_RESERVED*/
    if(!(g_stFlashChipInfo.stSectorInfo.bOEMReserved & OEM_BLOCK_RESERVED))
    {
        dwStatus |= BLOCK_STATUS_RESERVED;
    }
    OALMSG(ZONE_FMD_OPS,(TEXT("[INFO FMD_GetBlockStatus]:blockID = 0x%x,dwStatus = 0x%x\r\n"), ulBlock, dwStatus));

    return dwStatus;

}

/*******************************************************************************
  Function:     FMD_SetBlockStatus
  Description:  本接口用于写块状态
  Input:        1、待操作块地址
                2、待操作块状态
  Output:       none
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    DWORD ret = 0;
    DWORD ulBlock = g_stFlashChipInfo.pBaseAddress/g_stFlashChipInfo.BlockSize + blockID;

    /* 只支持设置为坏块 */
    if(BLOCK_STATUS_BAD != dwStatus)
    {
        return FALSE;
    }

    /*调用NF_PageRead读取块信息;*/
    ret = NF_PageRead(ulBlock*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                      g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:NF_PageRead Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }
    /*调用BMM_TranslateInfo转换SpareArea到SECTOR信息各标志位;*/
    ret = BMM_TranslateInfo(&(g_stFlashChipInfo.stSectorInfo),g_stFlashChipInfo.pucSpareArea, SPAREAREA_TO_BLOCKINFO);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }
    /*块状态是坏块标志*/
    g_stFlashChipInfo.stSectorInfo.bBadBlock = 0x0;

    /*调用BMM_TranslateInfo转换SECTOR信息各标志位到SpareArea;*/
    memset(g_stFlashChipInfo.pucSpareArea, 0xFF, g_stFlashChipInfo.SpareSize);
    ret = BMM_TranslateInfo(&(g_stFlashChipInfo.stSectorInfo), g_stFlashChipInfo.pucSpareArea, BLOCKINFO_TO_SPAREAREA);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }

    /*调用NF_PageProgram写块的SpareArea;*/
    ret = NF_PageProgram(blockID*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                         g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)/*出现坏块*/
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:NF_PageProgram Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }

    /*调用NF_PageRead读取块信息;*/
    ret = NF_PageRead(ulBlock*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                      g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:NF_PageRead Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }
    /*调用BMM_TranslateInfo转换SpareArea到SECTOR信息各标志位;*/
    ret = BMM_TranslateInfo(&(g_stFlashChipInfo.stSectorInfo),g_stFlashChipInfo.pucSpareArea, SPAREAREA_TO_BLOCKINFO);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_SetBlockStatus]:BMM_TranslateInfo Error!ret = 0x%x\r\n"), ret));
        return FALSE;
    }

    if(0x0 != g_stFlashChipInfo.stSectorInfo.bBadBlock)
    {
        return FALSE;
    }

    return TRUE;

}

/*******************************************************************************
  Function:     FMD_EraseBlock
  Description:  本接口用于擦除一个指定块的内容
  Input:        待擦除块地址
  Output:       none
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_EraseBlock(BLOCK_ID blockID)
{
    volatile ULONG ulBlock = 0;
    BOOL bRetVal = TRUE;
    DWORD ret = 0;
    ulBlock = g_stFlashChipInfo.pBaseAddress/g_stFlashChipInfo.BlockSize + blockID;

    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD_EraseBlock]: NF_BlockErase ulBlock = 0x%x.\r\n"), ulBlock));

    ret = NF_BlockErase(ulBlock);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_EraseBlock]: NF_BlockErase ulBlock = 0x%x error = 0x%x\r\n"), ulBlock, ret));
        bRetVal = FALSE;
    }

    return bRetVal;
}

/*******************************************************************************
  Function:     FMD_PowerUp
  Description:  本接口用于完成FMD设备上电动作
  Input:        none
  Output:       none
  Return:      none
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
VOID  FMD_PowerUp(VOID)
{
    return;
}

/*******************************************************************************
  Function:     FMD_PowerDown
  Description:  本接口用于完成FMD设备下电动作
  Input:        none
  Output:       none
  Return:      none
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
VOID  FMD_PowerDown(VOID)
{
    return;
}

/*******************************************************************************
  Function:     FMD_OEMIoControl
  Description:  本接口用于写块状态
  Input:        1、IOCTL命令
                2、输入缓冲区指针
                3、输入缓冲区数据长度
                4、输出缓冲区指针
                5、输出缓冲区数据长度
  Output:       1、输出数据
                2、输出数据长度
  Return:      TRUE:操作成功;
                FALSE:操作不成功;
  History:
                1. Created by chenbiyao on 2006/04/09
                2. .....
*******************************************************************************/
BOOL  FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
                       PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD_OEMIoControl]: base = 0x%x,dwIoControlCode = 0x%x.\r\n"),IOCTL_FMD_GET_INTERFACE,dwIoControlCode));
    switch(dwIoControlCode)
    {
    case IOCTL_FMD_GET_INTERFACE:
    {
        if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
        {
            OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_OEMIoControl]: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
            return(FALSE);
        }

        PFMDInterface pInterface = (PFMDInterface)pOutBuf;
        pInterface->cbSize = sizeof(FMDInterface);
        pInterface->pInit = FMD_Init;
        pInterface->pDeInit = FMD_Deinit;
        pInterface->pGetInfo = FMD_GetInfo;
#if 0
        pInterface->pGetInfoEx = FMD_GetInfoEx;
#endif
        pInterface->pGetBlockStatus = FMD_GetBlockStatus;
        pInterface->pSetBlockStatus = FMD_SetBlockStatus;
        pInterface->pReadSector = FMD_ReadSector;
        pInterface->pWriteSector = FMD_WriteSector;
        pInterface->pEraseBlock = FMD_EraseBlock;
        pInterface->pPowerUp = FMD_PowerUp;
        pInterface->pPowerDown = FMD_PowerDown;
        pInterface->pGetPhysSectorAddr = FMD_GetPhysSectorAddr;
        //pInterface->pOEMIoControl = FMD_OEMIoControl;

        break;
    }
    default:
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD_OEMIoControl]: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
        return(FALSE);
    }

    return(TRUE);
}



BOOL CheckMT29FBadBlock(BLOCK_ID blockID)
{
    DWORD ret;

    /*调用NF_PageRead读取Block第一个page的SpareArea信息;*/
    ret = NF_PageRead(blockID*g_stFlashChipInfo.SectorsPerBlock*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                      g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR ReplaceBadBlockSign]: Unknown Block 0x%x status\r\n"), blockID));
        return TRUE;
    }

    if(0xFF != g_stFlashChipInfo.pucSpareArea[0])
    {
        return TRUE;
    }

    /*调用NF_PageRead读取Block第后一个page的SpareArea信息;*/
    ret = NF_PageRead(((blockID+1)*g_stFlashChipInfo.SectorsPerBlock-1)*NF_SECTOR_ADDR_SHIFT + g_stFlashChipInfo.SectorSize,
                      g_stFlashChipInfo.pucSpareArea, g_stFlashChipInfo.SpareSize);
    if(FMD_SUCCESS != ret)
    {
        OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR ReplaceBadBlockSign]: Unknown Block 0x%x status last page\r\n"), blockID));
        return TRUE;
    }

    if(0xFF != g_stFlashChipInfo.pucSpareArea[0])
    {
        return TRUE;
    }

    return FALSE;
}


BOOL CheckFlashFirstUse(void)
{
    BYTE  pcSector[MAX_PAGE_SIZE];
    DWORD dwFirstDword;

    // 如果第0个Block已经被使用
    if(FMD_ReadSector(0, pcSector, NULL, 1))
    {
        memcpy(&dwFirstDword, pcSector, sizeof(dwFirstDword));

        if(0xFFFFFFFF != dwFirstDword)
        {
            return FALSE;
        }
    }

    // 如果第1个Block已经被使用
    if(FMD_ReadSector(g_stFlashChipInfo.SectorsPerBlock, pcSector, NULL, 1))
    {
        memcpy(&dwFirstDword, pcSector, sizeof(dwFirstDword));

        if(0xFFFFFFFF != dwFirstDword)
        {
            return FALSE;
        }
    }

    return (FLASH_IS_NO_NV == CheckNV())?TRUE:FALSE;
}

/* replace MT29F2G16ABD nand flash bad block */
BOOL ReplaceBadBlockSign(void)
{
    DWORD ui;

    OALMSG(ZONE_FMD_OPS, ("[INFO ReplaceBadBlockSign] +\r\n"));

    if(FALSE == CheckFlashFirstUse())
    {
        return TRUE;
    }

    OALMSG(ZONE_FMD_OPS, ("[INFO ReplaceBadBlockSign] Flash is first use\r\n"));

    if(NULL == g_stFlashChipInfo.pfnCheckOrgBadBlock)
    {
        return TRUE;
    }

    for(ui=0; ui<g_stFlashChipInfo.TotalBlockNumbers; ui++)
    {
        //OALMSG(1, (TEXT("CHECK: Block 0x%x\r\n"), ui));

        if(g_stFlashChipInfo.pfnCheckOrgBadBlock(ui))
        {
            OALMSG(ZONE_FMD_ERR, ("[INFO ReplaceBadBlockSign]: Original find a bad block = 0x%x\r\n", ui));
            FMD_EraseBlock(ui);
            if(FALSE == FMD_SetBlockStatus(ui, BLOCK_STATUS_BAD))
            {
                OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR ReplaceBadBlockSign]: Original set bad 0x%x block error\r\n"), ui));
                return FALSE;
            }
        }
    }

    //dwTickCount = GetPassedMicSec(dwTickCount);

    //OALMSG(1, ("Check Flash Passed %d Time\r\n", dwTickCount));
    OALMSG(ZONE_FMD_OPS, ("[INFO ReplaceBadBlockSign] -\r\n"));

    return TRUE;
}


/*******************************************************************************
  Function:     CreateNv
  Description:  本接口用于创建NV项区域
  Input:        none
  Output:       NV区域信息
  Return:      TRUE/FALSE
  History:
                1. Created by c56450 on 2006/04/09
                2. .....
*******************************************************************************/
BOOL CreateNv(void)
{
    DWORD       i        = 0;
    DWORD       j        = 0;
    SectorInfo  stSectorInfo;

    OALMSG(ZONE_FMD_OPS, (TEXT("[INFO FMD]CreateNv : create a nv region.\r\n")));

    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]CreateNv : get block status find a bad block = %d.\r\n"), i));
            continue;
        }

        if(FMD_SUCCESS != NF_BlockErase(i))
        {
            OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]CreateNv :  NF_BlockErase find a bad block = %d.\r\n"), i));
            FMD_SetBlockStatus(i, BLOCK_STATUS_BAD);
            continue;
        }

        stSectorInfo.dwReserved1 = j;
        if(!FMD_WriteSector(i*g_stFlashChipInfo.SectorsPerBlock, NULL, &stSectorInfo, 1))
        {
            OALMSG(ZONE_FMD_ERR, (TEXT("[ERROR FMD]CreateNv : Error while FMD_WritePhySector, Sector = %d.\r\n"), i*g_stFlashChipInfo.SectorsPerBlock));
            FMD_SetBlockStatus(i, BLOCK_STATUS_BAD);
            continue;
        }

        g_stFlashChipInfo.dwNvAddr[j] = i;
        if(++j == NV_BLOCK_NUM)
        {
            g_stFlashChipInfo.bNvInitialFlag = TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -