如何读/写 tty* 设备?

she*_*lbc 46 usb tty

我有一个通过 USB 向我的计算机发送信息的设备。Arch Linux的创建一个名为文件设置该设备ttyUSB0/dev/。我一直在使用GTKterm接收这些传入信息并将其显示在模拟终端窗口中。

我的问题是,究竟如何GTKterm读/写这个ttyUSB0文件,我可以从哪里开始学习如何实现类似的功能?也就是说,在最基本的形式中,我如何将字符写入ttyUSB0,或者相反,接收一个字节并将其写入文件?

Mic*_*mer 65

TTY 是您可以像其他任何文件一样使用的文件。您可以使用您的语言的标准文件打开工具打开它们,并从中读取或写入。它们有一些与“普通”文件不同的特殊行为,但基本原理是相同的。我将在最后介绍一些特殊情况,但首先是一个实验。

您可以直接从常规终端做一件有趣的事情。运行tty,它将打印如下一行:

/dev/pts/2
Run Code Online (Sandbox Code Playgroud)

那是您的终端正在运行的 TTY 设备。您可以向该终端写入一些内容:

$ echo Hello > /dev/pts/2
Hello
$
Run Code Online (Sandbox Code Playgroud)

您甚至可以从中阅读:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$
Run Code Online (Sandbox Code Playgroud)

read X是 sh 的“从标准输入读取一行到变量 X”命令;< 是使用 /dev/pts/2 作为读取命令的标准输入;我输入的第一个“hello”,第二个被打印出来) .

如果您打开另一个 shell,例如使用screenxterm,您可以echo spooky > /dev/pts/2在该 shell 中运行 run以使文本显示在原始终端上,其他命令也是如此。所有这一切只是你的 shell 在不知道它是 TTY 的情况下打开一个文件。


这是一个非常简单的 C 程序,它按照您的要求执行操作,并向 /dev/pts/3 写入一个字符,然后从中读取一个字节:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>    
int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c\n", byte);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

连接到外壳或终端仿真器的真正 TTY 设备将在那里有有趣的行为,但您应该得到一些回报。


要访问终端,您需要获得使用权限。这些只是您看到ls -l和设置的标准文件权限chmod:您需要读取权限才能打开和读取文件,并需要写入权限才能写入文件。支持您终端的 TTY 将归您所有,但其他用户的 TTY 不会,USB 设备的 TTY 可能是也可能不是,这取决于您的配置。您可以像往常一样更改权限。

就编写程序来处理它而言,您不需要做太多特别的事情。您可以在示例中看到,您不需要做的一件事就是每次都关闭文件以让另一端读取您的数据:TTY 文件就像管道一样,只是在数据进入时向两个方向推送数据。当我向 TTY 写文本时,它立即出现,当我之后阅读时,已经没有任何东西等着我了。它不是像写在那里得到的数据保存在磁盘上一个普通的文件-它被立即传递给对方,或者存储在内存中,直到有人读它。

您可能想要使用select函数,以便您在等待设备说话时可以做其他事情,但是如果您乐于等待数据通过,您可以使用阻塞读取并让操作系统来做举重。

要记住的一件事是内核中的缓冲区大小可能是有限的,如果您一次写入大量数据,您最终可能会无意识地阻塞。如果这可能是个问题,请将非阻塞 IOopen("/dev/...", O_RDWR | O_NONBLOCK). 无论哪种方式,原理都是相同的。

  • `&gt; /dev/tty4` 部分不是由 `sudo` 启动的 `echo` 子进程的一部分,而是由当前用户执行的 `sudo` 进程本身的一部分。应用当前用户的文件权限而不是 root。 (3认同)