📄 ecosserial.cpp
字号:
//####COPYRIGHTBEGIN####
//
// ----------------------------------------------------------------------------
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
//
// This program is part of the eCos host tools.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// ----------------------------------------------------------------------------
//
//####COPYRIGHTEND####
//=================================================================
//
// eCosSerial.cpp
//
// Serial test class
//
//=================================================================
//=================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): sdf
// Contributors: sdf
// Date: 1999-04-01
// Description: This class abstracts the serial port for use in the testing infrastructure
// Usage:
//
//####DESCRIPTIONEND####
#include "eCosStd.h"
#include "eCosSerial.h"
#include "eCosThreadUtils.h"
#include "eCosTrace.h"
CeCosSerial::CeCosSerial():
m_nErr(0),
m_pHandle(0),
m_nDataBits(8),
m_nStopBits(ONE_STOP_BIT),
m_bXONXOFFFlowControl(0),
m_bRTSCTSFlowControl(0),
m_bDSRDTRFlowControl(0),
m_bParity(false),
m_nBaud(0),
m_nTotalReadTimeout(10*1000),
m_nTotalWriteTimeout(10*1000),
m_nInterCharReadTimeout(500),
m_nInterCharWriteTimeout(500),
m_bBlockingReads(true)
{
}
CeCosSerial::~CeCosSerial()
{
Close();
}
CeCosSerial::CeCosSerial(LPCTSTR pszPort,int nBaud):
m_nErr(0),
m_pHandle(0),
m_nDataBits(8),
m_nStopBits(ONE_STOP_BIT),
m_bXONXOFFFlowControl(0),
m_bRTSCTSFlowControl(0),
m_bDSRDTRFlowControl(0),
m_bParity(false),
m_nTotalReadTimeout(10*1000),
m_nTotalWriteTimeout(10*1000),
m_nInterCharReadTimeout(500),
m_nInterCharWriteTimeout(500),
m_bBlockingReads(true)
{
Open(pszPort,nBaud);
}
bool CeCosSerial::SetBlockingReads(bool b,bool bApplySettingsNow/*=true*/)
{
m_bBlockingReads=b;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetBaud(unsigned int nBaud,bool bApplySettingsNow/*=true*/)
{
m_nBaud=nBaud;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetParity(bool bParityOn,bool bApplySettingsNow/*=true*/)
{
m_bParity=bParityOn;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetDataBits(int n,bool bApplySettingsNow/*=true*/)
{
m_nDataBits=n;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetStopBits(StopBitsType n,bool bApplySettingsNow/*=true*/)
{
m_nStopBits=n;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetXONXOFFFlowControl(bool b,bool bApplySettingsNow/*=true*/)
{
m_bXONXOFFFlowControl=b;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetRTSCTSFlowControl(bool b,bool bApplySettingsNow/*=true*/)
{
m_bRTSCTSFlowControl=b;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetDSRDTRFlowControl(bool b,bool bApplySettingsNow/*=true*/)
{
m_bDSRDTRFlowControl=b;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetReadTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec
{
m_nTotalReadTimeout=nTotal;
m_nInterCharReadTimeout=nBetweenChars;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
bool CeCosSerial:: SetWriteTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec
{
m_nTotalWriteTimeout=nTotal;
m_nInterCharWriteTimeout=nBetweenChars;
return 0==m_pHandle || !bApplySettingsNow || ApplySettings();
}
#ifdef _WIN32
bool CeCosSerial::Open(LPCTSTR pszPort,int nBaud)
{
bool rc=false;
m_nBaud=nBaud,
m_strPort=pszPort;
HANDLE hCom=::CreateFile(pszPort,GENERIC_READ|GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0,NULL);
SaveError();
if (INVALID_HANDLE_VALUE==hCom) {
ERROR(_T("Failed to open port %s - %s\n"),pszPort,(LPCTSTR)ErrString());
} else {
m_pHandle=(void *)hCom;
if(ApplySettings()){
Flush();
rc=true;
} else {
Close();
}
}
return rc;
}
bool CeCosSerial::Close()
{
bool rc=false;
if(m_pHandle){
try {
rc=(TRUE==CloseHandle((HANDLE)m_pHandle));
}
catch(...) {
TRACE(_T("!!! Exception caught closing serial handle %08x\n"),m_pHandle);
}
m_pHandle=0;
} else {
rc=true;
}
return rc;
}
bool CeCosSerial::ApplySettings()
{
bool rc=false;
try {
DCB dcb;
ZeroMemory(&dcb,sizeof dcb);
dcb.DCBlength=sizeof dcb;
dcb.BaudRate=m_nBaud;
dcb.fBinary=true;
dcb.fParity=true;
dcb.Parity=(BYTE) ((m_bParity) ? EVENPARITY : NOPARITY);
dcb.StopBits=(BYTE)m_nStopBits;
dcb.ByteSize=(BYTE)m_nDataBits;
LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")};
TRACE(_T("Applysettings baud=%d Parity=%d stopbits=%s databits=%d\n"),
dcb.BaudRate,
dcb.Parity,
arpszStopbits[dcb.StopBits],
dcb.ByteSize);
if (m_bDSRDTRFlowControl) {
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutxDsrFlow = 1;
} else {
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fOutxDsrFlow = 0;
}
if (m_bRTSCTSFlowControl) {
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutxCtsFlow = 1;
} else {
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fOutxCtsFlow = 0;
}
dcb.fTXContinueOnXoff=1;
dcb.XonChar=17;
dcb.XoffChar=19;
if (m_bXONXOFFFlowControl) {
dcb.XonLim=512;
dcb.XoffLim=512;
dcb.fOutX=1;
dcb.fInX=1;
} else {
dcb.XonLim=2048;
dcb.XoffLim=512;
dcb.fOutX=0;
dcb.fInX=0;
}
dcb.fAbortOnError=1;
HANDLE hCom=(HANDLE)m_pHandle;
if (!SetCommState(hCom, &dcb)) {
SaveError();
ERROR(_T("Failed to set comm state - port %s handle=%d err=%d\n"),(LPCTSTR)m_strPort,hCom,GetLastError());
} else {
COMMTIMEOUTS commtimeouts;
if(m_bBlockingReads){
commtimeouts.ReadIntervalTimeout=m_nInterCharReadTimeout;
commtimeouts.ReadTotalTimeoutMultiplier=0;
commtimeouts.ReadTotalTimeoutConstant=m_nTotalReadTimeout;
} else {
commtimeouts.ReadIntervalTimeout=MAXDWORD;
commtimeouts.ReadTotalTimeoutMultiplier=0;
commtimeouts.ReadTotalTimeoutConstant=0;
}
commtimeouts.WriteTotalTimeoutMultiplier=m_nTotalWriteTimeout;
commtimeouts.WriteTotalTimeoutConstant=m_nInterCharWriteTimeout;
if (SetCommTimeouts(hCom, &commtimeouts)) {
rc=true;
} else {
SaveError();
ERROR(_T("Failed to set comm timeouts - port %s\n"),(LPCTSTR)m_strPort);
}
}
}
catch(...)
{
TRACE(_T("!!! Exception caught in CeCosSerial::ApplySettings!!!\n"));
}
return rc;
}
bool CeCosSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead)
{
bool rc=(TRUE==ReadFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nRead,0));
SaveError();
return rc;
}
bool CeCosSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten)
{
bool rc=(TRUE==WriteFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nWritten,0));
SaveError();
return rc;
}
bool CeCosSerial::ClearError()
{
DWORD dwErrors;
bool rc=(TRUE==ClearCommError(HANDLE(m_pHandle),&dwErrors,0));
if(dwErrors&CE_BREAK)TRACE(_T("The hardware detected a break condition.\n"));
if(dwErrors&CE_DNS)TRACE(_T("Windows 95 and Windows 98: A parallel device is not selected.\n"));
if(dwErrors&CE_FRAME)TRACE(_T("The hardware detected a framing error.\n"));
if(dwErrors&CE_IOE)TRACE(_T("An I/O error occurred during communications with the device.\n"));
if(dwErrors&CE_MODE)TRACE(_T("The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.\n"));
if(dwErrors&CE_OOP)TRACE(_T("Windows 95 and Windows 98: A parallel device signaled that it is out of paper.\n"));
if(dwErrors&CE_OVERRUN)TRACE(_T("A character-buffer overrun has occurred. The next character is lost.\n"));
if(dwErrors&CE_PTO)TRACE(_T("Windows 95 and Windows 98: A time-out occurred on a parallel device.\n"));
if(dwErrors&CE_RXOVER)TRACE(_T("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.\n"));
if(dwErrors&CE_RXPARITY)TRACE(_T("The hardware detected a parity error.\n"));
if(dwErrors&CE_TXFULL)TRACE(_T("The application tried to transmit a character, but the output buffer was full.\n"));
return rc;
}
bool CeCosSerial::Flush (void)
{
bool rc=(TRUE==PurgeComm ((HANDLE)m_pHandle,PURGE_TXCLEAR|PURGE_RXCLEAR));
SaveError();
return rc;
}
String CeCosSerial::ErrString() const
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -