Below I mocked up a basic C serial program for linux. My requirement is to toggle the RTS port to high on a rs-232 serial port, wait 5 milliseconds, send a hart frame (which consists of 11 bytes), wait 5 milliseconds, and then toggle the RTS port to low. Now the requirement seems simple. But I am wondering if the sleep function is exactly the same thing as "waiting". The sleep function suspends the current thread for n seconds. If the thread is suspended, does that also suspend the influence on the RTS port? If it won't have any affect on the RTS signal, I still would like to know if there is a better way to wait a few milliseconds when communicating across an rs-232 serial port. Thanks.
Code:
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <unistd.h> /* Sleep Function */
#define BUFFER_SIZE 1000
unsigned char Buffer[BUFFER_SIZE];
struct termios options;
int open_port()
{
int fd; /* File descriptor for the port */
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
} else {
fcntl(fd, F_SETFL, 0);
return (fd);
}
}
void configure_port(int fd)
{
tcgetattr(fd, &options);
cfsetispeed(&options, B1200);
cfsetospeed(&options, B1200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB
options.c_cflag |= PARODD
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CNEW_RTSCTS;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);
}
void raise_rts_signal(int fd)
{
int status;
ioctl(fd, TIOCMGET, &status);
status &= TIOCM_RTS;
ioctl(fd, TIOCMSET, status);
}
void drop_rts_signal(int fd)
{
int status;
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, status);
}
int send_hart_frame(int fd)
{
int bytes;
unsigned char hart_buff[11] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x0, 0x0, 0x0, 0x2 };
bytes = write(fd, hart_buff, 11);
if (bytes != 11)
return -1;
else
return 0;
}
int get_bytes_available(int fd, unsigned char *Buf)
{
int bytes;
ioctl(fd, FIONREAD, &bytes);
if (bytes >= 1)
{
bytes = read(fd, Buf, BUFFER_SIZE);
if (bytes < 0)
return -1;
printf("Received Bytes from Hart: %s", Buf);
return 0;
}
else
printf("No data available.");
return -1;
}
int main(void)
{
int fd = open_port();
configure_port(fd);
while(1)
{
raise_rts_signal(fd);
// sleep 5 milliseconds
sleep(0.005);
send_hart_frame(fd);
// sleep 5 milliseconds
sleep(0.005);
drop_rts_signal(fd);
// now poll for bytes available in serial buffer
get_bytes_available(fd, Buffer);
// try again in 30 seconds
sleep(30);
}
close(fd);
return 0;
}