📄 flashhelper.cpp
字号:
}
BYTE *pBuffer = new BYTE[dwBufferSize]; // create buffer for source data
if (dwSize != file.Read(pBuffer, dwSize)) // read data into buffer
{
eRet = feFLASHFILE_READ_ERROR;
}
file.Close();
if (feOK == eRet)
{
//--------------------------------------------------------------------
// Convert source data to binary downloadable data, creating a new
// buffer for the binary data (pointed to by ppData).
//
// Note: When done with the binary data, the caller is responsible for
// deleting the memory space.
//--------------------------------------------------------------------
if (ftText == pFileItem->eType)
{
// Text Format
eRet = TextToBinaryChunks(pFileItem, pBuffer, dwSize, ppData, pSize);
}
else if (ftBinary == pFileItem->eType)
{
// Binary Format
eRet = BinaryToBinaryChunks(pFileItem, pBuffer, dwSize, ppData, pSize);
}
else
{
// Hex Format
eRet = ConvertToBinaryChunks(pFileItem, pBuffer, dwSize, ppData, pSize);
}
}
if (pBuffer)
{
delete pBuffer; // delete source file buffer
pBuffer = NULL;
}
return eRet;
}
//----------------------------------------------------------------------------
// Convert Text file data to downloadable binary data.
//
// Params:
// pFileItem : Pointer to file item structure of file to download.
// pData : Pointer to source file data.
// nDataSize : Byte size of source data.
// ppBinary : Pointer to returned pointer to created binary data.
// pnSize : Pointer to returned size of created binary data.
//
// Return: Enumerated status code.
//
// Notes: Text format is used for EDID programming. Format is a series of
// Ascii hex data byte values. Address starts at 0. example
// 33 54 8e df 7e
//
//----------------------------------------------------------------------------
eFLASHERROR CFlashHelper::TextToBinaryChunks(const PFILE_ITEM pFileItem,
const BYTE *pData, int nDataSize,
BYTE **ppBinary, int *pnSize)
{
eFLASHERROR eRet = feOK; // setup returned status code
*ppBinary = NULL; // clear returned pointers
*pnSize = 0;
BYTE *pcBuffer = new BYTE[nDataSize + 12 + 8]; // approximate maximum size
BYTE *pcDest = pcBuffer; // setup destination pointer
const BYTE *pInput = pData;
const BYTE *pEnd = pData + nDataSize;
int nTemp;
DWORD *pdwCurrentSize = NULL;
//------------------------------------------------------------------------
// Note: The boot loader code ignores the start address and assumes that
// the start address is the start of the data downloaded.
//------------------------------------------------------------------------
*pcDest = pFileItem->cFlashFlags; // setup flash file flags
pcDest++;
*((DWORD*)pcDest) = 0; // set CS:IP starting address to zero
pcDest += 4; // bump destination pointer
// Create a block header in the destination binary.
*((WORD*)pcDest) = 0; // set offset = 0
*((WORD*)(pcDest + 2)) = 0; // set segment = 0
pcDest += 4; // bump destination
pdwCurrentSize = (DWORD*)pcDest; // hold pointer to size
*pdwCurrentSize = 0; // clear size
pcDest += 4; // bump destination
while (-1 != (nTemp = GetByte(pInput, pEnd)))
{
*pcDest++ = (BYTE)nTemp;
++(*pdwCurrentSize);
}
// TESTING
ZeroMemory((LPVOID)pcDest, 8);
pcDest += 8;
*ppBinary = pcBuffer; // set returned start address
*pnSize = pcDest - pcBuffer; // set returned size
return eRet; // return status
}
//----------------------------------------------------------------------------
// Convert Binary file data to downloadable binary data.
//
// Params:
// pFileItem : Pointer to file item structure of file to download.
// pData : Pointer to source file data.
// nDataSize : Byte size of source data.
// ppBinary : Pointer to returned pointer to created binary data.
// pnSize : Pointer to returned size of created binary data.
//
// Return: Enumerated status code.
//
// Notes: Text format is used for EDID programming. Format is a series of
// Ascii hex data byte values. Address starts at 0. example
// 33 54 8e df 7e
//
//----------------------------------------------------------------------------
eFLASHERROR CFlashHelper::BinaryToBinaryChunks(const PFILE_ITEM pFileItem,
const BYTE *pData, int nDataSize,
BYTE **ppBinary, int *pnSize)
{
eFLASHERROR eRet = feOK; // setup returned status code
*ppBinary = NULL; // clear returned pointers
*pnSize = 0;
BYTE *pcBuffer = new BYTE[nDataSize + 29 + 9]; // approximate maximum size
BYTE *pcDest = pcBuffer; // setup destination pointer
const BYTE *pInput = pData;
DWORD *pdwCurrentSize = NULL;
//------------------------------------------------------------------------
// Note: The boot loader code ignores the start address and assumes that
// the start address is the start of the data downloaded.
//------------------------------------------------------------------------
*pcDest = pFileItem->cFlashFlags; // setup flash file flags
pcDest++;
*((DWORD*)pcDest) = 0; // set CS:IP starting address to zero
pcDest += 4; // bump destination pointer
// Create a block header in the destination binary.
*((WORD*)pcDest) = 0; // set offset = 0
*((WORD*)(pcDest + 2)) = 0; // set segment = 0
pcDest += 4; // bump destination
pdwCurrentSize = (DWORD*)pcDest; // hold pointer to size
*pdwCurrentSize = nDataSize; // set size
pcDest += 4; // bump destination
#ifndef OLD_FLASH_BLOCKHEADER
strncpy((char *)(pcDest), (const char *)(pFileItem->strPath), 16);
pcDest += 16; // bump destination
#endif
MoveMemory((LPVOID)pcDest, (const VOID *)pInput, nDataSize);
pcDest += nDataSize;
// TESTING
ZeroMemory((LPVOID)pcDest, 8);
pcDest += 8;
*ppBinary = pcBuffer; // set returned start address
*pnSize = pcDest - pcBuffer; // set returned size
return eRet; // return status
}
int CFlashHelper::HexDigit(char chr)
{
if (chr >= '0' && chr <= '9')
return (chr - '0');
if (chr >= 'A' && chr <= 'F')
return (10 + chr - 'A');
if (chr >= 'a' && chr <= 'f')
return (10 + chr - 'a');
else
return -1;
}
int CFlashHelper::GetByte(const BYTE * & pInput, const BYTE * pEnd)
{
int nResult = -1;
while ((pInput < pEnd) && (-1 == HexDigit(*pInput)))
++pInput;
if (pInput >= pEnd)
return -1;
nResult = HexDigit(*pInput);
++pInput;
if (pInput >= pEnd)
return nResult;
if (-1 != HexDigit(*pInput))
{
nResult = nResult * 16 + HexDigit(*pInput);
++pInput;
}
return nResult;
}
//----------------------------------------------------------------------------
// Convert Intel hex source file data to downloadable binary data.
//
// Params:
// pFileItem : Pointer to file item structure of file to download.
// pData : Pointer to source file data.
// nDataSize : Byte size of source data.
// ppBinary : Pointer to returned pointer to created binary data.
// pnSize : Pointer to returned size of created binary data.
//
// Return: Enumerated status code.
//
// Notes: Supports Intel80 HEX and Intel-Extended HEX source file formats.
//----------------------------------------------------------------------------
eFLASHERROR CFlashHelper::ConvertToBinaryChunks(const PFILE_ITEM pFileItem,
const BYTE *pData, int nDataSize,
BYTE **ppBinary, int *pnSize)
{
*ppBinary = NULL; // clear returned pointers
*pnSize = 0;
BYTE *pcBuffer = new BYTE[nDataSize / 2 + 5]; // approximate maximum size
BYTE *pcDest = pcBuffer; // setup destination pointer
BYTE *pcFlashFlags = pcDest; // remember the flash flags address, this may get set later
//------------------------------------------------------------------------
// Note: The boot loader code ignores the start address and assumes that
// the start address is the start of the data downloaded.
//------------------------------------------------------------------------
*pcDest = pFileItem->cFlashFlags; // setup flash file flags
pcDest++;
*((DWORD*)pcDest) = 0; // set CS:IP starting address to zero
pcDest += 4; // bump destination pointer
BOOL bAddressSet = FALSE; // clear header block created flag
BOOL bLinearAddress = FALSE;
DWORD *pdwCurrentSize = NULL; // zero returned binary size
BYTE cLineDataArray[256]; // setup array for a HEX line of binary data
BYTE cLineDataSize; // setup number of valid bytes in array
//
// If we parse and 04 (Extended Linear Address Record), then we need to shift
// the segement address by 16 bits. For 02 records, shift by 4 bits.
//
#define SEG_SHIFT (bLinearAddress?16:4)
//------------------------------------------------------------------------
// For now, we can assume all source files will be in Intel Extended Hex
// format (either intel80 or intel86 - extended format).
//
// Note: The boot loader code assumes that the data is one continious
// block and should be in the intel80 file format. It uses the wSegment
// and wOffset as the execution address and download starting address.
// Boot loaders should always be downloaded into RAM.
//------------------------------------------------------------------------
WORD wSegment = 0; // (Intel extended hex starting address is 0)
WORD wOffset = 0; // set starting base offset to zero
if (pFileItem->eType == ftHex80)
{
// Source file is not in Intel-Extended hex format. We must obtain the
// segment base address from the file item object.
wSegment = pFileItem->wIntelSegment;
}
// Setup starting physical destination address of binary data.
DWORD dwPhysicalAddress = (DWORD)(wSegment << SEG_SHIFT) + wOffset;
eFLASHERROR eRet = feOK; // setup returned status code
BOOL bEOF = FALSE; // setup EOF flag
// Process entire source file unless an error occurs.
while (nDataSize && (feOK == eRet) && (FALSE == bEOF))
{
eRECORDTYPE eRecordType;
// Parse and convert one line from the Intel Hex file to binary format.
if (FALSE == ParseIntelExtendedHexLine((char**)&pData, &nDataSize,
&wOffset, &eRecordType, cLineDataArray, &cLineDataSize))
{
eRet = feFLASHFILE_FORMAT_ERROR;
break;
}
switch (eRecordType) // switch on Intel Hex record type
{
case rtDATA:
//------------------------------------------------------------
// If this data record doesn't fit at the end of our current
// destination then we need to either add pad bytes or create
// a new block header.
//------------------------------------------------------------
if ((DWORD)(wSegment << SEG_SHIFT) + wOffset != dwPhysicalAddress)
{
if (pFileItem->eType == ftHex80)
{
// Source is Intel80 Hex. We only want 1 block header
// at the start of the binary so we must add pad bytes
// here.
DWORD dwPadSize = ((DWORD)(wSegment << SEG_SHIFT) + wOffset) - dwPhysicalAddress;
FillMemory((void*)pcDest, dwPadSize, 0xff);
pcDest += dwPadSize; // bump destination pointer
*pdwCurrentSize += dwPadSize; // bump current block's size
dwPhysicalAddress += dwPadSize; // bump physical address
}
else
{
// Source is Extended-Intel Hex. It is ok to create a
// new block header.
bAddressSet = FALSE;
}
}
//------------------------------------------------------------
// Check if we need to put a block header in the destination
// binary.
//------------------------------------------------------------
if (FALSE == bAddressSet)
{
if (pdwCurrentSize)
{
// TRACE("Size= %d\n", *pdwCurrentSize);
}
// TRACE("Block Header: %04X:%04X ", wSegment, wOffset);
// Create a block header in the destination binary.
*((WORD*)pcDest) = wOffset; // set offset
*((WORD*)(pcDest + 2)) = wSegment; // set segment
pcDest += 4; // bump destination
pdwCurrentSize = (DWORD*)pcDest; // hold pointer to size
*pdwCurrentSize = 0; // clear size
pcDest += 4; // bump destination
// Set new physical starting address.
dwPhysicalAddress = (DWORD)(wSegment << SEG_SHIFT) + wOffset;
bAddressSet = TRUE; // set header created flag
}
// Copy file data to binary destination.
CopyMemory((void*)pcDest, (void*)cLineDataArray, cLineDataSize);
pcDest += cLineDataSize; // bump destination pointer
*pdwCurrentSize += cLineDataSize; // bump current block's size
dwPhysicalAddress += cLineDataSize; // bump physical address
break;
case rtEOF:
bEOF = TRUE;
break;
case rtEXTENDED_ADDRESS:
if (pFileItem->eType == ftHex80)
{
// File must be in Intel80 hex format (not extended format).
return feFLASHFILE_EXPECTED_INTEL80_ERROR;
}
if (2 != cLineDataSize)
{
eRet = feFLASHFILE_FORMAT_ERROR;
}
else
{
// First byte is high byte of segment.
wSegment = (cLineDataArray[0] << 8) | cLineDataArray[1];
bLinearAddress = FALSE;
bAddressSet = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -