多线程串口管理代码(1)
// Serial.cpp: implementation of the XSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XSerial.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//#define COM_BUGSERIAL 1
#ifdef COM_BUGSERIAL
static void ComSerialPrintf(const BYTE *str,const int Len )
{
char szFileName[256];
char buf[512];
strcpy( szFileName, "c:\\CombugSerial.txt" );
FILE *fpDebug = fopen( szFileName, "a" );
memset(buf,0,Len * 3 +2);
for( int i =0; i< Len; i++) sprintf(buf+(3*i),"%02X ",str[i]);
fprintf( fpDebug, "%s\n", buf );
fclose( fpDebug );
}
static void ComSerialBccPrintf(const BYTE *str,const int Len )
{
char szFileName[256];
char buf[512];
strcpy( szFileName, "c:\\CombugBccSerial.txt" );
FILE *fpDebug = fopen( szFileName, "a" );
memset(buf,0,Len * 3 +2);
for( int i =0; i< Len; i++) sprintf(buf+(3*i),"%02X ",str[i]);
fprintf( fpDebug, "%s\n", buf );
fclose( fpDebug );
}
static void ComSerialErrorBccPrintf(const BYTE *str,const int Len )
{
char szFileName[256];
char buf[512];
strcpy( szFileName, "c:\\CombugErrorSerialCode.txt" );
FILE *fpDebug = fopen( szFileName, "a" );
memset(buf,0,Len * 3 +2);
for( int i =0; i< Len; i++) sprintf(buf+(3*i),"%02X ",str[i]);
fprintf( fpDebug, "%s\n", buf );
fclose( fpDebug );
}
#endif //BUG
XSerial::XSerial()
{
m_dwThreadID = 0;
m_nSerialNo = 0;
memset( m_pRecvBufferForComm, 0, MAX_BYTE_FROM_COMM );
memset( m_pEventCmd,0,SIZE_OF_CMD_TO_GET_HIS);
m_nPosInReadBuffer = 0;
m_nMaxWaitingTime = 0;
m_bWriting = false;
m_bReading = false;
m_bWaiting = false;
m_dwDelay = GetTickCount();
m_szPath =NULL;
m_pDownloadCmd = NULL;
m_pRecvMessage = NULL;
m_pHistoryMessage = NULL;
//m_nHistoryCmd = 0xF0;
}
XSerial::~XSerial()
{
SafeDelete( m_pDownloadCmd );
SafeDelete( m_pHistoryMessage );
SafeDelete( m_pRecvMessage );
}
//---------------------------------------------------------------------------
int XSerial::AddCmd( BYTE *pBuf,int nLen )
{
m_pDownloadCmd->AddContent( nLen,pBuf );
return SERIAL_OK;
}
//--------------------------------------------------------------------------
int XSerial::InitSerial( const DWORD dwThreadID,
int CommPortNo,
int SerialNo,
const char *szPath,
const int nWaitTime,
const short bHaveMID )
{
m_pHistoryMessage = new XArrays( MAX_SIZE_CMD_BUF );
m_pRecvMessage = new XArrays( MAX_SIZE_CMD_BUF );
m_pDownloadCmd = new XArrays( MAX_SIZE_CMD_BUF );
m_dwThreadID = dwThreadID;
m_nSerialNo = SerialNo;
m_nCommPortID = CommPortNo;
m_szPath = (LPSTR)szPath;
m_nMaxWaitingTime = nWaitTime;
m_bHaveMID = bHaveMID;
if ( m_bHaveMID == 1 ) { m_bMark = 0xFF; } else { m_bMark = 0xA5; }
//m_nHistoryCmd = 0xF0;
return SERIAL_OK; //..sucessed init
}
//--------------------------------------------------------------------------
int XSerial::ReceiveBuf( int len,const BYTE *pBuff )
{
//m_dwDelay = GetTickCount();
AtlTrace("Begin Read:%d\n", m_dwDelay);
if ( m_bRecvAll || 0 == len ) return SERIAL_OK;
if ( !m_bWaiting ) m_bWaiting = true;
if ( !m_bReading ) m_bReading = true;
BOOL bValid = TRUE;
BYTE *pData = (BYTE*)pBuff;
ATLASSERT(pData);
if ( !pData ) return SERIAL_ERROR;
if ( m_nPosInReadBuffer == 0 )
{
bValid = FALSE;
for ( int i = 0 ; i < len; i++)
{
if ( pData[i] == PUB_CMD_SOH )
{
bValid = TRUE;
break;
}
}
pData += i;
len -= i;
AtlTrace("InputLen:%d,丢弃%dByte\n",len,i);
}
if ( !bValid ) len = 0;
int iTemp = len < MAX_BYTE_FROM_COMM ? len:MAX_BYTE_FROM_COMM;
for ( int i = 0 ; i < len && m_nPosInReadBuffer < MAX_BYTE_FROM_COMM;i++)
{
m_pRecvBufferForComm[m_nPosInReadBuffer++] = pData[i];
}
return ReceiveCompleted();
}
//--------------------------------------------------------------------------
int XSerial::ReceiveCompleted()
{
int nSize = m_nPosInReadBuffer;
if ( nSize < 11 )
{
//m_dwDelay = GetTickCount();
m_bReading = false;
AtlTrace("End Delay: %d,ReadSize: %d \n",m_dwDelay,nSize);
return SERIAL_OK;
}
ATLASSERT( nSize < MAX_BYTE_FROM_COMM );
if ( nSize >= MAX_BYTE_FROM_COMM ) return SERIAL_ERROR;
RecvMessage( m_pRecvBufferForComm,nSize );
m_bReading = false;
m_bRecvAll = true;
m_bWaiting = false;
m_dwDelay = GetTickCount();
AtlTrace("End all Delay: %d,ReadSize: %d \n",m_dwDelay,nSize);
return SERIAL_OK;
}
//--------------------------------------------------------------------------
int XSerial::SendCmd()
{
if ( m_bWaiting )
{
DWORD dwTemp = GetTickCount();
if ( m_bWriting )
{
if ( dwTemp < RECOVER_TIME + m_dwDelay ) return SERIAL_WRITING;
}
else if ( m_bReading )
{
if ( dwTemp < m_nMaxWaitingTime + m_dwDelay ) //RECOVER_TIME
{
AtlTrace("正在等待读数据返回\n");
return SERIAL_READING;
}
}
else if ( dwTemp < m_nMaxWaitingTime + m_dwDelay )
{
AtlTrace(" 正在等待指令发送\n");
return SERIAL_WRITING;
}
OffLineDetected();
m_bWaiting = false;
//m_dwDelay = GetTickCount();
if ( m_bRepeat )
{
m_bRepeat = false;
}
else if (m_nWhichCmdSent == 1 ) //..temp
{
m_pDownloadCmd->NextContent();
}
else
{
return SERIAL_READY_TO_ASK_NEW_HISTORY;
}
}
if (GetTickCount() < m_dwDelay + 50 )
return SERIAL_CMD_SEND_OK;
int nLen = 0;
while ( 1 )
{
CBufferArray BufferArray;
m_pDownloadCmd->GetNewContent( &BufferArray );
BYTE *pBuf = BufferArray.Data();
nLen = BufferArray.Size();
if ( pBuf != NULL)
{
if ( pBuf[0] != 0x01 )
{
m_pDownloadCmd->NextContent();
continue;
}
if (pBuf[4] == 0x99 && pBuf[5] == 0x99 )
{
m_pDownloadCmd->NextContent();
m_bIsBroadCast = true;
m_bWaiting = false;
}
else
{
m_bIsBroadCast = false;
m_bWaiting = true;
}
m_bWriting = true;
m_nPosInReadBuffer = 0;
m_bRecvAll = false;
m_dwDelay = GetTickCount();
m_nWhichCmdSent = 1;
WriteToPort( pBuf , nLen );
//m_dwDelay = GetTickCount();
return SERIAL_CMD_SEND_OK;
}
else
{
return SERIAL_READY_TO_ASK_NEW_HISTORY;
}
}
}
//--------------------------------------------------------------------------
int XSerial::WriteCompleted(bool bRpt)
{
m_bWriting = false;
if ( m_bIsBroadCast )
{
m_bWaiting = true;
m_bIsBroadCast = false;
m_bReading = false;
}
else
{
m_bWaiting = true;
m_bReading = true;
m_dwDelay = GetTickCount();
AtlTrace("End write: %d \n",m_dwDelay);
}
m_bRepeat = bRpt;
return SERIAL_OK;
}
//--------------------------------------------------------------------------
int XSerial::RecvMessage( BYTE *buf,int nLen )
{
ATLASSERT( buf );
if ( !buf ) return SERIAL_ERROR;
if( buf[4] ==0x99 || buf[5] == 0x99 ) return SERIAL_OK;
if( buf[1] != PUB_CMD_w) return SERIAL_ERROR;
BYTE nBCC = buf[nLen-1];
#ifdef COM_BUGSERIAL
ComSerialPrintf(buf,nLen); //..no check
#endif
if ( nBCC != MarkBCC(buf,nLen-1) )
{
#ifdef COM_BUGSERIAL
ComSerialErrorBccPrintf(buf,nLen); // check error
#endif
m_bWaiting = false;
return SERIAL_OK;
}
#ifdef COM_BUGSERIAL
ComSerialBccPrintf(buf,nLen); //..output BCC code
#endif
WORD wParame =0 ;
if (DECToBCD(buf[3]) >0 || DECToBCD(buf[3]) <=32)
{
wParame = (DECToBCD(buf[3]) << 8)+DECToBCD(buf[5]);
}
else { wParame = (WORD)DECToBCD(buf[5]); }
//....
if ( buf[0] == 0x01 && buf[1] == 0x77 && buf[7] ==0x02 &&
( DECToBCD(buf[5]) > 0 || DECToBCD(buf[5]) <=32) )
{
PostThreadMessage( m_dwThreadID,WM_ON_LINE_DETECTED,wParame,m_nSerialNo );
}
AtlTrace("接收操作指令: %d,地址: %d\n",buf[6],2,wParame);
int nHisLen = 23;
if ( m_bMark == 0xFF ) nHisLen = 25;
if ( buf[6] == 0xF0 || buf[6] == 0xF5 )
{
BYTE *bHisBuf = new BYTE[nHisLen];
memcpy(&bHisBuf[0],&buf[0],nHisLen);
if ( buf[9] == m_bMark )
{
AtlTrace("没有事件的控制器地址: %d\n",wParame);
PostThreadMessage( m_dwThreadID,WM_NO_RECORD,wParame ,m_nSerialNo );
//m_bWaiting = false;
delete[] bHisBuf;
return SERIAL_OK;
}
else
{
AtlTrace("正在收取事件的控制器地址: %d\n",wParame);
m_pHistoryMessage->AddContent( nHisLen, bHisBuf );
PostThreadMessage( m_dwThreadID,WM_HAS_RECORD,wParame ,m_nSerialNo );
//m_bWaiting = false;
delete[] bHisBuf;
return SERIAL_OK;
}
}
if (DECToBCD(buf[5]) != 0x99 && DECToBCD(buf[4]) != 0x99 )
{
m_pRecvMessage->AddContent( nLen,buf );
m_pDownloadCmd->NextContent();
}
// m_bWaiting = false;
return SERIAL_OK;
}
//--------------------------------------------------------------------------
int XSerial::SetAskEventCmd( const BYTE *buf )
{
if( NULL == buf )
return SERIAL_ERROR;
memcpy( m_pEventCmd, buf, SIZE_OF_CMD_TO_GET_HIS );
return SERIAL_OK;
}
//--------------------------------------------------------------------------
int XSerial::AskForEvent()//( BYTE *pBuf, int nLen )
{
if ( GetTickCount() < m_dwDelay + 40 )
return SERIAL_OK;
m_nWhichCmdSent = 0;
m_nPosInReadBuffer = 0;
m_bRecvAll = false;
//m_dwDelay = GetTickCount();
AtlTrace("开始读历吏事件延时: %d\n",m_dwDelay);
m_bWriting = true;
m_bWaiting = true;
DWORD dwTemp = GetTickCount();
if ( m_bReading && ( dwTemp < m_nMaxWaitingTime + m_dwDelay ) ) return SERIAL_READING;
WriteToPort( m_pEventCmd, SIZE_OF_CMD_TO_GET_HIS );
return SERIAL_OK;
}
//--------------------------------------------------------------------------
void XSerial::GetRecenHistory( CBufferArray *pVal )
{
if ( pVal == NULL ) return;
m_pHistoryMessage->GetNewContent( pVal );
m_pHistoryMessage->NextContent();
}
//--------------------------------------------------------------------------
void XSerial::GetRecenMessage( CBufferArray *pVal )
{
if ( pVal == NULL ) return;
m_pRecvMessage->GetNewContent( pVal );
m_pRecvMessage->NextContent();
}
//--------------------------------------------------------------------------
int XSerial::OffLineDetected()
{
BYTE *buf = NULL;
int nLen = 0;
CBufferArray ba;
if( 1 == m_nWhichCmdSent )
{
m_pDownloadCmd->GetNewContent(&ba);
buf =ba.Data();
nLen=ba.Size();
}
else
buf = m_pEventCmd;
if( NULL == buf ) return SERIAL_OK;
WORD wParam = buf[5];
if( 0x99 == wParam ) return SERIAL_OK;
//.....
wParam = 0;
if ( DECToBCD(buf[3]) >= 1 && DECToBCD(buf[3]) <=32
&& DECToBCD(buf[5])>=1 && DECToBCD(buf[5])<=32 )
{
wParam = (DECToBCD(buf[3]) << 8)+DECToBCD(buf[5]);
} else
{
if (DECToBCD(buf[5])>=1 && DECToBCD(buf[5])<=32)
wParam = (WORD)DECToBCD(buf[5]);
else SERIAL_OK;
}
//.....
if( buf[6] == 0xB3 )
{
wParam = 0x8000;
}
PostThreadMessage( m_dwThreadID, WM_OFF_LINE_DETECTED, wParam, m_nSerialNo );
return SERIAL_OK;
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。