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

在Linux中处理a/dev/tty设备上的用户中断(UART中断),linux,signals,ioctl,tty,Linux,Signals,Ioctl,Tty,下面是一些代码示例,但问题是当通过带有“putty”的串行线发送“break”时,信号处理程序没有被调用 #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> #inc

下面是一些代码示例,但问题是当通过带有“putty”的串行线发送“break”时,信号处理程序没有被调用

#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);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效信号处理器(int状态);
内部主(空)
{
文件*f=fopen(“/dev/ttyS0”,“r+b”);
struct sigaction saio;/*信号动作的定义*/
saio.sa_handler=信号_handler;
//saio.sa_mask=0;
saio.sa_flags=0;
saio.sa_restorer=NULL;
sigaction(SIGINT和saio,NULL);
结构termios选项;
tcgetattr(文件编号(f)和选项);
cfsetispeed(和选项,B9600);
cfsetospeed(和选项,B9600);
options.c_iflag&=~IGNBRK;//&~IGNPAR;
options.c|u iflag |=BRKINT;/| PARMRK | INPCK;
options.c_cc[VMIN]=0;
选项c_cc[VTIME]=1;
if(tcsetattr(文件号(f)、TCSAFLUSH和选项)=-1)
{
printf(“端口设置失败\n”);
返回-1;
}
ioctl(fileno(f),TIOCSCTTY,(char*)NULL);
而(1){
int ch=fgetc(f);
开关(ch){
案例EOF:破裂;
案例EAGAIN:printf(“[EAGAIN]”);break;
案例EBADF:printf(“[EBADF]”);break;
案例输入:printf(“[EINTR]”);中断;
案例EIO:printf(“[EIO]”);中断;
案例EOVERFLOW:printf(“[EOVERFLOW]”);中断;
违约:
如果(iPrint(ch))
putchar(ch);
其他的
printf(“[%02x]”,ch);
}
}
}
无效信号处理器(int状态)
{
printf(“收到信号%d。\n”,状态);
出口(0);
}
以下是我的stty设置:

user@dev:~/$ 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
user@dev:~/$sudo stty-F/dev/ttyS0
速度9600波特;直线=0;
intr=;退出=;擦除=;杀死=;eof=;开始=;停止=;susp=;rprnt=;werase=;
lnext=;同花顺=;最小值=0;时间=1;
-伊玛克斯贝尔
-opost-onlcr
-icanon-iexten-echo-echok-echoctl-echoke
我错过了什么/为什么没有收到信号?我正在使用USB-2串行转换器,我可以看到中断被发送过来,但在这个客户端上根本没有触发任何东西。

在监督下尝试一下。在您的
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.