#include "SerialPortWinBase.h"
#include <iostream>
std::wstring stringToWString(const std::string &str)
{
if (str.empty())
{
return std::wstring();
}
int size = MultiByteToWideChar(CP_ACP, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring ret = std::wstring(size, 0);
MultiByteToWideChar(CP_ACP, 0, &str[0], (int)str.size(), &ret[0], size);
return ret;
}
CSerialPortWinBase::CSerialPortWinBase()
{
construct();
}
CSerialPortWinBase::CSerialPortWinBase(const std::string &portName)
{
construct();
}
CSerialPortWinBase::~CSerialPortWinBase()
{
if (isOpened())
{
closePort();
}
DeleteCriticalSection(&m_communicationMutex);
}
void CSerialPortWinBase::construct()
{
m_handle = INVALID_HANDLE_VALUE;
m_monitorThread = INVALID_HANDLE_VALUE;
m_baudRate = itas109::BaudRate9600;
m_parity = itas109::ParityNone;
m_dataBits = itas109::DataBits8;
m_stopbits = itas109::StopOne;
m_flowControl = itas109::FlowNone;
m_readBufferSize = 512;
m_operateMode = itas109::AsynchronousOperate;
overlapMonitor.Internal = 0;
overlapMonitor.InternalHigh = 0;
overlapMonitor.Offset = 0;
overlapMonitor.OffsetHigh = 0;
overlapMonitor.hEvent = CreateEvent(NULL, true, false, NULL);
m_isThreadRunning = false;
InitializeCriticalSection(&m_communicationMutex);
}
void CSerialPortWinBase::init(std::string portName,
int baudRate /*= itas109::BaudRate::BaudRate9600*/,
itas109::Parity parity /*= itas109::Parity::ParityNone*/,
itas109::DataBits dataBits /*= itas109::DataBits::DataBits8*/,
itas109::StopBits stopbits /*= itas109::StopBits::StopOne*/,
itas109::FlowControl flowControl /*= itas109::FlowControl::FlowNone*/,
int64 readBufferSize /*= 512*/)
{
m_portName = "\\\\.\\" + portName; // support COM10 above \\\\.\\COM10
m_baudRate = baudRate;
m_parity = parity;
m_dataBits = dataBits;
m_stopbits = stopbits;
m_flowControl = flowControl;
m_readBufferSize = readBufferSize;
}
bool CSerialPortWinBase::openPort()
{
lock();
bool bRet = false;
TCHAR *tcPortName = NULL;
#ifdef UNICODE
std::wstring wstr = stringToWString(m_portName);
tcPortName = const_cast<TCHAR *>(wstr.c_str());
#else
tcPortName = const_cast<TCHAR *>(m_portName.c_str());
#endif
unsigned long configSize = sizeof(COMMCONFIG);
m_comConfigure.dwSize = configSize;
DWORD dwFlagsAndAttributes = 0;
if (m_operateMode == itas109::/*OperateMode::*/ AsynchronousOperate)
{
dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;
}
if (!isOpened())
{
// get a handle to the port
m_handle = CreateFile(tcPortName, // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
dwFlagsAndAttributes, // Async I/O or sync I/O
NULL);
if (m_handle != INVALID_HANDLE_VALUE)
{
// get default parameter
GetCommConfig(m_handle, &m_comConfigure, &configSize);
GetCommState(m_handle, &(m_comConfigure.dcb));
// set parameter
m_comConfigure.dcb.BaudRate = m_baudRate;
m_comConfigure.dcb.ByteSize = m_dataBits;
m_comConfigure.dcb.Parity = m_parity;
m_comConfigure.dcb.StopBits = m_stopbits;
// m_comConfigure.dcb.fDtrControl;
// m_comConfigure.dcb.fRtsControl;
m_comConfigure.dcb.fBinary = true;
m_comConfigure.dcb.fInX = false;
m_comConfigure.dcb.fOutX = false;
m_comConfigure.dcb.fAbortOnError = false;
m_comConfigure.dcb.fNull = false;
// setBaudRate(m_baudRate);
// setDataBits(m_dataBits);
// setStopBits(m_stopbits);
// setParity(m_parity);
setFlowControl(m_flowControl); // @todo
// COMMTIMEOUTS m_commTimeouts;
// //set read timeout
// m_commTimeouts.ReadIntervalTimeout = MAXWORD;
// m_commTimeouts.ReadTotalTimeoutMultiplier = 0;
// m_commTimeouts.ReadTotalTimeoutConstant = 0;
// //set write timeout
// m_commTimeouts.WriteTotalTimeoutConstant = 500;
// m_commTimeouts.WriteTotalTimeoutMultiplier = 100;
// SetCommTimeouts(m_handle,&m_commTimeouts); // @todo for test
if (SetCommConfig(m_handle, &m_comConfigure, configSize))
{
// @todo
// Discards all characters from the output or input buffer of a specified communications resource. It
// can also terminate pending read or write operations on the resource.
PurgeComm(m_handle, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT);
// init event driven approach
if (m_operateMode == itas109::/*OperateMode::*/ AsynchronousOperate)
{
m_comTimeout.ReadIntervalTimeout = MAXDWORD;
m_comTimeout.ReadTotalTimeoutMultiplier = 0;
m_comTimeout.ReadTotalTimeoutConstant = 0;
m_comTimeout.WriteTotalTimeoutMultiplier = 0;
m_comTimeout.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(m_handle, &m_comTimeout);
// set comm event
if (SetCommMask(m_handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) // @todo mask need modify
{
m_isThreadRunning = true;
bRet = startThreadMonitor();
if (!bRet)
{
m_isThreadRunning = false;
lastError = itas109::/*SerialPortError::*/ SystemError;
}
}
else
{
// Failed to set Comm Mask
bRet = false;
lastError = itas109::/*SerialPortError::*/ InvalidParameterError;
}
}
else
{
m_comTimeout.ReadIntervalTimeout = MAXDWORD;
m_comTimeout.ReadTotalTimeoutMultiplier = 0;
m_comTimeout.ReadTotalTimeoutConstant = 0;
m_comTimeout.WriteTotalTimeoutMultiplier = 100;
m_comTimeout.WriteTotalTimeoutConstant = 500;
SetCommTimeouts(m_handle, &m_comTimeout);
bRet = true;
}
}
else
{
// set com configure error
bRet = false;
lastError = itas109::/*SerialPortError::*/ InvalidParameterError;
}
}
else
{
//串口打开失败,增加提示信息
switch (GetLastError())
{
//串口不存在
case ERROR_FILE_NOT_FOUND:
{
lastError = itas109::/*SerialPortError::*/ DeviceNotFoundError;
break;
}
//串口拒绝访问
case ERROR_ACCESS_DENIED:
{
lastError = itas109::/*SerialPortError::*/ Permiss
评论5