如何读/写 tty* 设备?

如何读/写 tty* 设备?

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

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

答案1

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

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

/dev/pts/2

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

$ echo Hello > /dev/pts/2
Hello
$

您甚至可以从中阅读:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

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

如果您打开另一个 shell,例如使用screenxterm,您可以在该 shell 中运行 runecho spooky > /dev/pts/2以使文本显示在原始终端上,对于其他命令也是如此。所有这一切只是您的 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;
}

连接到 shell 或终端模拟器的真实 TTY 设备将有有趣的行为,但您应该得到一些回报。


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

至于编写一个程序来使用它,您不需要做太多特别的事情。您可以在示例中看到一件事需要做的是每次关闭文件,让另一端读取数据:TTY 文件就像管道一样,只是在数据传入时向两个方向推送数据。当我向 TTY 写入文本时,它会立即出现,当后来我读到,已经没有什么在等着我了。它是不是就像写入常规文件一样,数据保存在磁盘上 - 它会立即传递到另一端,或存储在内存中直到有人读取它。

您可能想使用选择函数,以便您可以在等待设备说话时做其他事情,但如果您愿意等待数据通过,您可以使用阻塞读取并让操作系统来完成提升。

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

相关内容