📄 ecosserial.cpp
字号:
String str;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
m_nErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
str=(LPCTSTR)lpMsgBuf;
// Free the buffer.
LocalFree( lpMsgBuf );
return str;
}
#else // UNIX
String CeCosSerial::ErrString() const
{
return strerror(errno);
}
bool CeCosSerial::Close()
{
bool rc=m_pHandle && (-1!=close((int)m_pHandle));
m_pHandle=0;
return rc;
}
bool CeCosSerial::Open(LPCTSTR pszPort,int nBaud)
{
bool rc=false;
m_nBaud=nBaud,
m_strPort=pszPort;
int fd = open(pszPort,O_RDWR|O_NONBLOCK);
if (-1==fd) {
ERROR(_T("Failed to open port %s\n"),pszPort);
return false;
} else {
m_pHandle=(void *)fd;
if(ApplySettings()){
rc=true;
} else {
Close();
ERROR(_T("Failed to apply settings.\n"));
return false;
}
}
return rc;
}
bool CeCosSerial::ApplySettings()
{
struct termios buf, buf_verify;
int rate;
// Clear the two structures so we can make a binary comparison later on.
memset(&buf, 0, sizeof(buf));
memset(&buf_verify, 0, sizeof(buf_verify));
LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")};
TRACE(_T("Applysettings baud=%d bParity=%d stopbits=%s databits=%d\n"),
m_nBaud,
m_bParity,
arpszStopbits[m_nStopBits],
m_nDataBits);
switch(m_nBaud) {
case 110:
rate = B110;
break;
case 150:
rate = B150;
break;
case 300:
rate = B300;
break;
case 600:
rate = B600;
break;
case 1200:
rate = B1200;
break;
case 2400:
rate = B2400;
break;
case 4800:
rate = B4800;
break;
case 9600:
rate = B9600;
break;
case 19200:
rate = B19200;
break;
case 38400:
rate = B38400;
break;
case 57600:
rate = B57600;
break;
case 115200:
rate = B115200;
break;
default:
return false;
};
TRACE(_T("Changing configuration...\n"));
// Get current settings.
if (tcgetattr((int) m_pHandle, &buf)) {
fprintf(stderr, _T("Error: tcgetattr\n"));
return false;
}
// Reset to raw.
buf.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
buf.c_oflag &= ~OPOST;
buf.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
buf.c_cflag &= ~(CSIZE|PARENB);
buf.c_cflag |= CS8;
// Set baud rate.
cfsetispeed(&buf, rate);
cfsetospeed(&buf, rate);
// Set data bits.
{
int data_bits[9] = {0, 0, 0, 0, 0, CS5, CS6, CS7, CS8};
buf.c_cflag &= ~CSIZE;
buf.c_cflag |= data_bits[m_nDataBits];
}
// Set stop bits.
{
buf.c_cflag &= ~CSTOPB;
if (ONE_STOP_BIT != m_nStopBits)
buf.c_cflag |= CSTOPB;
}
// Set parity.
{
buf.c_cflag &= ~(PARENB | PARODD); // no parity.
if (m_bParity) // even parity.
buf.c_cflag |= PARENB;
}
// Set flow control
{
buf.c_iflag &= ~(IXON|IXOFF);
#ifdef CRTSCTS
buf.c_cflag &= ~CRTSCTS;
#endif
if ( m_bXONXOFFFlowControl ) {
buf.c_iflag |= (IXON|IXOFF);
}
if ( m_bRTSCTSFlowControl ) {
#ifdef CRTSCTS
buf.c_cflag |= CRTSCTS;
#else
return false;
#endif
}
if ( m_bDSRDTRFlowControl ) {
#ifdef CDSRDTR
buf.c_cflag |= CDSRDTR;
#else
return false;
#endif
}
}
// Set the new settings
if (tcsetattr((int) m_pHandle, TCSADRAIN, &buf)) {
fprintf(stderr, _T("Error: tcsetattr\n"));
return false;
}
// Now read back the settings. On SunOS tcsetattr only returns
// error if _all_ settings fail. If just a few settings are not
// supported, the call returns true while the hardware is set to a
// combination of old and new settings.
if (tcgetattr((int) m_pHandle, &buf_verify)) {
fprintf(stderr, _T("Error: tcgetattr\n"));
return false;
}
if (memcmp(&buf, &buf_verify, sizeof(buf))) {
fprintf(stderr, _T("Error: termios verify failed\n"));
return false;
}
// A slight delay to allow things to settle.
CeCosThreadUtils::Sleep(10);
TRACE(_T("Done.\n"));
return true;
}
bool CeCosSerial::Flush (void)
{
return 0==tcflush((int) m_pHandle, TCIOFLUSH);
}
bool CeCosSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead)
{
if (!m_bBlockingReads) {
nRead = 0;
int n = read((int)m_pHandle, pBuf, nSize);
if (-1 == n) {
if (EAGAIN == errno)
return true;
ERROR(_T("Read failed: %d\n"), errno);
return false;
}
nRead = n;
#if 0
if (n>0) {
unsigned int i;
fprintf(stderr, "%d:", nRead);
for (i = 0; i < nRead; i++)
fprintf(stderr, "%02x!", ((unsigned char *)pBuf)[i]);
fprintf(stderr, "\n");
}
#endif
return true;
}
// Blocking reads: emulate the Windows semantics:
// If m_nTotalReadTimeout elapses before we see the first TCHAR,
// return.
// If m_nInterCharReadTimeout elapses after reading any
// subsequent TCHAR, return.
fd_set rfds;
FD_ZERO(&rfds);
FD_SET((int)m_pHandle, &rfds);
// Start with total timeout.
struct timeval tv;
tv.tv_sec = m_nTotalReadTimeout / 1000;
tv.tv_usec = (m_nTotalReadTimeout % 1000) * 1000;
unsigned char* pData = (unsigned char*) pBuf;
nRead = 0;
while (nSize) {
switch(select((int)m_pHandle + 1, &rfds, NULL, NULL, &tv)) {
case 1:
{
int n = read((int)m_pHandle, pData, nSize);
if (-1 == n && EAGAIN != errno) {
ERROR(_T("Read failed: %d\n"), errno);
return false; // FAILED
}
else if (n > 0) {
#if 0
unsigned int i;
fprintf(stderr, "%d:", nRead);
for (i = 0; i < nRead; i++)
fprintf(stderr, "%02x!", ((unsigned char *)pBuf)[i]);
fprintf(stderr, "\n");
#endif
nRead += n;
pData += n;
nSize -= n;
}
// Now use inter-char timeout.
tv.tv_sec = m_nInterCharReadTimeout / 1000;
tv.tv_usec = (m_nInterCharReadTimeout % 1000) * 1000;
}
break;
case 0:
return true; // Timeout
case -1:
ERROR(_T("Select failed: %d\n"), errno);
return false;
}
}
return true;
}
bool CeCosSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten)
{
bool rc;
int n=write((int)m_pHandle,pBuf,nSize);
if(-1==n){
nWritten=0;
if (errno == EAGAIN)
rc = true;
else
rc=false;
} else {
nWritten=n;
rc=true;
}
return rc;
}
bool CeCosSerial::ClearError()
{
return false;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -