📄 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 // UNIXString 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 + -