2009-06-10 195 views
2

以下是一些代碼示例,但問題是在通過串行線路發送「中斷」時調用的信號處理程序爲而非與'膩子'。在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轉換器,我可以看到中斷已發送完畢,但在此客戶端沒有任何事件觸發。

回答

1

試試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.