Thread: Asynchronous Serial I/O

  1. #1
    Registered User
    Join Date
    Oct 2010

    Asynchronous Serial I/O


    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.


    Meng Fang

    ======================MY 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;
            saio.sa_flags = saio.sa_flags|SA_SIGINFO;
            saio.sa_restorer = NULL;
            saio.sa_sigaction = signal_handler_IO;
            /* 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;
            tcflush(fd, TCIFLUSH);
            /* loop while waiting for input. normally we would do something
               useful here */
            while (STOP==FALSE) {
              /* after receiving SIGIO, wait_flag = FALSE, input is available
                 and can be read */
              if (wait_flag==FALSE) {
                res = read(fd,buf,255);
                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 */
            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;
            case POLL_OUT:
            printf("signal received for something else.sig:%d -%d\n",status, ioinfo->si_code);
    Last edited by Salem; 10-13-2010 at 01:49 AM. Reason: Added code tags - learn to use them yourself

  2. #2
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Personally, I try to avoid SIGIO because it's not portable, and, well, signals are disgusting.

    I don't know what's causing the problem, but I advise using poll() instead of SIGIO. If you must preform a simultaneous operation that won't realistically be able to check the descriptor's status, create another thread. I love threads, they are an easy way to solve a lot of problems. ;-)
    I just want to use my computer in a productive manner, not learn how to use it. Elysia
    A year spent in artificial intelligence is enough to make one believe in God. Alan Jay Perlis

  3. #3
    Registered User
    Join Date
    Oct 2010

    Thank you so much for your advices. The "poll()" idea you brought up is really great! I used that function and solved my problem!!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Synchronous and asynchronous I/O
    By starcatcher in forum Windows Programming
    Replies: 4
    Last Post: 04-11-2010, 10:57 PM
  2. Asynchronous serial port (or SerialPortStream)
    By Perspective in forum C# Programming
    Replies: 0
    Last Post: 07-31-2008, 11:14 AM
  3. Recommend some asynchronous I/O tutorial?
    By George2 in forum Windows Programming
    Replies: 8
    Last Post: 01-29-2008, 07:11 PM
  4. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM
  5. Carrying out Serial I/O btw 2 comps using interrupts
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 06-06-2002, 11:28 AM