📄 flashhelper.cpp
字号:
//---------------------------------------------------------------------------
// 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 + -