I am trying to set the interruption for a serial port in ubuntu (in program written in C), but it does not work. I have checked that the serial communication works correctly without the interruption, so I may be setting something wrong. The code is the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <errno.h>
#include <termios.h>
void signal_handler_IO (int status); /* definition of signal handler */
int n;
int fd;
int connected;
struct termios termAttr;
struct sigaction saio;
int main(int argc, char *argv[])
{
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyO1\n");
exit(1);
}
saio.sa_handler = signal_handler_IO;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETFL, FNDELAY);
fcntl(fd, F_SETOWN, getpid());
tcgetattr(fd,&termAttr);
baudRate = B115200;
cfsetispeed(&termAttr,B115200);
cfsetospeed(&termAttr,B115200);
termAttr.c_cflag &= ~PARENB;
termAttr.c_cflag &= ~CSTOPB;
termAttr.c_cflag &= ~CSIZE;
termAttr.c_cflag |= CS8;
termAttr.c_cflag |= (CLOCAL | CREAD);
termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termAttr.c_iflag &= ~(IXON | IXOFF | IXANY);
termAttr.c_oflag &= ~OPOST;
tcsetattr(fd,TCSANOW,&termAttr);
printf("UART1 configured....\n");
connected = 1;
while(connected == 1){
// some code
}
close(fd);
exit(0);
}
void signal_handler_IO (int status)
{
printf("received data from UART.\n");
}
So anytime time another device send a message through the configured port, the message "received data from UART." is never displayed.
Any suggestion to solve this problem? Also, how does the system relate the interruption with the serial port?, I have read about signal.h but I have not found an answer for that. I got the interruption idea from this page: http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html
Thanks in advance for any help. Thanks in advance.
I have found that a piece of code is missing for the original code to work as expected. The code below is working on Linux compiled with gcc. The added line of code is the one marked with
/**<<<<<<------This line made it work.**/
One line was also commented out :
//baudRate = B115200;
.The output from the program was:
I hope that works for you too.
The serial port interrupt is written inside the device part of the serial driver in linux kernel. The interrupt is handled by the driver itself , so you can have not control over it.
What the above program is doing is , notifying you through a signal , when a receive interrupt of the serial part device is triggered.
The above signal handling is not related to interrupts , it is more of even handling. First you register , your program , to get a signal when an io interrupt occours , the signal handler in your program will then display the printf message.
I think the signal handling in your program , is not implemented properly Just correct the signal parts of your program
The problem is that you're disabling signals from the file descriptor by clearing the
FASYNC
flag withF_SETFL
. You need to set that if you want to get signals:Also, you might want to use the POSIX names for these flags (
O_NDELAY
andO_ASYNC
) rather than the BSD names for more portability, though either will work on Linux.