仮想シリアルポートに送信して他のプログラムから読み取るには?

仮想シリアルポートに送信して他のプログラムから読み取るには?

screen同じコンピュータから読み取るシリアルポートにいくつかのデータを書き込もうとします。この答えを見ようとしました。シリアルポートにデータを転送して回答を確認する方法
私のユーザーをグループに追加し、dialoutPythonchmod o+rw /dev/ttyS1
として実行しました。これを行い、次のエラーが発生します。

>>> 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メッセージを受け取りました。これはシリアルポートのみを表示できるソフトウェアに送信する必要があるということです。
たぶん別のアプローチがありますか?
この場合、良いアプローチは何ですか?

ベストアンサー1

2つのプログラムを接続する必要があり、そのうちの1つがttyデバイス(シリアルポートはい)を使用する必要がある場合は、次のものを使用できます。擬似端末カップル。

標準のPythonを使用してこれを行うことができます。ptyモジュール、または小さな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; 
}

おすすめ記事