📄 flashhelper.cpp
字号:
// If we are expecting a string returned from the target, then
// check for it here.
//
// Note: The string returned only has to contain our search
// string, not equal it.
//----------------------------------------------------------------
TRACE("Returned text= %s\n", m_strReturnedMsg);
// Invoke callback procedure with completed message.
(*m_pCallback)(fsCOMPLETED, 0);
break;
case scCANCEL:
// Target cancelled operation.
if (FALSE == m_strReturnedMsg.IsEmpty())
{
// Got returned error message from target.
SetLastError(feTARGET_ERROR_MESSAGE);
}
else
{
SetLastError(feFLASH_CANCELED);
}
(*m_pCallback)(fsERROR);
return FALSE;
break;
case scERROR:
default:
// Download failed. Invoke callback procedure with error message.
SetLastError(feFLASH_CANCELED);
(*m_pCallback)(fsERROR);
}
return TRUE;
}
//----------------------------------------------------------------------------
// Download binary data to target using the X-Modem protocol.
//
// Params:
// pData : Pointer to binary data to download.
// nSize : Byte size of binary data.
// rstrResult : String returned from target after download has completed.
//
// Return: TRUE= Binary data successfully downloaded to target.
//
// Notes:
//----------------------------------------------------------------------------
eSENDCMDRETVAL CFlashHelper::DownloadDataXModem(const BYTE *pData, int nSize,
CString& rstrResult)
{
eSENDCMDRETVAL eRet = scOK;
BYTE cBlock = 1;
BYTE *pCurrent = (BYTE*)pData;
rstrResult.Empty();
// Keep downloading bytes until none left.
m_nBlockCounter = 0;
while (nSize)
{
int nChunkSize = m_nBlockSize;
if (nSize < nChunkSize)
{
// Last chunk to download is less than X-Modem block size.
nChunkSize = nSize;
}
// Download a X-Modem block of data.
eRet = DownloadXModemBlock(cBlock, pCurrent, nChunkSize);
if (scOK != eRet)
{
// Error occured or operation was canceled
if (scCANCEL == eRet && (FALSE == m_bCanceled) && (m_pComPortCmd->m_eComm != ccUSB))
{
// If operation was cancelled, attempt to get returned error
// string.
GetResponseString(rstrResult);
}
return eRet;
}
// Invoke callback procedure with chunk downloaded message.
(*m_pCallback)(fsDOWNLOADED_BLOCK, nChunkSize);
cBlock++; // bump X-Modem block number
pCurrent += nChunkSize; // bump pointer to current binary data
nSize -= nChunkSize; // adjust remaining size of bytes to download
}
// Setup to attempt sending the EOT (end of file marker) to the target.
int nRetryCount = 10;
while (nRetryCount)
{
m_pComPortCmd->SendData(EOT_CHAR); // Send EOT character to target
// Wait for response from target. Should be an ACK character.
CByteArray byteArray;
eRet = m_pComPortCmd->GetData(byteArray, m_hCancelEvent, 1, XMODEM_TIMEOUT_SEC);
if (scOK == eRet)
{
BYTE cData = byteArray.GetAt(0); // get first byte received
if (ACK_CHAR == cData)
{
break;
}
}
else if (scCANCEL == eRet)
{
break;
}
nRetryCount--; // try again
}
if (scOK == eRet && (m_pComPortCmd->m_eComm != ccUSB))
{
eRet = GetResponseString(rstrResult);
}
return eRet;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
eSENDCMDRETVAL CFlashHelper::GetResponseString(CString& rstrResult)
{
eSENDCMDRETVAL eRet;
CString strTail;
rstrResult.Empty();
//--------------------------------------------------------------------
// Get response string from target. We are expecting a CR or NULL
// terminated string here so only request to receive the first
// terminated string sent within the timeout period.
//--------------------------------------------------------------------
eRet = m_pComPortCmd->GetData(strTail,
m_hCancelEvent,
RESPONSE_STRING_TIMEOUT_MS,
0,
TRUE); // TRUE= only get string until a CR or NULL char
if (scOK == eRet)
{
// Remove CR if one exist in string.
int nPos = strTail.Find('\r');
if (-1 != nPos)
{
rstrResult = strTail.Left(nPos); // get string only to CR
}
else
{
rstrResult = strTail; // use entire string
}
}
return eRet;
}
//----------------------------------------------------------------------------
// Download one block of data to the target using the X-Modem protocol.
//
// Params:
// cBlock : Number of block to download.
// pData : Pointer to binary data to download.
// nSize : Size of binary data.
//
// Return: TRUE= Block successfully downloaded to target.
//
// Notes:
//----------------------------------------------------------------------------
eSENDCMDRETVAL CFlashHelper::DownloadXModemBlock(BYTE cBlock, const BYTE *pData,
int nSize)
{
CByteArray byteArray;
CByteArray byteResponse;
byteArray.SetSize(m_nBlockSize); // set size of X-Modem data block
byteResponse.SetSize(10);
// Copy data to X-Modem block area.
CopyMemory((void*)byteArray.GetData(), (void*)pData, nSize);
m_nBlockCounter++;
//------------------------------------------------------------------------
// If the data doesn't fill the entire block, fill the remaining bytes with
// zeros.
//------------------------------------------------------------------------
if (nSize < m_nBlockSize)
{
FillMemory((void*)(byteArray.GetData() + nSize), m_nBlockSize - nSize, 0);
}
// Calculate 16-bit checksum of binary data block to send.
WORD wChecksum = CalculateCRC16(byteArray.GetData(), m_nBlockSize);
//------------------------------------------------------------------------
// Send block using X-Modem protocol. Send SOH, block number, ones
// complemented block number, binary data bytes and 16-bit CRC (high byte
// first).
//------------------------------------------------------------------------
int nRetryCount = 10;
eSENDCMDRETVAL eRet = scOK;
while(nRetryCount)
{
if (m_pComPortCmd->m_eComm != ccUSB)
{
m_pComPortCmd->SendData(SOH_CHAR);
// Only serial uses XModem protocol.
//TRACE("Sending X-Modem. cBlock=%d, wChecksum=0x%04X\n", cBlock, wChecksum);
m_pComPortCmd->SendData(cBlock);
m_pComPortCmd->SendData(cBlock ^ 0xff);
}
else
{
if (m_nBlockCounter != 1)
{
m_pComPortCmd->SendData(SOH_CHAR);
}
}
if (cBlock == 1)
{
int i = 5;
}
BYTE* pByte = byteArray.GetData();
m_pComPortCmd->SendData(pByte, m_nBlockSize);
if (scOK == eRet)
{
if (m_pComPortCmd->m_eComm != ccUSB)
{
m_pComPortCmd->SendData((BYTE)(wChecksum >> 8)); // send CRC high byte
m_pComPortCmd->SendData((BYTE)wChecksum); // send CRC low byte
}
// Wait for response from target.
CByteArray byteArray;
eRet = m_pComPortCmd->GetData(byteArray, m_hCancelEvent, 1, XMODEM_TIMEOUT_SEC);
if (scOK == eRet)
{
BYTE cData = byteArray.GetAt(0); // get first byte received
if (ACK_CHAR == cData)
{
// ACK received. Block was successfully received by target.
break;
}
if (CAN_CHAR == cData)
{
eRet = scCANCEL;
break; // Target is cancelling the download.
}
}
else if (scCANCEL == eRet)
{
break;
}
// We either time-out or received bad data from the target.
nRetryCount--;
}
}
return eRet; // return status code
}
//----------------------------------------------------------------------------
// Following is CRC arrays used to quickly calculate CRC of incoming and
// outgoing messages. They're large, but this is the fastest way.
//----------------------------------------------------------------------------
static BYTE far cCRCHiArray[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
static BYTE far cCRCLoArray[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};
//----------------------------------------------------------------------------
// Calculate a 16-bit Cycle Redundency Check (CRC) value on a block of data.
//
// Params:
// pData : Pointer to data to calculate CRC.
// dwSize : Size of data in bytes.
//
// Return:
// 16-bit CRC value.
//
// Notes:
//----------------------------------------------------------------------------
WORD CFlashHelper::CalculateCRC16(const BYTE *pcData, int nCount)
{
BYTE cCRCHi = 0xFF; // high byte of CRC initialized
BYTE cCRCLo = 0xFF; // low byte of CRC initialized
BYTE cIndex; // will index into CRC lookup table
while (nCount--) // step through each byte of data
{
cIndex = cCRCHi ^ *pcData++; // calculate the CRC
cCRCHi = cCRCLo ^ cCRCHiArray[cIndex];
cCRCLo = cCRCLoArray[cIndex];
}
return (cCRCHi << 8) + cCRCLo;
}
//----------------------------------------------------------------------------
// Delete objects created on the heap (with new operator).
//
// Params: none
//
// Return: none
//
// Notes:
//----------------------------------------------------------------------------
void CFlashHelper::DeleteHeapObjects()
{
if (m_pFlashData)
{
delete m_pFlashData;
m_pFlashData = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -