Serial-Port
如何發送到虛擬串口,並從另一個程序讀取?
我正在嘗試將一些數據寫入串列埠,例如我將從
screen
同一台電腦中讀取的數據。我試過看這個答案how-to-send-data-to-a-serial-port-and-see-any-answer我已經將我的使用者添加到組
dialout
並執行chmod o+rw /dev/ttyS1
然後在python中我喜歡這樣,並得到關注錯誤:
>>> import serial >>> ser = serial.Serial("/dev/ttyS1",4800) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialutil.py", line 236, in __init__ self.open() File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialposix.py", line 272, in open self._reconfigure_port(force_update=True) File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialposix.py", line 315, in _reconfigure_port raise SerialException("Could not configure port: {}".format(msg)) serial.serialutil.SerialException: Could not configure port: (5, 'Input/output error')
所以問題是,我在這裡做錯了什麼?
或者我應該尋找不同的方法。
問題是,我得到了一些我可以在例如 python 中接收的 udp 消息,我需要發送到一個只能看到串列埠的軟體。
也許有不同的方法?
在這種情況下,有什麼好方法可以做到這一點?
如果您需要連接兩個程序,其中一個堅持使用 tty 設備(其中一個串列埠就是一個例子),您可以使用偽終端對來連接它們。
您可以使用標準pty 模組從 Python 執行此操作,也可以使用僅創建該對的小型 C 程序,然後從外殼程序、Python 程序或任何普通文件中訪問它。
您在評論中的建議使用了核心模組,該模組過度殺傷且不便攜。
這是我在類似情況下使用的範例 C 程序,它不是很精緻,需要某種方式來傳達使用的名稱。
/* ptycat (ptypipe? ptypair?) * * create a pair of pseudo-terminal slaves connected to each other * * Link with -lutil */ #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <errno.h> #include <termios.h> #include <unistd.h> #include <pty.h> #undef max #define max(x,y) ((x) > (y) ? (x) : (y)) /* (void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win); */ /* TODO: make symlinks, unlink on atexit */ static uint8_t buf[BUFSIZ]; /* BUFSIZ from stdio.h, at least 256 */ static char *log_dir = NULL; void logdata (char *dir, uint8_t *data, int n) { if (dir != log_dir) fprintf (stdout, "\n%s", dir); log_dir = dir; for (; n > 0; n--, data++) fprintf (stdout, " %02x", *data); fflush (stdout); } int main (int argc, char* argv[]) { char name[256]; /* max namelen = 255 for most fs. */ fd_set rfd; struct termios tt; struct winsize ws; int master[2], slave[2]; int n, nfds, cc; if (tcgetattr (STDIN_FILENO, &tt) < 0) { perror("Cannot get terminal attributes of stdin"); exit(1); } cfmakeraw (&tt); for (int i = 0; i < 2; i++) { if (openpty (&master[i], &slave[i], name, &tt, NULL /*ws*/) < 0) { perror("Cannot open pty"); exit(1); } puts(name); } for (;;) { FD_ZERO(&rfd); FD_SET(master[0], &rfd); FD_SET(master[1], &rfd); nfds = max(master[0], master[1]) + 1; n = select(nfds, &rfd, 0, 0, NULL); if (n > 0 || errno == EINTR) { if (FD_ISSET(master[0], &rfd)) { if ((cc = read(master[0], buf, sizeof(buf))) > 0) { (void) write(master[1], buf, cc); logdata (">>>", buf, cc); } } if (FD_ISSET(master[1], &rfd)) { if ((cc = read(master[1], buf, sizeof(buf))) > 0) { (void) write(master[0], buf, cc); logdata ("<<<", buf, cc); } } } } /* This never reached */ return 0; }