Hi folks,
I'm working on an application that runs under uClinux on a custom board
(arm7) and deals with serial port. It's kind of a data acquisition app
that uses serial port to yield the data from remote sensors.
Application uses "request->response" technique: sends an appropiate
command to the sensors periodically and waits response from them.
Sensors work fine and respond within 15-25 ms right after they get the
command. But application doesn't work as we want. The problem is that
the time between "write" syscall (write to serial port) and the moment
when the data physically appears on a pin is huge - up to 200 ms and it
varies from one cycle to another. And it's unacceptable for us.
You may find the configuration of serial port which i'm using at the
moment. I have only 2 questions to the whole maillist:
1. how to decrease this latency down to ... 50 ms (i guess, would be fine)?
2. what information do you want me to provide to help fixing this issue?
Thank you!
--
Agava Design Bureau
620026, Russia, Yekaterinburg, Bazhova str. 174
tel./fax. +7 (343) 262-92-76, 262-92-78, 262-92-87
http://kb-agava.ru
int set_up_comms( char *device, int baud_i,
char *parity, int stopbits, int readtimeout )
{
int ttyfd;
struct termios settings;
struct serial_struct ser;
speed_t baud_rate;
/* get integral part (in seconds) of MODBUS reading timeout */
read_timeout_s = readtimeout / 1000;
/* get fractional part (in microseconds) of MODBUS reading timeout */
read_timeout_us = (readtimeout - read_timeout_s * 1000) * 1000;
#ifdef DEBUG
fprintf( stderr, "opening %s\n", device );
#endif
switch( baud_i )
{
case 110:
baud_rate = B110;
char_interval_timeout = TO_B110;
break;
case 300:
baud_rate = B300;
char_interval_timeout = TO_B300;
break;
case 600:
baud_rate = B600;
char_interval_timeout = TO_B600;
break;
case 1200:
baud_rate = B1200;
char_interval_timeout = TO_B1200;
break;
case 2400:
baud_rate = B2400;
char_interval_timeout = TO_B2400;
break;
case 4800:
baud_rate = B4800;
char_interval_timeout = TO_B4800;
break;
case 9600: case 0:
baud_rate = B9600;
char_interval_timeout = TO_B9600;
break;
case 19200:
baud_rate = B19200;
char_interval_timeout = TO_B19200;
break;
case 38400:
baud_rate = B38400;
char_interval_timeout = TO_B38400;
break;
case 57600:
baud_rate = B57600;
char_interval_timeout = TO_B57600;
break;
case 115200:
baud_rate = B115200;
char_interval_timeout = TO_B115200;
break;
case 230400:
baud_rate = B230400;
char_interval_timeout = TO_B230400;
break;
case 460800:
baud_rate = B460800;
char_interval_timeout = TO_B460800;
break;
case 921600:
baud_rate = B921600;
char_interval_timeout = TO_B921600;
break;
default:
baud_rate = B9600;
char_interval_timeout = TO_B9600;
fprintf(stderr, "Unknown baud rate %d for %s.", baud_i,
device);
}
if(( ttyfd = open( device, O_RDWR | O_NOCTTY | O_NDELAY ) ) < 0 )
{
fprintf( stderr, "Error opening device %s. ", device );
fprintf( stderr, "Error no. %d \n",errno );
return -1;
}
ioctl( ttyfd, TIOCGSERIAL, &ser );
ser.flags |= ASYNC_LOW_LATENCY;
ioctl( ttyfd, TIOCSSERIAL, &ser );
#ifdef DEBUG
fprintf( stderr, "%s open\n", device );
#endif
bzero( &settings, sizeof(settings) );
cfsetispeed( &settings, baud_rate );/* Set the baud rate */
cfsetospeed( &settings, baud_rate );
settings.c_line = 0;
settings.c_iflag |= IGNBRK; /* ignore BREAK condition on input */
settings.c_iflag |= IGNPAR; /* ignore framing errors and parity
errors */
settings.c_iflag &= ~PARMRK;
settings.c_iflag &= ~INPCK; /* disable input parity checking */
settings.c_iflag &= ~ISTRIP; /* disable strip off eighth bit */
settings.c_iflag &= ~INLCR; /* don't map NL to CR-NL on input */
settings.c_iflag &= ~IGNCR; /* don't ignore carriage return(CR) on
input */
settings.c_iflag &= ~ICRNL; /* don't map CR to NL on input */
settings.c_iflag &= ~IUCLC; /* don't map uppercase->lowcase on input
*/
settings.c_iflag &= ~IXON; /* disable XON/XOFF flow control on input
*/
settings.c_iflag |= IXANY;
settings.c_iflag &= ~IXOFF; /* disable XON/XOFF flow control on
output */
settings.c_iflag &= ~IMAXBEL; /* not implemented in Linux */
settings.c_oflag &= ~OPOST; /* disable implementation-defined output
processing */
settings.c_oflag &= ~OLCUC; /* don't map uppercase->lowcase on
output */
settings.c_oflag &= ~ONLCR; /* don't map NL to CR-NL on output */
settings.c_oflag &= ~OCRNL; /* don't map CR to NL on output */
settings.c_oflag |= ONOCR; /* don't output CR at column 0 */
settings.c_oflag &= ~ONLRET;
settings.c_oflag &= ~OFILL; /* use a timed delay rather than send
fill chars */
settings.c_oflag &= ~OFDEL; /* not implemented in Linux */
settings.c_cflag &= ~CSIZE; /* mask the character size bits */
settings.c_cflag |= CS8; /* 8 data bits */
settings.c_cflag |= CLOCAL; /* ignore modem control lines */
settings.c_cflag |= CREAD; /* enable receiver */
settings.c_cflag &= ~HUPCL;
settings.c_cflag &= ~CRTSCTS; /* disable RTS/CTS (hardware) flow
control */
settings.c_lflag &= ~ISIG; /* disable generation of EOF and other
signals */
settings.c_lflag &= ~ICANON; /* disable canonical mode */
settings.c_lflag &= ~ECHO; /* disable echo input characters */
settings.c_lflag &= ~IEXTEN; /* disable implementation-defined input
processing */
/********** applying stopbits count settings ***************/
if( stopbits == 2 )
{
settings.c_cflag |= CSTOPB; /* explicitly set up 2 stopbits
*/
}
else
{
settings.c_cflag &= ~CSTOPB; /* one stopbit in any other
cases */
}
/*********** applying parity settings **********************/
if( strncmp( parity, "none", 4 ) == 0 )
{
settings.c_cflag &=~ PARENB;
settings.c_cflag &=~ PARODD;
}
else
if( strncmp( parity, "even", 4 ) == 0 )
{
settings.c_cflag |= PARENB;
settings.c_cflag &=~ PARODD;
}
else
{
settings.c_cflag |= PARENB;
settings.c_cflag |= PARODD;
}
settings.c_cc[VMIN] = 0; //4
settings.c_cc[VTIME] = 0; //1
tcflush(ttyfd, TCOFLUSH | TCIFLUSH );
if( tcsetattr( ttyfd, TCSANOW, &settings ) < 0 )
{
fprintf( stderr, "tcsetattr failed\n");
return -1;
}
return( ttyfd );
}
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev