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

📄 flash.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  flash.c
//
//
#include <windows.h>
#include <blcommon.h>
#include <fmd.h>
#include <omap2420.h>
#include <bsp.h>

//------------------------------------------------------------------------------

ROMHDR * volatile const pTOC = (ROMHDR *)-1; 

//------------------------------------------------------------------------------
//
//  Function:  SetupCopySection
//
//  Copies image's copy section data (initialized globals) to the correct
//  fix-up location.  Once completed, initialized globals are valid. Optimized
//  memcpy is too big for X-Loader.
//
static BOOL SetupCopySection(ROMHDR *const pTOC)
{
    BOOL rc = FALSE;
    UINT32 loop, count;
    COPYentry *pCopyEntry;
    UINT8 *pSrc, *pDst;

    if (pTOC == (ROMHDR *const) -1) goto cleanUp;

    pCopyEntry = (COPYentry *)pTOC->ulCopyOffset;
    for (loop = 0; loop < pTOC->ulCopyEntries; loop++) {
        count = pCopyEntry->ulCopyLen;
        pDst = (UINT8*)pCopyEntry->ulDest;
        pSrc = (UINT8*)pCopyEntry->ulSource; 
        while (count-- > 0) *pDst++ = *pSrc++;
        count = pCopyEntry->ulDestLen - pCopyEntry->ulCopyLen;
        while (count-- > 0) *pDst++ = 0;
             
    }

    rc = TRUE;

cleanUp:    
    return rc;
}

//------------------------------------------------------------------------------

BOOL FlashMain(UINT32 offset, UINT32 size, VOID *pBuffer)
{
    BOOL rc = FALSE, ok;
    HANDLE hFMD = NULL;
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    SECTOR_ADDR sector, ix;
    BLOCK_ID block;
    UINT32 count, retry;


    // Setup global variables
    if (!SetupCopySection(pTOC)) goto cleanUp;

    // Initialize debug serial output
    OEMDebugInit();

    // Print information...
    OEMWriteDebugString(
        L"\r\nMicrosoft Windows CE NAND Flash Utility for OMAP2420 H4-Sample 1.0\r\n"
    );

    // Open FMD to access NAND
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL) goto cleanUp;

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) goto cleanUp;

    // First offset given 
    count = 0;
    block = 0;
    sector = 0;
    while (count < offset) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) == 0) {
            OEMWriteDebugString(L"!");
            count += flashInfo.dwBytesPerBlock;
        }
        block++;
        sector += flashInfo.wSectorsPerBlock;
    }

    // Now we are at block where we need start erase
    count = 0;
    while (count < size && block < flashInfo.dwNumBlocks) {
        
        // If block is bad, we have to offset it
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            sector += flashInfo.wSectorsPerBlock;
            OEMWriteDebugString(L"#");
            continue;
        }
       
        // Erase block
        retry = 0;
        do {
            ok = FMD_EraseBlock(block);
        } while (!ok && retry++ < 4);
        // When erase failed, mark block as bad and skip it
        if (!ok) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            sector += flashInfo.wSectorsPerBlock;
            OEMWriteDebugString(L"$");
            continue;
        }

        // Now write sectors
        ix = 0;
        while (ix < flashInfo.wSectorsPerBlock && count < size) {
            // Prepare sector info
            memset(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;
            // Write sector
            retry = 0;
            do {
                ok = FMD_WriteSector(
                    sector, (UCHAR*)pBuffer + count, &sectorInfo, 1
                );
            } while (!ok && retry++ < 4);
            // When write fail, break sector write loop
            if (!ok) break;

            // Read sector back - when this fail, exit
            if (!FMD_ReadSector(
                sector, (UCHAR*)pBuffer + count, &sectorInfo, 1
            )) {
                OEMWriteDebugString(L"*");
                goto cleanUp;
            }
            
            // Move to next sector
            count += flashInfo.wDataBytesPerSector;
            ix++;
            sector++;
            OEMWriteDebugString(L".");
        }            

        // When sector write failed, mark block as bad and move back
        if (!ok) {
            // First move back            
            count -= ix * flashInfo.wDataBytesPerSector;
            sector -= ix;
            // Mark block as bad 
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            sector += flashInfo.wSectorsPerBlock;
            OEMWriteDebugString(L"%");
            continue;
        }

        // We are done with block
        block++;
    }

    OEMWriteDebugString(L"\r\n");

    // Did we wrote all?
    rc = (count >= size);

    
cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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