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

📄 serial.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		waitOutput();		setp(pbuf, pbuf + bufsize);	}	setg(gbuf, gbuf + bufsize, gbuf + bufsize);	return 0;}int TTYStream::overflow(int c){	unsigned char ch;	ssize_t rlen, req;	if(bufsize < 2)	{		if(c == EOF)			return 0;		ch = (unsigned char)(c);		rlen = aWrite((char *)&ch, 1);		if(rlen < 1)		{			if(rlen < 0)				clear(ios::failbit | rdstate());			return EOF;		}		else			return c;	}	if(!pbase())		return EOF;	req = (ssize_t)(pptr() - pbase());	if(req)	{		rlen = aWrite((char *)pbase(), req);		if(rlen < 1)		{			if(rlen < 0)				clear(ios::failbit | rdstate());			return EOF;		}		req -= rlen;	}		if(req)//		memmove(pptr(), pptr() + rlen, req);		memmove(pbuf, pbuf + rlen, req);	setp(pbuf + req, pbuf + bufsize);	if(c != EOF)	{		*pptr() = (unsigned char)c;		pbump(1);	}	return c;}bool TTYStream::isPending(Pending pending, timeout_t timer){//	if(pending == pendingInput && in_avail())//		return true;//	else if(pending == pendingOutput)//		flush();	return Serial::isPending(pending, timer);}ttystream::ttystream() :TTYStream(){	setError(false);}ttystream::ttystream(const char *name) :TTYStream(){	setError(false);	open(name);}void ttystream::close(void){#ifdef	WIN32	if (INVALID_HANDLE_VALUE == dev)#else	if(dev < 0)#endif		return;	endStream();	restore();	TTYStream::close();}void ttystream::open(const char *name){	const char *cpp;	char *cp;	char pathname[256];	size_t namelen;	long opt;	if (INVALID_HANDLE_VALUE != dev)	{		restore();		close();	}	cpp = strrchr(name, ':');	if(cpp)		namelen = cpp - name;	else		namelen = strlen(name);	cp = pathname;#ifndef	WIN32	if(*name != '/')	{		strcpy(pathname, "/dev/");		cp += 5;	}	if((cp - pathname) + namelen > 255)	{		error(errResourceFailure);		return;	}#endif	setString(cp, pathname - cp + sizeof(pathname), name);	cp += namelen;#ifdef	WIN32	*cp++ = ':';#endif	*cp = 0;		Serial::open(pathname);	if(INVALID_HANDLE_VALUE == dev)	{		error(errOpenFailed);		return;	}	allocate();	setString(pathname, sizeof(pathname), name + namelen);	cp = pathname + 1;	if(*pathname == ':')		cp = strtok(cp, ",");	else		cp = NULL;	while(cp)	{		switch(*cp)		{		case 'h':		case 'H':			setFlowControl(flowHard);			break;		case 's':		case 'S':			setFlowControl(flowSoft);			break;		case 'b':		case 'B':			setFlowControl(flowBoth);			break;		case 'n':		case 'N':			setParity(parityNone);			break;		case 'O':		case 'o':			setParity(parityOdd);			break;		case 'e':		case 'E':			setParity(parityEven);			break;		case '0':		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':			opt = atol(cp);			if(opt == 1 || opt == 2)			{				setStopBits((int)opt);				break;			}			if(opt > 4 && opt < 9)			{				setCharBits((int)opt);				break;			}			setSpeed(opt);			break;		default:			error(errOptionInvalid);		}		cp = strtok(NULL, ","); 	}			}TTYSession::TTYSession(const char *filename, int pri, int stack) :Thread(pri, stack), TTYStream(filename){	setError(false);}TTYSession::~TTYSession(){	terminate();	endSerial();}#ifndef	WIN32//	Not supporting this right now........//SerialPort::SerialPort(SerialService *svc, const char *name) :Serial(name),detect_pending(true),detect_output(false),detect_disconnect(true){	next = prev = NULL;	service = NULL;#ifdef	WIN32	if(INVALID_HANDLE_VALUE != dev)#else	if(dev > -1)#endif	{		setError(false);		service = svc;		svc->attach(this);	}}SerialPort::~SerialPort(){	if(service)		service->detach(this);	endSerial();}void SerialPort::expired(void){}void SerialPort::pending(void){}void SerialPort::disconnect(void){}void SerialPort::output(void){}void SerialPort::setTimer(timeout_t ptimer){	TimerPort::setTimer(ptimer);	service->update();}void SerialPort::incTimer(timeout_t ptimer){	TimerPort::incTimer(ptimer);	service->update();}void SerialPort::setDetectPending( bool val ){	if ( detect_pending != val ) {		detect_pending = val;#ifdef USE_POLL		if ( ufd ) {			if ( val ) {				ufd->events |= POLLIN;			} else {				ufd->events &= ~POLLIN;			}		}#endif		service->update();	}}void SerialPort::setDetectOutput( bool val ){	if ( detect_output != val ) {		detect_output = val;#ifdef  USE_POLL		if ( ufd ) {			if ( val ) {				ufd->events |= POLLOUT;			} else {				ufd->events &= ~POLLOUT;			}		}#endif		service->update();	}}SerialService::SerialService(int pri, size_t stack, const char *id) :Thread(pri, stack), Mutex(id){	long opt;	first = last = NULL;	count = 0;	FD_ZERO(&connect);	::pipe(iosync);	hiwater = iosync[0] + 1;	FD_SET(iosync[0], &connect);	opt = fcntl(iosync[0], F_GETFL);	fcntl(iosync[0], F_SETFL, opt | O_NDELAY);	}SerialService::~SerialService(){	update(0);	terminate();	while(first)		delete first;}void SerialService::onUpdate(unsigned char flag){}void SerialService::onEvent(void){}void SerialService::onCallback(SerialPort *port){}void SerialService::attach(SerialPort *port){	enterMutex();#ifdef	USE_POLL	port->ufd = 0;#endif	if(last)		last->next = port;	port->prev = last;	last = port;	FD_SET(port->dev, &connect);	if(port->dev >= hiwater)		hiwater = port->dev + 1;	if(!first)	{		first = port;		leaveMutex();		++count;		start();	}	else	{		leaveMutex();		update();		++count;	}}void SerialService::detach(SerialPort *port){	enterMutex();#ifndef USE_POLL	FD_CLR(port->dev, &connect);#endif	if(port->prev)		port->prev->next = port->next;	else		first = port->next;			if(port->next)		port->next->prev = port->prev;	else		last = port->prev;	--count;	leaveMutex();	update();}void SerialService::update(unsigned char flag){	::write(iosync[1], (char *)&flag, 1);}		void SerialService::run(void){	timeout_t timer, expires;	SerialPort *port;	unsigned char buf;#ifdef	USE_POLL		Poller	mfd;	pollfd *p_ufd;	int lastcount = 0;	// initialize ufd in all attached ports :	// probably don't need this but it can't hurt.	enterMutex();	port = first;	while(port)	{		port->ufd = 0;		port = port->next;	}	leaveMutex();	#else	struct timeval timeout, *tvp;	fd_set inp, out, err;	int dev;	FD_ZERO(&inp);	FD_ZERO(&out);	FD_ZERO(&err);#endif	setCancel(cancelDeferred);	for(;;)	{		timer = TIMEOUT_INF;		while(1 == ::read(iosync[0], (char *)&buf, 1))		{			if(buf)			{				onUpdate(buf);				continue;			}			setCancel(cancelImmediate);			sleep(TIMEOUT_INF);			exit();		}#ifdef	USE_POLL		bool	reallocate = false;		enterMutex();		onEvent();		port = first;		while(port)		{			onCallback(port);			if ( ( p_ufd = port->ufd ) ) {				if ( ( POLLHUP | POLLNVAL ) & p_ufd->revents ) {					// Avoid infinite loop from disconnected sockets					port->detect_disconnect = false;					p_ufd->events &= ~POLLHUP;					port->disconnect();				}					if ( ( POLLIN | POLLPRI ) & p_ufd->revents )					port->pending();					if ( POLLOUT & p_ufd->revents )					port->output();			} else {				reallocate = true;			}retry:			expires = port->getTimer();			if(expires > 0)				if(expires < timer)					timer = expires;			if(!expires)			{				port->endTimer();				port->expired();				goto retry;			}			port = port->next;		}		//		// reallocate things if we saw a ServerPort without		// ufd set !		if ( reallocate || ( ( count + 1 ) != lastcount ) ) {			lastcount = count + 1;			p_ufd = mfd.getList( count + 1 );			// Set up iosync polling			p_ufd->fd = iosync[0];			p_ufd->events = POLLIN | POLLHUP;			p_ufd ++;						port = first;			while(port)			{				p_ufd->fd = port->dev;				p_ufd->events =					( port->detect_disconnect ? POLLHUP : 0 )					| ( port->detect_output ? POLLOUT : 0 )					| ( port->detect_pending ? POLLIN : 0 )				;				port->ufd = p_ufd;				p_ufd ++;				port = port->next;			}		}		leaveMutex();		poll( mfd.getList(), count + 1, timer );#else		enterMutex();		onEvent();		port = first;		while(port)		{			onCallback(port);			dev = port->dev;			if(FD_ISSET(dev, &err)) {				port->detect_disconnect = false;				port->disconnect();			}			if(FD_ISSET(dev, &inp))				port->pending();			if(FD_ISSET(dev, &out))				port->output();retry:			expires = port->getTimer();			if(expires > 0)				if(expires < timer)					timer = expires;			if(!expires)			{				port->endTimer();				port->expired();				goto retry;			}			port = port->next;		}		FD_ZERO(&inp);		FD_ZERO(&out);		FD_ZERO(&err);		int so;		port = first;		while(port)		{			so = port->dev;			if(port->detect_pending)				FD_SET(so, &inp);			if(port->detect_output)				FD_SET(so, &out);			if(port->detect_disconnect)				FD_SET(so, &err);			port = port->next;		}						leaveMutex();		if(timer == TIMEOUT_INF)			tvp = NULL;		else		{			tvp = &timeout;			timeout.tv_sec = timer / 1000;			timeout.tv_usec = (timer % 1000) * 1000;		}		select(hiwater, &inp, &out, &err, tvp);		#endif	}}						#endif		#ifdef	CCXX_NAMESPACES}#endif/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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