📄 flashupgraderdlg.cpp
字号:
if (FALSE == ValidateROMFiles())
{
return FALSE;
}
UpdateData();
return TRUE;
}
BOOL CFlashUpgraderDlg::BeginFlashProcess()
{
UpdateData();
//
// Clear the selected states for all items in the list control.
//
for (int i=0; i<m_listRegions.GetItemCount(); i++)
{
m_listRegions.SetItemState(i, 0,LVIS_FOCUSED|LVIS_SELECTED);
}
//
// First save off the current settings in the registry...
//
// 2. Connection
// 3. COM Port
// 4. Baud Rate
//
CString strKey;
strKey.LoadString(IDS_REGKEY_BASE);
CString strValueName;
CString strValue;
strValueName.LoadString(IDS_REGVALUE_CONNECTION);
strValue = m_strConnection;
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
strValueName.LoadString(IDS_REGVALUE_VERIFYONLY);
strValue = m_bVerifyOnly?"true":"false";
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
strValueName.LoadString(IDS_REGVALUE_NOTIFY);
strValue = m_bNotify?"true":"false";
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
strValueName.LoadString(IDS_REGVALUE_CONTINUOUS);
strValue = m_bContinuous?"true":"false";
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
strValueName.LoadString(IDS_REGVALUE_RESETTIME);
strValue.Format("%d", m_nResetTime);
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
// Only save the COM port setting if this is the first (or only) instance of
// FlashUpgrader.
if (m_bFirstInstance)
{
strValueName.LoadString(IDS_REGVALUE_COMPORT);
strValue = m_strComPort;
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
}
strValueName.LoadString(IDS_REGVALUE_BAUDRATE);
strValue = m_strBaudRate;
gSetValueInRegistry(HKEY_CURRENT_USER, strKey, strValueName, (LPCSTR)strValue);
//
// Tell the user if there are conflicts detected. Ask is we should continue.
//
if (m_bConflicts)
{
CString strMsg = "There are conflicts in the hex files. Are\n";
strMsg += "you sure you want to flash the target?";
if (AfxMessageBox(strMsg, MB_YESNO) == IDNO)
{
return FALSE;
}
}
//#define SIMULATE
#ifdef SIMULATE
//
// Simulated Flash
//
AfxMessageBox("Shazamm!!!", MB_OK);
//
// While simulating, remember to re-enable the controls or we
// won't be able to simulate again.
//
return TRUE;
#endif
//
// Validate the INF file and the ROM files to ensure that everything is
// OK to proceed.
//
if (!ValidateInfFile())
{
//
// There was a problem detected. Tell the user.
//
AfxMessageBox("INF File Invalid", MB_OK);
return FALSE;
}
m_eState = psNONE;
m_strFileName = "Waiting for target reset...";
UpdateData(FALSE);
if (!BeginDownloadingFirmware()) return FALSE;
return TRUE;
}
static int nFileCounter = 0;
static bool bResetTarget = FALSE;
static bool bLastFileWasExe = FALSE;
static CString LastFile;
static CString ThisFile;
BOOL CFlashUpgraderDlg::BeginDownloadingFirmware()
{
m_eState = psNONE;
m_nCurrentFileNum = 0; // set starting file number
m_ctrlProgress.SetPos(0);
// Open COM port
CreateComPort();
CComPortCmd *pComPort = GetComPortCmdPtr();
BOOL bStatus = TRUE;
pComPort->SetBaudRate(m_nBaudRate);
if (m_nComPort == -1)
{
pComPort->m_eComm = ccUSB;
}
if (m_nComPort > -1 /* Not USB */)
{
if (!m_bFirstTime)
{
Sleep(500);
}
m_bFirstTime = FALSE;
bStatus = pComPort->SetComPort(m_nComPort + 1);
}
if (FALSE == bStatus)
{
CString strError;
strError.Format("Unable to open the specified port. Ensure that\n no other application or device driver is using it.");
DisplayErrorMsg(strError);
}
else
{
bResetTarget = FALSE;
nFileCounter = 0;
bStatus = DownloadNextFile();
}
if (FALSE == bStatus)
{
m_eState = psNONE;
}
return bStatus;
}
BOOL CFlashUpgraderDlg::CreateComPort()
{
if (m_pComPort)
delete m_pComPort;
m_pComPort = new CComPortCmd;
return m_pComPort->Create(this);
}
CComPortCmd* CFlashUpgraderDlg::GetComPortCmdPtr()
{
return m_pComPort;
}
void CFlashUpgraderDlg::DisplayErrorMsg(LPCSTR pstrMsg)
{
CString strError(pstrMsg);
BOOL bDisplayFilename = TRUE;
if (strError.IsEmpty())
{
strError = m_FlashHelper.GetLastReturnedTargetMessage();
}
CString strMsg;
if (strError.IsEmpty())
{
strMsg = "An unknown error occured.";
}
else
{
strMsg.Format("The following error occured:\n\n%s.", strError);
}
if (FALSE == m_fileItem.strPath.IsEmpty())
{
CString cstrTmp;
cstrTmp.Format("\n\nFile being downloaded:%s", m_fileItem.strPath);
strMsg += cstrTmp;
}
strMsg += "\n\nFlash download operation aborted.";
MessageBox(strMsg, "Error", MB_OK | MB_ICONEXCLAMATION);
}
BOOL CFlashUpgraderDlg::DownloadNextFile()
{
if (m_bCancel)
{
return FALSE; // operation canceled by user
}
//
// Mark the list control item to idicate that it is being downloaded.
//
if (m_nCurrentFileNum>0)
{
m_listRegions.SetItemState(m_nCurrentFileNum-1, LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED);
m_listRegions.SetFocus();
}
BOOL bGetNextFile = TRUE;
while (bGetNextFile)
{
if (FALSE == GetFirmwareFileItem(m_nCurrentFileNum, &m_fileItem))
{
return FALSE; // Done, no more files to download.
}
CHexFileData* pHexFile = GetHexFileData(m_fileItem.strPath);
if (pHexFile != NULL)
{
if (!pHexFile->m_bDownload || pHexFile->m_bMissing)
{
//
// Don't downlod this file...
//
m_nCurrentFileNum++;
}
else
{
bGetNextFile = FALSE;
}
}
m_pCurHexFile = pHexFile;
}
g_strFileName = pTheApp->GetFilename((LPCSTR)m_fileItem.strPath);
//
// Reset progress bar to start.
//
m_ctrlProgress.SetPos(0);
m_ctrlProgress.SetStep(1);
m_ctrlProgress.SetRange(0, 100);
CMakeSafe ms(&m_Safe); // make following block thread-safe
m_nTotalSize = 0; // set total file size to zero
m_nTransferedSize = 0; // set transfered data size to zero
m_eState = psPENDING; // setup current state to download pending
bResetTarget = bLastFileWasExe;
bLastFileWasExe = (0 == (m_fileItem.cFlashFlags & DISABLE_CODE_EXECUTION));
nFileCounter++;
CComPortCmd *pComPort = GetComPortCmdPtr();
if (bResetTarget && GetComPortCmdPtr() != NULL && GetComPortCmdPtr()->m_eComm == ccUSB)
{
// If this is the second file (implying that flasher.hex was the first file),
// and we're using USB, then sleep for a few seconds to give the target time
// to reset and begin enumerating the USB device before we try to establish
// a connection.
pComPort->CloseComPort();
int nDelay = 8000;
int nSteps = 100;
int nStep = nDelay/nSteps;
int nTmp;
CString cStr;
CString cPct;
cStr.Format("Delay %dms for target reset...", nDelay);
g_pFileLabel->SetWindowText(cStr);
m_pThis->m_ctrlProgress.SetRange(0, nSteps);
m_pThis->m_ctrlProgress.SetPos(0);
for (nTmp=0; nTmp<nSteps; nTmp++)
{
cPct.Format("%dms", (nTmp*nStep));
g_pPercentLabel->SetWindowText(cPct);
m_pThis->m_ctrlProgress.StepIt();
Sleep(nStep);
}
}
#ifdef BUILD_USB_CONFIG
if (GetComPortCmdPtr() != NULL && GetComPortCmdPtr()->m_eComm == ccUSB &&
GetComPortCmdPtr()->m_pUsb == NULL)
{
if (!pComPort->SetComPort(-1))
{
return FALSE;
}
}
#endif
eFLASHERROR eStatus;
// Using Flash Helper Object, start download operation.
eStatus = m_FlashHelper.BeginFlashDownload(
&CallbackProc, // pointer to static callback procedure
GetComPortCmdPtr(), // pointer to CComPortCmd object
&m_fileItem, // pointer to FILE_ITEM structure
&m_nTotalSize, // pointer to returned byte size of data to download
bResetTarget); // is the current file the flash executable
if (feOK != eStatus)
{
m_eState = psERROR; // set current state to error condition
if (feAPP_ERROR == eStatus)
{
DisplayErrorMsg("Could not open USB device.");
}
else
{
DisplayErrorMsg(); // display error dialog
}
return FALSE; // FALSE= download operation failed to start.
}
return TRUE; // TRUE= download operation successfully started.
}
BOOL CFlashUpgraderDlg::GetFirmwareFileItem(int nFileNum, PFILE_ITEM pFileItem)
{
if (m_FlashItemArray.GetSize() < (nFileNum + 1))
{
return FALSE;
}
*pFileItem = m_FlashItemArray.GetAt(nFileNum);
return TRUE;
}
static wLastPercent = 0;
void CFlashUpgraderDlg::CallbackProc(eFLASHSTATUS eStatus, DWORD dwParam)
{
CMakeSafe ms(&m_pThis->m_Safe); // Make this block thread-safe
ASSERT(psPENDING == m_pThis->m_eState);
switch (eStatus)
{
//--------------------------------------------------------------------
// No message (should never be invoked with this option).
//--------------------------------------------------------------------
case fsNONE:
break;
//--------------------------------------------------------------------
// Error occured while downloading file to target.
//--------------------------------------------------------------------
case fsERROR:
m_pThis->m_eState = psNONE;
m_pThis->DisplayErrorMsg();
if (m_pThis->m_bVerifyOnly)
{
m_pThis->m_eState = psVERIFYFAILED;
}
m_pThis->PostMessage(DOWNLOAD_COMPLETED_MESSAGE, 0, 0);
break;
//--------------------------------------------------------------------
// Block successfully downloaded. We can update our progress bar.
//
// dwParam : Size of block transfered in bytes.
//--------------------------------------------------------------------
case fsDOWNLOADED_BLOCK:
{
m_pThis->m_nTransferedSize += dwParam;
WORD wPercent = ((m_pThis->m_nTransferedSize) * 100) /
m_pThis->m_nTotalSize;
if (wPercent != wLastPercent)
{
wLastPercent = wPercent;
m_pThis->m_ctrlProgress.SetPos(wPercent);
CString cStr;
cStr.Format("%s: %s", "Downloading", g_strFileName);
g_pFileLabel->SetWindowText(cStr);
cStr.Format("%d", m_pThis->m_nTransferedSize);
g_pByteLabel->SetWindowText(cStr);
cStr.Format("%d%%", wPercent);
g_pPercentLabel->SetWindowText(cStr);
if (m_pThis->IsIconic())
{
cStr.Format("%d%% - %s", wPercent, g_strFileName);
m_pThis->SetWindowText(cStr);
}
}
}
break;
//--------------------------------------------------------------------
// File download operation has completed.
//--------------------------------------------------------------------
case fsCOMPLETED:
{
m_pThis->m_eState = psNONE;
CString strMsg(m_pThis->m_FlashHelper.GetLastReturnedTargetMessage());
if (FALSE == strMsg.IsEmpty())
{
// Check if returned string contains our success string.
if (-1 == strMsg.Find(lpszReturnedSuccessText))
{
// Data returned from target doesn't contain expected text.
m_pThis->DisplayErrorMsg();
//
// Set the return code to failure.
//
pTheApp->m_nReturnValue = -1;
}
}
//----------------------------------------------------------------
// Since we are on another thread, we cannot make calls to
// update this window directly. We will post a message to this
// window so its thread can process the fsCOMPLETED message.
//----------------------------------------------------------------
m_pThis->PostMessage(DOWNLOAD_COMPLETED_MESSAGE, 0, 0);
}
break;
default:
TRACE("Unknown value from CallbackProc: %d\n", eStatus);
}
}
long CFlashUpgraderDlg::OnDownloadCompletedMessage(UINT wParam, LONG lParam)
{
// Downloading of a file has completed. Invoke method that only this
// window's thread can execute.
DownloadFileCompleted();
return 0;
}
void CFlashUpgraderDlg::DownloadFileCompleted()
{
m_nCurrentFileNum++; // bump download file number
if (DownloadNextFile())
{
m_strFileName = "Resetting...";
UpdateData(FALSE);
return; // Another file is starting to download.
}
//------------------------------------------------------------------------
// An error occured or we are done downloading files. We can tell by the
// current state member variable (m_eState).
//------------------------------------------------------------------------
CString strTitle;
strTitle.LoadString(IDS_APP_TITLE);
SetWindowText(strTitle);
// Close COM port, this will allow hyperterm to connect without needing to
// exit flash upgrader.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -