在Linux中处理/ dev/tty设备上的用户中断(UART中断)

问题描述:

以下是一些代码示例,但问题是在通过串行线路发送“中断”时调用的信号处理程序为而非与'腻子'。在Linux中处理/ dev/tty设备上的用户中断(UART中断)

#include <sys/ioctl.h> 
#include <termios.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/signal.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <unistd.h> 

void signal_handler(int status); 

int main(void) 
{ 
    FILE* f = fopen("/dev/ttyS0", "r+b"); 

    struct sigaction saio; /* definition of signal action */ 
    saio.sa_handler = signal_handler; 
    // saio.sa_mask = 0; 
    saio.sa_flags = 0; 
    saio.sa_restorer = NULL; 
    sigaction(SIGINT,&saio,NULL); 

    struct termios options; 

    tcgetattr (fileno(f), &options); 

    cfsetispeed(&options, B9600); 
    cfsetospeed(&options, B9600); 

    options.c_iflag &= ~IGNBRK; // & ~IGNPAR; 
    options.c_iflag |= BRKINT; // | PARMRK | INPCK; 
    options.c_cc[VMIN] = 0; 
    options.c_cc[VTIME] = 1; 

    if (tcsetattr(fileno(f), TCSAFLUSH, &options) == -1) 
    { 
     printf("port setup failure\n"); 
     return -1; 
    } 

    ioctl(fileno(f), TIOCSCTTY, (char *)NULL); 
    while (1) { 
     int ch = fgetc(f); 
     switch (ch) { 
     case EOF: break; 
     case EAGAIN: printf("[EAGAIN]"); break; 
     case EBADF: printf("[EBADF]"); break; 
     case EINTR: printf("[EINTR]"); break; 
     case EIO: printf("[EIO]"); break; 
     case EOVERFLOW: printf("[EOVERFLOW]"); break; 
     default: 
      if (isprint(ch)) 
       putchar(ch); 
      else 
       printf("[%02x]", ch); 
     } 
    } 
} 

void signal_handler(int status) 
{ 
    printf("received SIGINT %d signal.\n", status); 
    exit(0); 
} 

这里是我的stty设置:

[email protected]:~/$ sudo stty -F /dev/ttyS0 
speed 9600 baud; line = 0; 
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>; start = <undef>; stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; 
lnext = <undef>; flush = <undef>; min = 0; time = 1; 
-imaxbel 
-opost -onlcr 
-icanon -iexten -echo -echoe -echok -echoctl -echoke 

我缺少什么/为什么我收不到信号?我使用的是USB-2-Serial转换器,我可以看到中断已发送完毕,但在此客户端没有任何事件触发。

试试strace监督下。在您的tcsetattr之后加上tcgetattr的电话,并检查您所要求的所有更改是否已作出
您还应该在获取新tty之前摆脱您的控制tty。根据man tty-ioctl:

Controlling tty 
     TIOCSCTTY int arg 
       Make the given tty the controlling tty of the calling process. The calling process must be a session leader and not have a controlling tty already. If 
       this tty is already the controlling tty of a different session group then the ioctl fails with EPERM, unless the caller is root and arg equals 1, in 
       which case the tty is stolen, and all processes that had it as controlling tty lose it. 

     TIOCNOTTY void 
       If the given tty was the controlling tty of the calling process, give up this controlling tty. If the process was session leader, then send SIGHUP and 
       SIGCONT to the foreground process group and all processes in the current session lose their controlling tty.