select() does not seem to work on TTY

眉间皱痕 提交于 2021-01-27 17:04:20

问题


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;
}

The run looks something like this

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

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.

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

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

EDIT: 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.

changed fd to what I actually used and wondered about.


回答1:


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

Change line:

FD_SET(0, &rfds);

to:

FD_SET(fd, &rfds);

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

FD_SET(fd, &rfds);



回答2:


I believe it should be /dev/ttyS1 and not /dev/tty01. You are attempting to select on the VT (virtual terminal) which happens to be attached to the UART in your embedded board, but this is not the same thing,



来源:https://stackoverflow.com/questions/11986998/select-does-not-seem-to-work-on-tty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!