select()在TTY上似乎不起作用 [英] select() does not seem to work on TTY

查看:73
本文介绍了select()在TTY上似乎不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在编写一个程序,该程序需要通过UART接口(操作系统是Linux)与AT接口进行通信.但是我在文件描述符上使用 select()时遇到了麻烦.由于某种原因,select认为文件描述符未准备就绪,但是为了缩小问题的范围,我使用了以下程序.

I'm currently writing a program that needs to communicate with an AT interface over an UART interface (the operating system is Linux). But I'm having trouble using select() on the file descriptor. For some reason select does not consider the file descriptor to be ready for reading, but To narrow down the problem I have used the following program.

int main()
{
    char buffer[BSIZE];
    fd_set rfds;
    int ret;
    struct termios cnf;
    struct timeval tv;

    fd = open("/dev/ttyO1", O_RDWR);
    // Have also tried to set fd = 0 for stdin, as a reference
    signal(SIGINT, sig_handler);
    tcgetattr(fd, &cnf);
    old = cnf;
    cfmakeraw(&cnf);
    tcsetattr(fd, TCSANOW, &cnf);
    while (1) {
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
        write(fd, "AT\r", 3);
        ret = select(fd+1, &rfds, NULL, NULL, &tv);
        printf("ret = %d\n", ret);
        if (ret < 0) {
            perror("select()");
        }
        else {
            ret = read(fd, buffer, BSIZE-1);
            buffer[ret] = '\0';
            printf("read: \"%s\"\n", buffer);
        }
    }
    return 0;
}

运行看起来像这样

    root@linux:~# ./stuff
    ret = 0
    read: "AT
    OK
    "

哪个表示select认为没有数据,但是在尝试读取时有数据.这对我来说似乎很奇怪.另外,我尝试将tty与stdin交换,效果很好.

Which indicates that select thinks that there is no data, but when trying to read there is data. This seems very strange to me. Also, I've tried to exchange the tty with stdin, and that works just fine.

该代码正在Texas Instruments EZSDK PSP内核上运行,但这不应该成为问题.另外, stty 设置如下所示

The code is being run on Texas Instruments EZSDK PSP kernel, but that shouldn't be the problem. Also, the stty settings looks like the following

    root@linux:~# stty -aF /dev/ttyO1
    speed 9600 baud; rows 24; columns 80;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
    lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    -iuclc -ixany -imaxbel
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    echoctl echoke

我错过了 open()的关键标志吗?还是需要使用 termios 进行一些设置?这种方法是否需要一些特殊的硬件

Have I missed som crucial flag to open()? or perhaps need to set some setting using termios? Does this method require some special hardware

尝试运行程序/dev/ttyUSB0 时遇到相同的问题,该程序恰好是AT接口.在我看来,这与 tty 有关.

I get the same problem when trying to run the program /dev/ttyUSB0, which also happens to be is an AT interface. Seems to me that it is tty related.

将fd更改为我实际使用并想知道的内容.

changed fd to what I actually used and wondered about.

推荐答案

您无需将串行端口的文件描述符添加到fd集中.

You don't add file descriptor of serial port to fd set.

更改行:

FD_SET(0, &rfds);

收件人:

FD_SET(fd, &rfds);

如果需要将fd设置为零,则添加以下行.

Or add the following line, if you need fd zero in the set.

FD_SET(fd, &rfds);

这篇关于select()在TTY上似乎不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆