SIGIO什么时候开火?

Ale*_*der 6 c linux

我正在尝试接收串行数据,但我无法确定时间。

当接收到串行数据时,SIGIO 何时触发 - 在接收到数据的第一个字节时,或者在接收到特定字符时(CR、NL...)?

设置串口数据:

/*  Open serial port.
*   O_RDONLY - Only receive data
*   O_NOCTTY - Leave process control to other 'jobs' for better portability.
*   O_NDELAY - Enable non-blocking read
*/
fd = open(PORT_PATHNAME, O_RDONLY | O_NOCTTY | O_NDELAY);
fd = open(PORT_PATHNAME, O_RDONLY | O_NOCTTY | O_NDELAY);
/* Set process ID, that will receive SIGIO signals for file desc. events */
fcntl (fd, F_SETOWN, getpid());
/* Enable generation of signals */
fcntl (fd, F_SETFL, O_ASYNC);

...

options.c_oflag &= ~OPOST;

/* Set terminal options using the file descriptor */
tcsetattr(fd, TCSANOW, &options);

struct termios options;
tcgetattr(fd, &options);

/* Set baudrate */
options.c_cflag = B115200;
Run Code Online (Sandbox Code Playgroud)

设置信号中断:

/* Add UART handler function */
saio.sa_handler = signal_handler_IO;
/* Non-zero used for calling sighandler on alternative stacks and so on */
saio.sa_flags = 0;
/* Not specified by POSIX -> not in use */
saio.sa_restorer = NULL;
/* Bind SIGIO (async I/O signals) to the defined structure */
int status = sigaction(SIGIO, &saio, NULL);
Run Code Online (Sandbox Code Playgroud)

Mar*_* G. 1

一旦收到一个字节的数据,SIGIO 就会触发。

这是在 Linux 上使用驱动程序测试的最小示例ftdi_sio

  #include <stdio.h>
  #include <stdlib.h>
  #include <fcntl.h>
  #include <time.h>
  #include <unistd.h>
  #include <termios.h>
  #include <errno.h>
  #include <string.h>
  #include <sys/types.h>
  #include <sys/uio.h>
  #include <signal.h>      
  #include <termios.h>     
  #include <unistd.h>     

  #define tty   "/dev/ttyUSB0"
  #define baudrate  B9600



  void byteCallback(int status);      // interrupt function 



  int main(){

    int ttyDev = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK);

    if (!ttyDev)
    {
      printf("couldn't open serial device");
      return -1;
    }
    struct sigaction byteAction;      // set the serial interrupt handler
    struct termios oldtio, newtio; 
    //create signal handler
    byteAction.sa_handler = byteCallback;
    sigemptyset(&byteAction.sa_mask); //sa_mask = 0
    byteAction.sa_flags = SA_RESTART;
    sigaction(SIGIO, &byteAction, NULL);

    //Allow process to detect SIGIO
    fcntl(ttyDev, F_SETOWN, getpid());
        fcntl(ttyDev, F_SETFL, FASYNC);


    tcgetattr(ttyDev, &oldtio); //backup current settings
    newtio.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
    newtio.c_cflag &= ~CRTSCTS; //disable hw flow control
    newtio.c_iflag &= ~(IXON | IXOFF | IXANY); //disable flow control
    newtio.c_iflag |= IGNPAR; //ignore parity
    newtio.c_oflag = 0;
    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw mode
    newtio.c_cc[VMIN] = 1; 
    newtio.c_cc[VTIME] = 0;
    tcflush(ttyDev, TCIFLUSH);
    tcsetattr(ttyDev, TCSANOW, &newtio);

        while(1){
            //Wait for SIGIO to fire
        }

  }

  void byteCallback(int status){
        printf("SIGIO fired!\r\n");


  }
Run Code Online (Sandbox Code Playgroud)

另请参阅这个问题