Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - serial port support for vmin: (3 Items)
   
serial port support for vmin  
We have an application which works under linux, but not qnx6.  It talks to a number of serial ports (max 16) and waits 
on a select for a port to receive data.  Each data packet is 12 bytes in length, and is binary data.  Data rate is 38k4 
and running at full data rate.  We set vmin to 12 in order that the select doesn't get triggered before 12 bytes are 
available.
This works under linux, but under qnx6 the select always triggers on the first byte, not the 12th as it should do.  
Consequently if O_NONBLOCK is set then EAGAIN is returned on the subsequent read or if O_NONBLOCK is clear then the read
 blocks until all the data is in or forever if the sending end aborts.  Setting vtime overrides vmin so can't be used 
and the timeout is too long for us anyway.
Attached is a sample program we are using to test this compiled on linux with
ntox86-gcc -o testselect-q testselect.c

Any ideas?  It appears to us that the character/select interface is broken.
Attachment: Text testselect.c 2.56 KB
Re: serial port support for vmin  
> We have an application which works under linux, but not qnx6.  It talks to a 
> number of serial ports (max 16) and waits on a select for a port to receive 
> data.  Each data packet is 12 bytes in length, and is binary data.  Data rate 
> is 38k4 and running at full data rate.  We set vmin to 12 in order that the 
> select doesn't get triggered before 12 bytes are available.
> This works under linux, but under qnx6 the select always triggers on the first
>  byte, not the 12th as it should do.  Consequently if O_NONBLOCK is set then 
> EAGAIN is returned on the subsequent read or if O_NONBLOCK is clear then the 
> read blocks until all the data is in or forever if the sending end aborts.  
> Setting vtime overrides vmin so can't be used and the timeout is too long for 
> us anyway.
> Attached is a sample program we are using to test this compiled on linux with
> ntox86-gcc -o testselect-q testselect.c
> 
> Any ideas?  It appears to us that the character/select interface is broken.


Don't know about select and vmin stuff, can't help you there.   here is what I would.  Start a thread for each serial 
port and use readcond().  This is more efficient then using select which add extra context switch and message passing.

The parsing of the data can be handle by the thread.  If you have more then 1 core, you'll get better performance/
througput.



Re: serial port support for vmin  
On Wed, Apr 02, 2008 at 03:27:55AM -0400, Mario Charest wrote:
> > We have an application which works under linux, but not qnx6.  It talks to a 
> > number of serial ports (max 16) and waits on a select for a port to receive 
> > data.  Each data packet is 12 bytes in length, and is binary data.  Data rate 
> > is 38k4 and running at full data rate.  We set vmin to 12 in order that the 
> > select doesn't get triggered before 12 bytes are available.
> > This works under linux, but under qnx6 the select always triggers on the first
> >  byte, not the 12th as it should do.  Consequently if O_NONBLOCK is set then 
> > EAGAIN is returned on the subsequent read or if O_NONBLOCK is clear then the 
> > read blocks until all the data is in or forever if the sending end aborts.  
> > Setting vtime overrides vmin so can't be used and the timeout is too long for 
> > us anyway.
> > Attached is a sample program we are using to test this compiled on linux with
> > ntox86-gcc -o testselect-q testselect.c
> > 
> > Any ideas?  It appears to us that the character/select interface is broken.
> 
> 
> Don't know about select and vmin stuff, can't help you there.   here is what I would.  Start a thread for each serial 
port and use readcond().  This is more efficient then using select which add extra context switch and message passing.
> 
> The parsing of the data can be handle by the thread.  If you have more then 1 core, you'll get better performance/
througput.

This should work though.  I've made PR 56779 on this.  Here's
another self contained test case.

-seanb


#include <err.h>
#include <termios.h>
#include <unix.h>
#include <errno.h>
#include <pthread.h>
#include <sys/poll.h>

#define OURVMIN 4

int
main(void)
{
	int		master, slave, vmin, ret;
	struct termios	tiold, tinew;
	char		buf[OURVMIN];
	struct pollfd	pollfd;

	vmin = 4;

	if (openpty(&master, &slave, NULL, NULL, NULL) == -1)
		err(1, "openpty");

	if (tcgetattr(slave, &tiold) == -1)
		err(1, "tcgetattr");

	memcpy(&tinew, &tiold, sizeof(tinew));
	cfmakeraw(&tinew);

	tinew.c_cc[VMIN] = OURVMIN;

	if (tcsetattr(slave, TCSANOW, &tinew) == -1)
		err(1, "tcsetattr");

	write(master, buf, 1);

	pollfd.fd = slave;
	pollfd.revents = 0;
	pollfd.events = POLLRDNORM;
	if ((ret = poll(&pollfd, 1, 1000)) != 0) {
		if (ret == -1)
			err(1, "poll");
		errx(1, "poll succeeded unexpectedly: ret = %d", ret);
	}

	write(master, buf, OURVMIN - 1);

	if ((ret = poll(&pollfd, 1, 1000)) != 1) {
		if (ret == -1)
			err(1, "poll");
		if (ret == 0)
			errx(1, "poll timed out");
		errx(1, "poll unexpected rval: %d", ret);
	}

	(void)tcsetattr(slave, TCSANOW, &tiold);

	printf("success\n");

	return 0;
}