如何讀取/寫入 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 文件就像管道一樣,只是在資料傳入時向兩個方向推送資料。後來我讀到,已經沒有什麼在等我了。它是不是就像寫入常規檔案一樣,資料保存在磁碟上 - 它會立即傳遞到另一端,或儲存在記憶體中直到有人讀取它。

您可能會想使用選擇函數,以便您可以在等待裝置說話時做其他事情,但如果您願意等待資料通過,您可以使用阻塞讀取並讓作業系統來完成提升。

要記住的一件事是,內核中的緩衝區大小可能是有限的,如果您一次寫入大量數據,您可能會無意中阻塞。如果這可能是個問題,請使用非阻塞IOopen("/dev/...", O_RDWR | O_NONBLOCK)。無論哪種方式,原則都是相同的。

相關內容