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

📄 flashhelper.cpp

📁 PW芯片方案Flash ROM烧写程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//---------------------------------------------------------------------------
// Pixelworks Inc. Company Confidential Strictly Private
//
// $Archive: /SwTools/FlashUpgrader/FlashHelper.cpp $
// $Revision: 1.5 $
// $Author: ckerchner $
// $Date: 2005/03/24 00:35:23 $
//
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Copyright 1997 (c) Pixelworks Inc.
//
// Pixelworks owns the sole copyright to this software. Under international 
// copyright laws you (1) may not make a copy of this software except for 
// the purposes of maintaining a single archive copy, (2) may not derive
// works herefrom, (3) may not distribute this work to others. These rights 
// are provided for information clarification, other restrictions of rights 
// may apply as well.
//
// This is an unpublished work.
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>>>>> WARRANTEE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Pixelworks Inc. MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE USE OF
// THIS SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE.
// --------------------------------------------------------------------------

#include "stdafx.h"
#include "FlashHelper.h"

//#define OLD_FLASH_BLOCKHEADER

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//----------------------------------------------------------------------------
// X-Modem protocol definitions
//----------------------------------------------------------------------------

#define CHECKSUM_ID_CHAR            ('C')
#define CHECKSUM_ID_CHAR_1K			('D')

#define XMODEM_TIMEOUT_SEC          (10)

#define CANCEL_DOWNLOAD_TIMEOUT     (5 * 5000)

#define RESPONSE_STRING_TIMEOUT_MS  (3000)

// X-Modem protocol command characters
#define SOH_CHAR	(0x01)
#define STX_CHAR    (0x02)
#define EOT_CHAR	(0x04)
#define ACK_CHAR	(0x06)
#define	NAK_CHAR	(0x15)
#define CAN_CHAR	(0x18)

static bool g_bHaveBlockSize = FALSE;

//----------------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------------
CFlashHelper::CFlashHelper()
{
    m_pCallback = NULL;
    
    m_pComPortCmd = NULL;

    m_pFlashData = NULL;
    m_nFlashDataSize = 0;

    m_hThread = 0;
    m_hCancelEvent = INVALID_HANDLE_VALUE;
    m_bCanceled = FALSE;

    m_eLastError = feOK;
}

//----------------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------------
CFlashHelper::~CFlashHelper()
{
    CancelOperation();

    ::CloseHandle(m_hCancelEvent);
    m_hCancelEvent = INVALID_HANDLE_VALUE;

    DeleteHeapObjects();
}

//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
LPCSTR CFlashHelper::GetLastReturnedTargetMessage() const
{
    return (LPCSTR)m_strReturnedMsg;
}

//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
LPCSTR CFlashHelper::GetLastError() const
{
    if (feOK == m_eLastError || m_strLastErrorMsg.IsEmpty())
    {
        return NULL;
    }

    return m_strLastErrorMsg;
}

//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
void CFlashHelper::SetLastError(eFLASHERROR eError)
{
    ASSERT(feOK == m_eLastError);

    m_eLastError = eError;

    CString strError;
    switch (eError)
    {
        case feOK:
            strError.Empty();
        break;

        case feFLASHFILE_NOTFOUND:
            strError = "Unable to find the file";
        break;

        case feFLASHFILE_FORMAT_ERROR:
            strError = "Error occured while parsing the file";
        break;

        case feFLASHFILE_EXPECTED_INTEL80_ERROR:
            strError = "The file must be in Intel80 format";
        break;

        case feTARGET_ERROR_MESSAGE:
            if (m_strReturnedMsg.IsEmpty())
            {
                strError = "Unknown error occured in target system";
            }
            else
            {
                strError = m_strReturnedMsg;
            }
        break;

        case feFLASH_CANCELED:
            strError = "Error occured while downloading firmware to target";
        break;

        case feAPP_ERROR:
        default:
            strError.Format("Unknown error occured: %d", (int)eError);
    }

    m_strLastErrorMsg = strError;
}

//----------------------------------------------------------------------------
// Begin flash download.
//
// Params:
//  pCallback   : Pointer to event callback procedure downloader thread uses
//                to notify object of download status.
//  pFileItem   : Pointer to file item structure of file to download.
//  pnTotalSize : Pointer to returned size of binary data being downloaded.
//  lpszReturn  : Pointer to string returned on successfull download from
//                target.
//
// Return: Enumerated status code.
//
// Notes:
//----------------------------------------------------------------------------
eFLASHERROR CFlashHelper::BeginFlashDownload(const PFLASHCALLBACK pCallback,
                                             CComPortCmd *pComPortCmd,
                                             const PFILE_ITEM pFileItem,
                                             int *pnTotalSize,
											 bool bResetConnection)
{
	int nSleepCount = 10;
    CMakeSafe ms(&m_Safe);      // Make following code thread-safe

    m_bCanceled = FALSE;        // clear operation canceled flag

    m_eLastError = feOK;        // clear last error state (do to avoid ASSERT)
    SetLastError(feOK);         // clear last error text
    m_strReturnedMsg.Empty();   // clear last message returned from target

    while (m_hThread)
    {
		if (0 == --nSleepCount)
		{
			TRACE("Already downloading a file\n");
			ASSERT(0);
			AfxMessageBox("box 1");

			SetLastError(feAPP_ERROR);
			return feAPP_ERROR;     // return internal application error to caller
		}
		Sleep(500);
    }


    ASSERT(pComPortCmd);
    m_pComPortCmd = pComPortCmd;

	if (bResetConnection)
	{
		if (m_pComPortCmd->m_eComm == ccUSB)
		{
			// Since the target was essentially rebooted, we need
			// to reset the USB connection.
			// Sleep(5000);
			if (!m_pComPortCmd->SetComPort(-1))
			{
				return feAPP_ERROR;
			}
			g_bHaveBlockSize = FALSE;
		}
	}

    if (INVALID_HANDLE_VALUE == m_hCancelEvent)
    {
        // Create an auto-reset event.
        m_hCancelEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (INVALID_HANDLE_VALUE == m_hCancelEvent)
        {
            SetLastError(feAPP_ERROR);
            return feAPP_ERROR;     // return internal application error to caller
        }
    }

    DeleteHeapObjects();        // Ensure that old heap objects are deleted

    ASSERT(pCallback);          // Validate that callback procedure exist
    m_pCallback = pCallback;    // save pointer

    ASSERT(NULL == m_pFlashData);   // Valid that old flash data doesn't exist

    // Convert flash source data into binary format that the target uses.
    eFLASHERROR eStatus = GetFlashData(pFileItem, &m_pFlashData,
                           &m_nFlashDataSize);

	if (bResetConnection && (m_pComPortCmd->m_eComm == ccUSB))
	{
		Sleep(500);
	}

    if (feOK == eStatus)
    {
        DWORD dwThreadId = 0;

        // Create thread that is used to download the binary data to the target.
        m_hThread = ::CreateThread(
                NULL,	        // pointer to thread security attributes
                0,	            // initial thread stack size, in bytes (0= use same)
                ThreadProc,	    // pointer to thread function
                this,           // argument for new thread
                0,  	        // creation flags
                &dwThreadId);

        if (0 == m_hThread)
        {
            TRACE("CreateThread failed\n");
            eStatus = feAPP_ERROR;
        }
    }

    if (feOK == eStatus)
    {
        *pnTotalSize = m_nFlashDataSize;    // setup returned size of data to download
    }
    else
    {
        DeleteHeapObjects();                // Error occured. Delete heap objects.
    }

    SetLastError(eStatus);

    return eStatus;
}

//----------------------------------------------------------------------------
// Cancel the current download operation.
//
// Params: none
//
// Return: TRUE= Download successfully cancel, FALSE= unable to cancel
//         download operation.
//
// Notes:
//----------------------------------------------------------------------------
BOOL CFlashHelper::CancelOperation()
{
    BOOL bRet = TRUE;

    m_bCanceled = TRUE;

    if (m_hCancelEvent)
    {
        CMakeSafe ms(&m_Safe);      // Make following code thread-safe

        //--------------------------------------------------------------------
        // If downloader thread exist then we need to signal it to die.
        //--------------------------------------------------------------------
        if (m_hThread)
        {
            // We need to signal CComPortCmd to cancel the current operation.
            // This will cause our thread to die too.
            SetEvent(m_hCancelEvent);

            // Wait for thread to die before exiting this method.
            int nStatus = WaitForSingleObject(m_hThread, CANCEL_DOWNLOAD_TIMEOUT);
            if (WAIT_TIMEOUT == nStatus)
            {
                BOOL bRet = FALSE;  // Timed-out waiting for thread to die
            }
        }
    }

    return bRet;                    // return status
}

//----------------------------------------------------------------------------
// Convert source data into downloadable binary data that target uses.
//
// Params:
//  pFileItem : Pointer to file item structure of file to download.
//  ppData    : Pointer to returned pointer to binary data.
//  pSize     : Pointer to returned size of binary data to download.
//
// Return: Enumerated status code.
//
// Notes: Data will be read into a buffer created on the heap and converted
// into the following binary format:
//
//   Byte
//  Offset                 Data
// ---------- --------------------------------------
// 0000     : Flash flags (see FlashDef.h)
// 0001-0002: Execution start address IP. Note: if CS:IP = 0000:0000, then
//            don't execute.
// 0003-0004: Execution start address CS.
//
// Start of first block.
// 0005-0006: Block offset (Word).
// 0007-0008: Block segment (Word).
// 0009-000C: Block size (DWord, 32-bits). Use Zero as end of binary data marker.
// 000D-001C: Filename
// 001D-xxxx: Start of data.
//
// Start of next block
// xxxx: Block offset (word).
// xxxx: Block segment (word).
//  ..   etc.
//  ..   etc.
//----------------------------------------------------------------------------
eFLASHERROR CFlashHelper::GetFlashData(const PFILE_ITEM pFileItem, BYTE **ppData,
                                       int *pSize)
{
    eFLASHERROR eRet = feOK;

    CFile file;
    if (FALSE == file.Open(pFileItem->strPath, CFile::modeRead | CFile::typeBinary))
    {
        return feFLASHFILE_NOTFOUND;
    }

    DWORD dwSize = file.GetLength();            // get length of source file
    DWORD dwBufferSize = dwSize;                // buffer size

    if (ftBinary == pFileItem->eType)
    {
#ifdef OLD_FLASH_BLOCKHEADER
        dwBufferSize += (12 * 2);               // 28 bytes for begin & end packets
#else
        dwBufferSize += (28 * 2);               // 28 bytes for begin & end packets
#endif
        pFileItem->cFlashFlags |= BINARY_FILE;

⌨️ 快捷键说明

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