📄 flash.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(§orInfo, 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, §orInfo, 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, §orInfo, 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 + -