2

我有一个串行到 USB 转换器(FTDI,从http://www.ftdichip.com/Drivers/VCP.htm安装的驱动程序)将串行设备连接到 MacBook Air。它在 MacBook 上显示为/dev/cu.usbserial-A4017CQY/dev/tty.usbserial-A4017CQY无论我使用这两个中的哪一个,我描述的所有行为都是相同的。

编辑:使用/dev/cu.*确实解决了问题。我不确定为什么当我第一次发布这个问题时它似乎不起作用。感谢duskwuff 为我指明了正确的方向,尽管他的TTY 名称倒过来了:/dev/tty.*将等待流量控制,而/dev/cu.*不会。

open()我遇到的第一个问题是,如果我不使用该O_NONBLOCK标志,系统调用将永远阻塞。使用该标志,我得到了一个很好的文件描述符,但write()似乎并没有真正写入(尽管它返回很好,声称已写入字节),并且read()失败并出现错误“资源暂时不可用”。

stty -af /dev/cu.usbserial-A4017CQY显示设置就好了,但是如果我尝试使用类似的命令更改它们,stty -f /dev/cu.usbserial-A4017CQY -clocal当连续调用stty.

如果我select()在读/写之前等待设备准备好,它会在短时间内报告它已准备好写入,但永远不会读取。这与如何write()毫无怨言地完成,而read()失败。请注意,写入的数据从未真正进入设备。

我为调试而编写的整个测试程序如下:

#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <sys/select.h>

#define SYSCALL(A) do { ret = A; if (ret == -1) { perror(#A); return -1; } else printf("%s returned %d\n", #A, ret); } while (0)
int ret; /* necessary for SYSCALL */

int main()
{
    struct termios tio;
    char buf[256];
    int fd = open("/dev/cu.usbserial-A4017CQY", 
            O_RDWR | O_NOCTTY | O_NONBLOCK);
    fd_set rfds, wfds, xfds;
    struct timeval to;
    to.tv_sec = 5;
    to.tv_usec = 0;

    SYSCALL(tcgetattr(fd, &tio));

    cfmakeraw(&tio);

    tio.c_cflag = CS8|CREAD|CLOCAL;
    tio.c_cc[VMIN] = 1;
    tio.c_cc[VTIME] = 1;

    cfsetispeed(&tio, B115200);
    cfsetospeed(&tio, B115200);

    SYSCALL(tcsetattr(fd, TCSANOW, &tio));

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&xfds);
    FD_SET(fd, &rfds);
    FD_SET(fd, &wfds);
    FD_SET(fd, &xfds);

    int ret = select(fd+1, &rfds, NULL, &xfds, &to);
    if (ret == -1) perror("select");
    else if (ret > 0)
    {
        if(FD_ISSET(fd, &rfds))
            puts("Ready to read");
        if(FD_ISSET(fd, &wfds))
            puts("Ready to write");
        if(FD_ISSET(fd, &xfds))
            puts("Exception!");
    }
    else puts("Timed out!");

    SYSCALL(write(fd, "/home\n", 5));
    SYSCALL(read(fd, buf, 256));

    return 0;
}
4

1 回答 1

1

您有流量控制问题。要么环回连接电缆上的 RTS/CTS 和 DTR/DSR/CD,让另一端提供控制信号,要么正如@duskwuff 建议的那样,使用忽略流量控制的设备。

我看到您正在设置CLOCAL- 这应该可以,但是某些 USB 设备没有做正确的事情。您的描述与设备等待调制解调器控制信号一致。

于 2014-11-13T01:53:38.987 回答