Folks,
This is my first post here.
I am trying to configure a serial port under Ubuntu 10.04 to performer asynchronous serial I/O. The idea is to use the signal SIGIO to raise the flags for "data available to read" and "sand buffer is not in use". I would like to have my signal handler be able to tell whether the signal is caused by a "send" or a "receive", so I activated the SA_SIGINFO flag in the sa_flags field of the sigaction structure. Two additional arguments are passed to the signal-catching function. If the second argument is not equal to NULL, it points to a siginfo_t structure containing the reason why the signal was generated. the third argument points to a ucontext_t structure containing the receiving process's context when the signal was delivered.
I hook my linux machine to a windows machine via serial cable. However, my code is not working as I expected when I sent strings from my windows machine to the linux machine. The program succeeded in invoking the signal-catching function whenever new characters were received, and the received signal turns to be 29 (correspond to the signal SIGIO). But the member si_code in struct siginfo_t failed to be updated to reflect the reason of the signal. When characters are received, I expect the si_code to be up dated to POLL_IN (which is 1). But the actual value printed in the signal-catching program is 128, which does not make sense to me.
Can anybody take a look at my code and shine some light on it if at all possible? I cannot figure out what I missed.
Thanks.
Meng Fang
======================MY CODE===============================
Code:#include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <sys/types.h> #include <signal.h> #include <bits/siginfo.h> #define BAUDRATE B57600 #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 void signal_handler_IO (int status, siginfo_t *ioinfo, void *context ); volatile int STOP=FALSE; int wait_flag=TRUE; /* TRUE while no signal received */ int main() { int fd, res; struct termios oldtio,newtio; struct sigaction saio; /* definition of signal action */ char buf[255]; /* open the device to be non-blocking (read will return immediatly) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); /* install the signal handler before making the device asynchronous */ //saio.sa_handler = signal_handler_IO; sigemptyset(&saio.sa_mask); saio.sa_flags = saio.sa_flags|SA_SIGINFO; saio.sa_restorer = NULL; saio.sa_sigaction = signal_handler_IO; sigaction(SIGIO,&saio,NULL); /* allow the process to receive SIGIO */ fcntl(fd, F_SETOWN, getpid()); /* Make the file descriptor asynchronous (the manual page says only O_APPEND and O_NONBLOCK, will work with F_SETFL...) */ fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&oldtio); /* save current port settings */ /* set new port settings for canonical input processing */ newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* loop while waiting for input. normally we would do something useful here */ while (STOP==FALSE) { printf(".");usleep(100000); /* after receiving SIGIO, wait_flag = FALSE, input is available and can be read */ if (wait_flag==FALSE) { res = read(fd,buf,255); buf[res]=0; printf(":%s:%d\n", buf, res); if (res==1) STOP=TRUE; /* stop loop if only a CR was input */ wait_flag = TRUE; /* wait for new input */ } } /* restore old port settings */ tcsetattr(fd,TCSANOW,&oldtio); return 1; } /*************************************************************************** * signal handler. sets wait_flag to FALSE, to indicate above loop that * * characters have been received. * ***************************************************************************/ void signal_handler_IO (int status, siginfo_t *ioinfo, void * context ) { switch (ioinfo->si_code) { case POLL_IN: printf("signal received for input chars.sig:%d -%d\n",status, ioinfo->si_code); wait_flag = FALSE; break; case POLL_OUT: default: printf("signal received for something else.sig:%d -%d\n",status, ioinfo->si_code); break; } }



LinkBack URL
About LinkBacks


