sint32_t uart_open
(
char_t port[],
uint32_t baud,
boolean_t is_timeout_enabled,
uint32_t timeout
)
{
sint32_t fd;
/* Try to open the uart port */
fd = open(port, O_RDWR | O_NOCTTY);
if (fd == IO_error)
{
fprintf(stderr, "error, %s is unknown\n", port);
}
else
{
/*
* Apply the proper port settings to the port
*/
uart_setup(fd, baud, is_timeout_enabled, timeout);
fprintf(stderr, "%s at %lubps, ", port, baud);
fprintf(stderr, "opened\n");
}
return fd;
}
void uart_setup
(
sint32_t fd,
uint32_t baud,
boolean_t is_timeout_enabled,
uint32_t timeout
)
{
termios_t ios;
p_termios_t p_ios;
uint32_t iosbaud;
p_ios = &ios;
/* See what our baud rate is */
switch (baud)
{
case 1200:
iosbaud = B1200;
break;
case 9600:
iosbaud = B9600;
break;
case 19200:
iosbaud = B19200;
break;
case 38400:
iosbaud = B38400;
break;
case 115200:
iosbaud = B115200;
break;
case 230400:
iosbaud = B230400; /* untested */
break;
case 460800:
iosbaud = B460800; /* untested */
break;
default:
/* no deal with this baud rate */
fprintf(stderr, "[!] error: Unknown baud rate %lu\n", baud);
exit(1);
break;
}
/* Zero out the new port settings */
memset(p_ios, 0, sizeof(ios));
/* Create the new port settings */
ios.c_iflag = IGNBRK;
ios.c_oflag = 0;
ios.c_cflag = iosbaud | CS8 | HUPCL | CREAD | CLOCAL;
ios.c_lflag = 0;
if (is_timeout_enabled == True)
{
/*
* apply a timeout of 0.x sec (x deciseconds)
*/
ios.c_cc[VMIN] = 0;
ios.c_cc[VTIME] = timeout;
}
else
{
/*
* apply no timeout
*/
ios.c_cc[VMIN] = 1;
ios.c_cc[VTIME] = 0;
}
uart_set_timeout(fd, is_timeout_enabled);
/* Flush the input buffer to get rid of any lingering garbage */
tcflush(fd, TCIFLUSH);
/* Apply the new port settings */
tcsetattr(fd, TCSANOW, p_ios);
/* Flush the input buffer again */
tcflush(fd, TCIFLUSH);
}
/*
* POSIX Control Characters
* The c_cc character array contains control character definitions
* as well as timeout parameters.
* Constants are defined for every element of this array.
*
* Setting Software Flow Control Characters
*
* The VSTART and VSTOP elements of the c_cc array contain
* the characters used for software flow control. N
* ormally they should be set to DC1 (17) and DC3 (19),
* representing the defacto standard XON and XOFF characters.
*
* Setting Read Timeouts
* UNIX uart interface drivers provide the ability
* to specify character and packet timeouts.
* Timeouts are ignored in canonical input mode.
* Two elements of the c_cc array are used for timeouts: VMIN and VTIME.
*
* VMIN specifies the minimum number of characters to read.
* If it is set to 0, then the VTIME value specifies
* the time to wait for every character read.
* If it is non-zero, VTIME specifies
* the time to wait for the first character read.
* If a character is read within the time given,
* any read will block (wait) until all VMIN characters are read.
* That is, once the first character is read,
* the uart interface driver expects
* to receive an entire packet of characters (VMIN bytes total).
* If no character is read within the time allowed,
* then the call to read returns 0.
* VTIME specifies the amount of time to wait for incoming characters
* in tenths of seconds.
* If VTIME is set to 0 (the default),
* calls to read will block (wait) indefinitely
* unless the NDELAY option is set on the port with open or fcntl
*/
void uart_set_timeout
(
sint32_t fd,
boolean_t is_timeout_enabled
)
{
/*
* Reading Data from the Port
* Reading data from a port is a little trickier.
* When you operate the port in raw data mode,
* each read(2) system call will return
* however many characters are actually available in the uart input buffers.
* If no characters are available, the call will block (wait)
* until characters come in, an interval timer expires,
* or an error occurs.
* The read function can be made to return immediately
* by doing the following:
* fcntl(fd, F_SETFL, FNDELAY);
* The FNDELAY option causes the read function to return 0
* if no characters are available on the port.
*
* To restore normal (blocking) behavior,
* call fcntl() without the FNDELAY option:
* fcntl(fd, F_SETFL, 0);
*
* This is also used after opening a uart port with the O_NDELAY option.
*/
if (is_timeout_enabled isEqualTo True)
{
/*
* don't block uart read
*/
//fcntl(fd, F_SETFL, FNDELAY);
}
else
{
/*
* blocking behavior
*/
fcntl(fd, F_SETFL, 0);
}
}
this is a part of my actual linux side, i have enabled the timeout support for the serial