⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//// 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.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#ifdef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/exception.h>#include <cc++/thread.h>#include <cc++/file.h>#ifndef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/serial.h>#include "private.h"#include <cstdlib>#include <climits>#ifdef	WIN32#define	B256000		CBR_256000#define	B128000		CBR_128000#define	B115200		CBR_115200#define B57600		CBR_57600#define	B56000		CBR_56000#define	B38400		CBR_38400#define	B19200		CBR_19200#define	B14400		CBR_14400#define	B9600		CBR_9600#define	B4800		CBR_4800#define	B2400		CBR_2400#define	B1200		CBR_1200#define	B600		CBR_600#define	B300		CBR_300#define	B110		CBR_110#include <io.h>#include <fcntl.h>#else#include <sys/ioctl.h>#include <termios.h>#endif#include <cerrno>#include <iostream>#ifdef	CCXX_NAMESPACESnamespace ost {using std::streambuf;using std::iostream;using std::ios;#endif#ifndef	MAX_INPUT#define	MAX_INPUT 255#endif#ifndef MAX_CANON#define MAX_CANON MAX_INPUT#endif#ifdef	__FreeBSD__#undef	_PC_MAX_INPUT#undef	_PC_MAX_CANON#endif#if defined(__QNX__)#define CRTSCTS (IHFLOW | OHFLOW)#endif#if defined(_THR_UNIXWARE) || defined(__hpux) || defined(_AIX)  #include <sys/termiox.h>#define	CRTSCTS	(CTSXON | RTSXOFF)#endif// IRIX#ifndef	CRTSCTS#ifdef	CNEW_RTSCTS#define	CRTSCTS (CNEW_RTSCTS)#endif#endif#if defined(CTSXON) && defined(RTSXOFF) && !defined(CRTSCTS) #define	CRTSCTS (CTSXON | RTSXOFF)#endif#ifndef	CRTSCTS#define	CRTSCTS	0#endifSerial::Serial(const char *fname){	initSerial();	open(fname);#ifdef	WIN32	if(dev == INVALID_HANDLE_VALUE)#else	if(dev < 0)#endif	{		error(errOpenFailed);		return;	}#ifdef	WIN32    COMMTIMEOUTS  CommTimeOuts ;    GetCommTimeouts(dev, &CommTimeOuts);//    CommTimeOuts.ReadIntervalTimeout = MAXDWORD;    CommTimeOuts.ReadIntervalTimeout = 0;    CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;    CommTimeOuts.ReadTotalTimeoutConstant = 0;    CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;    CommTimeOuts.WriteTotalTimeoutConstant = 1000;    SetCommTimeouts(dev, &CommTimeOuts) ;#else		if(!isatty(dev))	{		Serial::close();		error(errOpenNoTty);		return;	}#endif}Serial::~Serial(){	endSerial();}void Serial::initConfig(void){#ifdef	WIN32#define ASCII_XON       0x11#define ASCII_XOFF      0x13	DCB * attr = (DCB *)current;	DCB * orig = (DCB *)original;    attr->DCBlength = sizeof(DCB);    orig->DCBlength = sizeof(DCB);    GetCommState(dev, orig);    GetCommState(dev, attr);    attr->DCBlength = sizeof(DCB);    attr->BaudRate = 1200;    attr->Parity = NOPARITY;    attr->ByteSize = 8;    attr->XonChar = ASCII_XON;    attr->XoffChar = ASCII_XOFF;    attr->XonLim = 100;    attr->XoffLim = 100;    attr->fOutxDsrFlow = 0;    attr->fDtrControl = DTR_CONTROL_ENABLE;    attr->fOutxCtsFlow = 1;    attr->fRtsControl = RTS_CONTROL_ENABLE;    attr->fInX = attr->fOutX = 0;    attr->fBinary = true;    attr->fParity = true;    SetCommState(dev, attr);#else	struct termios *attr = (struct termios *)current;	struct termios *orig = (struct termios *)original;	long ioflags = fcntl(dev, F_GETFL);	tcgetattr(dev, (struct termios *)original);	tcgetattr(dev, (struct termios *)current);	attr->c_oflag = attr->c_lflag = 0;	attr->c_cflag = CLOCAL | CREAD | HUPCL;	attr->c_iflag = IGNBRK;	memset(attr->c_cc, 0, sizeof(attr->c_cc));	attr->c_cc[VMIN] = 1;		// inherit original settings, maybe we should keep more??	cfsetispeed(attr, cfgetispeed(orig));	cfsetospeed(attr, cfgetospeed(orig));	attr->c_cflag |= orig->c_cflag & (CRTSCTS | CSIZE | PARENB | PARODD | CSTOPB);	attr->c_iflag |= orig->c_iflag & (IXON | IXANY | IXOFF);		tcsetattr(dev, TCSANOW, attr);	fcntl(dev, F_SETFL, ioflags & ~O_NDELAY);#if defined(TIOCM_RTS) && defined(TIOCMODG)	int mcs = 0;	ioctl(dev, TIOCMODG, &mcs);	mcs |= TIOCM_RTS;	ioctl(dev, TIOCMODS, &mcs);#endif	#ifdef	_COHERENT	ioctl(dev, TIOCSRTS, 0);#endif#endif	// WIN32}void Serial::restore(void){#ifdef	WIN32	memcpy(current, original, sizeof(DCB));	SetCommState(dev, (DCB *)current);#else	memcpy(current, original, sizeof(struct termios));	tcsetattr(dev, TCSANOW, (struct termios *)current);#endif}void Serial::initSerial(void){	flags.thrown = false;	flags.linebuf = false;	errid = errSuccess;	errstr = NULL;	dev = INVALID_HANDLE_VALUE;#ifdef	WIN32	current = new DCB;	original = new DCB;#else	current = new struct termios;	original = new struct termios;#endif}void Serial::endSerial(void){#ifdef	WIN32	if(dev == INVALID_HANDLE_VALUE && original)		SetCommState(dev, (DCB *)original);	if(current)		delete (DCB *)current;	if(original)		delete (DCB *)original;#else	if(dev < 0 && original)		tcsetattr(dev, TCSANOW, (struct termios *)original);	if(current)		delete (struct termios *)current;	if(original)		delete (struct termios *)original;#endif	Serial::close();	current = NULL;	original = NULL;}Serial::Error Serial::error(Error err, char *errs){	errid = err;	errstr = errs;	if(!err)		return err;	if(flags.thrown)		return err; 	// prevents recursive throws 	flags.thrown = true;#ifdef	CCXX_EXCEPTIONS	if(Thread::getException() == Thread::throwObject)	        throw((Serial *)this);#ifdef	COMMON_STD_EXCEPTION	else if(Thread::getException() == Thread::throwException)	{		if(!errs)			errs = "";		throw SerException(String(errs));	}#endif#endif	return err;                                                             }int Serial::setPacketInput(int size, unsigned char btimer){#ifdef	WIN32	//	Still to be done......	return 0;#else#ifdef	_PC_MAX_INPUT	int max = fpathconf(dev, _PC_MAX_INPUT);#else	int max = MAX_INPUT;#endif	struct termios *attr = (struct termios *)current;	if(size > max)		size = max;	attr->c_cc[VEOL] = attr->c_cc[VEOL2] = 0;	attr->c_cc[VMIN] = (unsigned char)size;	attr->c_cc[VTIME] = btimer;	attr->c_lflag &= ~ICANON;	tcsetattr(dev, TCSANOW, attr);	bufsize = size;	return size;#endif}int Serial::setLineInput(char newline, char nl1){#ifdef	WIN32	//	Still to be done......	return 0;#else	struct termios *attr = (struct termios *)current;	attr->c_cc[VMIN] = attr->c_cc[VTIME] = 0;	attr->c_cc[VEOL] = newline;	attr->c_cc[VEOL2] = nl1;	attr->c_lflag |= ICANON;	tcsetattr(dev, TCSANOW, attr);#ifdef _PC_MAX_CANON	bufsize = fpathconf(dev, _PC_MAX_CANON);#else	bufsize = MAX_CANON;#endif	return bufsize;#endif}void Serial::flushInput(void){#ifdef	WIN32	PurgeComm(dev, PURGE_RXABORT | PURGE_RXCLEAR);#else	tcflush(dev, TCIFLUSH);#endif}void Serial::flushOutput(void){#ifdef	WIN32	PurgeComm(dev, PURGE_TXABORT | PURGE_TXCLEAR);#else	tcflush(dev, TCOFLUSH);#endif}void Serial::waitOutput(void){#ifdef	WIN32#else	tcdrain(dev);#endif}Serial &Serial::operator=(const Serial &ser){	Serial::close();	if(ser.dev < 0)		return *this;#ifdef	WIN32	HANDLE process = GetCurrentProcess();	int result = DuplicateHandle(process, ser.dev, process, &dev, DUPLICATE_SAME_ACCESS, 0, 0);	if (0 == result)	{		memcpy(current, ser.current, sizeof(DCB));		memcpy(original, ser.original, sizeof(DCB));	}#else	dev = dup(ser.dev);	memcpy(current, ser.current, sizeof(struct termios));	memcpy(original, ser.original, sizeof(struct termios));#endif	return *this;}void Serial::open(const char * fname){#ifndef	WIN32	int cflags = O_RDWR | O_NDELAY;	dev = ::open(fname, cflags);	if(dev > -1)		initConfig();#else    // open COMM device    dev = CreateFile(fname,                    GENERIC_READ | GENERIC_WRITE,                    0,                    // exclusive access                    NULL,                 // no security attrs                    OPEN_EXISTING,                    FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,                    NULL);	if(dev != INVALID_HANDLE_VALUE)		initConfig();#endif}#ifdef	WIN32int Serial::aRead(char * Data, const int Length){	unsigned long	dwLength = 0, dwError, dwReadLength;	COMSTAT	cs;    OVERLAPPED ol;        // Return zero if handle is invalid    if(dev == INVALID_HANDLE_VALUE)        return 0;    // Read max length or only what is available    ClearCommError(dev, &dwError, &cs);    // If not requiring an exact byte count, get whatever is available    if(dwLength > (int)cs.cbInQue)        dwReadLength = cs.cbInQue;    else        dwReadLength = Length;    memset(&ol, 0, sizeof(OVERLAPPED));    ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        if(dwReadLength > 0)    {        if(ReadFile(dev, Data, dwReadLength, &dwLength, &ol) == FALSE)         {            if(GetLastError() == ERROR_IO_PENDING)            {                WaitForSingleObject(ol.hEvent, INFINITE);                GetOverlappedResult(dev, &ol, &dwLength, TRUE);            }            else                ClearCommError(dev, &dwError, &cs);        }    }            if(ol.hEvent != INVALID_HANDLE_VALUE)        CloseHandle(ol.hEvent);        	return dwLength;}int Serial::aWrite(const char * Data, const int Length){	COMSTAT	cs;	unsigned long dwError = 0;    OVERLAPPED ol;	// Clear the com port of any error condition prior to read	ClearCommError(dev, &dwError, &cs);	unsigned long retSize = 0;        memset(&ol, 0, sizeof(OVERLAPPED));    ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);	    if(WriteFile(dev, Data, Length, &retSize, &ol) == FALSE)    {        if(GetLastError() == ERROR_IO_PENDING)        {            WaitForSingleObject(ol.hEvent, INFINITE);            GetOverlappedResult(dev, &ol, &retSize, TRUE);        }        else            ClearCommError(dev, &dwError, &cs);    }        if(ol.hEvent != INVALID_HANDLE_VALUE)        CloseHandle(ol.hEvent);        	return retSize;}#elseint Serial::aRead(char *Data, const int Length){	return ::read(dev, Data, Length);}int Serial::aWrite(const char *Data, const int Length){	return ::write(dev, Data, Length);}#endifvoid Serial::close(){#ifdef	WIN32	CloseHandle(dev);#else	::close(dev);#endif	dev = INVALID_HANDLE_VALUE;	}/*const int iAsync::getTimeOuts(unsigned long & readTimeout, unsigned long & writeTimeout){    return GetCommTimeouts(_TheHandle, &CommTimeOuts);}const int iAsync::setTimeOuts(unsigned long readTimeout, unsigned long writeTimeout){    COMMTIMEOUTS  CommTimeOuts ;    getTimeOuts(CommTimeOuts);    CommTimeOuts.ReadIntervalTimeout = readTimeout;    CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;    CommTimeOuts.ReadTotalTimeoutConstant = 0;    CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;    CommTimeOuts.WriteTotalTimeoutConstant = 1000;    return GetCommTimeouts(_TheHandle, &CommTimeOuts);}    return SetCommTimeouts(_TheHandle, &CommTimeOuts) ;{    DCB        dcb ;    dcb.DCBlength = sizeof(DCB) ;    GetCommState(_TheHandle, &dcb) ;	// hardcode this stuff for now.....    dcb.BaudRate = _TheBaudrate;    dcb.ByteSize = 8;    dcb.Parity   = NOPARITY;    dcb.StopBits = ONESTOPBIT;    dcb.fOutxDsrFlow = 0;    dcb.fDtrControl = DTR_CONTROL_ENABLE ;    dcb.fOutxCtsFlow = 1;    dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;    dcb.fInX = dcb.fOutX = 0;    dcb.XonChar = ASCII_XON;    dcb.XoffChar = ASCII_XOFF;    dcb.XonLim = 100;    dcb.XoffLim = 100;    // other various settings    dcb.fBinary = TRUE;    dcb.fParity = TRUE;    GetCommState(_TheHandle, &dcb) ;    dcb.DCBlength = sizeof(DCB) ;    dcb.BaudRate = _TheBaudrate;    SetCommState(_TheHandle, &dcb) ;}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -