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

📄 flashhelper.cpp

📁 PW芯片方案Flash ROM烧写程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }

    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 + -