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

📄 nand.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
        return(FALSE);
    }

    EdbgOutputDebugString("INFO: Writing IPL image to NAND (please wait)...\r\n");

    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    // Make sure IPL length does not exceed reserved NAND size
    if (dwLength > IMAGE_BOOT_IPLIMAGE_NAND_SIZE)
    {
        EdbgOutputDebugString("ERROR: IPL size exceeds reserved NAND region (size = 0x%x)\r\n", dwLength);
        return(FALSE);
    }

    // Calculate the physical block range for the IPL image
    startBlockID = IMAGE_BOOT_IPLIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_IPLIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    EdbgOutputDebugString("INFO: Erasing NAND flash blocks [0x%x - 0x%x].\r\n", startBlockID, endBlockID);
    
    // Erase range of NAND blocks reserved for IPL
    for (blockID = startBlockID; blockID < endBlockID; blockID++)
    {
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Erase the block...
        if (!FMD_EraseBlock(blockID))
        {
            EdbgOutputDebugString("ERROR: Unable to erase NAND flash block [0x%x].\r\n", blockID);
            return(FALSE);
        }
    }

    // Get cached image location
    pImage = OEMMapMemAddr(dwStartAddr, dwStartAddr);

    // Fill unused space with 0xFF
    memset(pImage + dwLength, 0xFF, (IMAGE_BOOT_IPLIMAGE_NAND_SIZE) - dwLength);

    EdbgOutputDebugString("INFO: Programming IPL image from flash cache address 0x%x, size = %d\r\n", pImage, dwLength);

    sectorInfo.dwReserved1 = 0xFFFFFFFF;
    sectorInfo.bOEMReserved = 0x00;
    sectorInfo.bBadBlock = 0xFF;    
    sectorInfo.wReserved2 = 0xFFFF;
    
    // Write IPL to NAND flash
    pSectorBuf = pImage;

    for (blockID = startBlockID; blockID < endBlockID; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
        
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_WriteSector(sectorAddr, pSectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("ERROR: Failed to update IPL.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }
    }
    
    // Read IPL from NAND flash to verify contents
    pSectorBuf = pImage + IMAGE_BOOT_IPLIMAGE_NAND_SIZE;

    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
        
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_ReadSector(sectorAddr, pSectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("ERROR: Failed to update IPL.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }
    }

    EdbgOutputDebugString("INFO: Verifying image.\r\n");

    if (memcmp(pImage, pImage + IMAGE_BOOT_IPLIMAGE_NAND_SIZE, IMAGE_BOOT_IPLIMAGE_NAND_SIZE) != 0)
    {
        EdbgOutputDebugString("ERROR: Failed to verify IPL.\r\n");
    }
    
    EdbgOutputDebugString("INFO: Update of IPL completed successfully.\r\n");

    return(TRUE);
}

//-----------------------------------------------------------------------------
//
//  Function:  NANDWriteNK
//
//  This function writes to NAND flash memory the OS image stored 
//  in the RAM file cache area.
//
//  Parameters:
//      dwStartAddr 
//          [in] Address in flash memory where the start of the downloaded 
//          OS image is to be written.
//
//      dwLength 
//          [in] Length of the OS image, in bytes, to be written to flash
//          memory.            
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDWriteNK(DWORD dwStartAddr, DWORD dwLength)
{
    FlashInfo flashInfo;
    LPBYTE pSectorBuf, pImage;
    SectorInfo sectorInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;
    UINT32 percentComplete, lastPercentComplete;


    // Check for NAND device availability
    //
    if (!g_bNandExist)
    {
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
        return(FALSE);
    }

    EdbgOutputDebugString("INFO: Writing NK image to NAND (please wait)...\r\n");

    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    // Make sure NK length does not exceed reserved NAND size
    if (dwLength > IMAGE_BOOT_NKIMAGE_NAND_SIZE)
    {
        EdbgOutputDebugString("ERROR: NK size exceeds reserved NAND region (size = 0x%x)\r\n", dwLength);
        return(FALSE);
    }

    // Calculate the physical block range for the NK image
    startBlockID = IMAGE_BOOT_NKIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_NKIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    EdbgOutputDebugString("INFO: Erasing NAND flash blocks [0x%x - 0x%x].\r\n", startBlockID, endBlockID);

    lastPercentComplete = 0;
    
    // Erase range of NAND blocks reserved for NK
    for (blockID = startBlockID; blockID < endBlockID; blockID++)
    {
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Erase the block...
        if (!FMD_EraseBlock(blockID))
        {
            EdbgOutputDebugString("ERROR: Unable to erase NAND flash block [0x%x].\r\n", blockID);
            return(FALSE);
        }
    }

    // Get cached image location
    pImage = OEMMapMemAddr(dwStartAddr, dwStartAddr);

    // Fill unused space with 0xFF
    memset(pImage + dwLength, 0xFF, (IMAGE_BOOT_NKIMAGE_NAND_SIZE) - dwLength);

    EdbgOutputDebugString("INFO: Programming NK image from flash cache address 0x%x, size = %d\r\n", pImage, dwLength);

    sectorInfo.dwReserved1 = 0xFFFFFFFF;
    sectorInfo.bOEMReserved = 0x00;
    sectorInfo.bBadBlock = 0xFF;    
    sectorInfo.wReserved2 = 0xFFFF;
    
    // Write NK to NAND flash
    pSectorBuf = pImage;
    lastPercentComplete = 0;

    for (blockID = startBlockID; blockID < endBlockID; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
        
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_WriteSector(sectorAddr, pSectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("ERROR: Failed to update NK.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }

        percentComplete =  100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);

        // If percentage complete has changed, show the progress
        if (lastPercentComplete != percentComplete)
        {
            lastPercentComplete = percentComplete;
            OEMWriteDebugByte('\r');
            EdbgOutputDebugString("INFO: Program is %d%% complete.", percentComplete);
        }

    }
    
    EdbgOutputDebugString("\r\nINFO: Reading image in NAND for verification.\r\n");

    // Read NK from NAND flash to verify contents
    pSectorBuf = pImage + IMAGE_BOOT_NKIMAGE_NAND_SIZE;
    lastPercentComplete = 0;

    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("\r\nINFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
        
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_ReadSector(sectorAddr, pSectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("\r\nERROR: Failed to update NK.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }

        percentComplete =  100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);

        // If percentage complete has changed, show the progress
        if (lastPercentComplete != percentComplete)
        {
            lastPercentComplete = percentComplete;
            OEMWriteDebugByte('\r');
            EdbgOutputDebugString("INFO: Read is %d%% complete.", percentComplete);
        }
    }

    EdbgOutputDebugString("\nINFO: Verifying image.\r\n");

    if (memcmp(pImage, pImage + IMAGE_BOOT_NKIMAGE_NAND_SIZE, IMAGE_BOOT_NKIMAGE_NAND_SIZE) != 0)
    {
        EdbgOutputDebugString("ERROR: Failed to verify NK.\r\n");
    }
    

    EdbgOutputDebugString("INFO: Update of NK completed successfully.\r\n");

    
    return(TRUE);

}

//------------------------------------------------------------------------------
//
//  Function:  IsSectorEmpty
//
//  N/A
//
//  Parameters:
//      None.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL IsSectorEmpty(UCHAR *pData, ULONG sectorSize, SectorInfo *pSectorInfo)
{
    BOOL rc = FALSE;
    ULONG idx;

    if (pSectorInfo->dwReserved1 != 0xFFFFFFFF) goto cleanUp;
    if (pSectorInfo->wReserved2 != 0xFFFF) goto cleanUp;
    if (pSectorInfo->bOEMReserved != 0xFF) goto cleanUp;

    for (idx = 0; idx < sectorSize; idx++)
    {
        if (pData[idx] != 0xFF) 
            goto cleanUp;
    }      

    rc = TRUE;

cleanUp:
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  NANDStartWriteBinDIO
//
//  N/A
//
//  Parameters:
//      None.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDStartWriteBinDIO(DWORD dwStartAddr, DWORD dwLength)
{
    BLOCK_ID blockID, startBlockID, endBlockID;
    UINT32 percentComplete, lastPercentComplete = 0;
    
    // Check for NAND device availability
    //
    if (!g_bNandExist)
    {

⌨️ 快捷键说明

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