10

私は、シリアルポート接続を使用する「仮想デバイス」(pythonプロセス)を、シリアルポートも使用する実際のデバイスとインターフェイスするプロジェクトに取り組んでおり、疑似端末を使用して、これらのシリアルポートのいくつか(2つ以上)を接続しています通信プロセス(シリアルデバイスのモデリング)を一緒に行うと、ちょっとした問題にぶつかりました。

疑似端末を生成し、ptyのスレーブエンドをファイルにシンボリックリンクする(プロセスがファイル名にpyserialオブジェクトを作成できるようにする)Pythonプロセスがありますが、マスターエンドはpty生成プロセスによって保持されて読み取られます。1つのマスターにデータが入ると、データはログに記録されてから、他のマスターに書き込まれます。このアプローチは、リスニングプロセスが常に存在する場合に機能します。

問題は、仮想デバイスが停止するか、起動されない場合です(これは、このプロジェクトの有効なユースケースです)。私のシステムでは、データがptyのマスターエンドに書き込まれる場合、スレーブエンドをリッスンするものがない場合、そのマスターでreadを呼び出すと、書き込まれたばかりのデータが返されるようです。これは、デバイスが同じデータを複数回受信することを意味します-良くありません!

例:

>>master, slave = pty.openpty()
>>os.write(master,"Hello!")
6
>>os.read(master,6)
'Hello!'

スレーブがデータを送信するまで、read()ブロックを呼び出すことをお勧めします。実際、これはスレーブデバイスの動作です。書き込み可能であり、マスターがデータを書き込むまでos.read(slave、1)はブロックします。

私の「仮想デバイス」は、シリアルポートオブジェクトを開くためにファイル名を渡すことができる必要があります。マスターエンドをシンボリックリンクしようとしましたが、仮想デバイスが/ dev / ptmxを開くため、既存のスレーブにリンクする代わりに、新しい疑似端末ペアが作成されます。

マスターの動作を変更する方法はありますか?または、(/ dev / ptmxだけでなく)スレーブデバイスに対応するマスターへのファイル名を取得するだけでもかまいませんか?

前もって感謝します!

4

2 に答える 2

6

これは、エコーがデフォルトでオンになっているためだと確信しています。Python termios docsから借用するには、次のようにします。

master, slave = os.openpty()    # It's preferred to use os.openpty()
old_settings = termios.tcgetattr(master)
new_settings = termios.tcgetattr(master)   # Does this to avoid modifying a reference that also modifies old_settings
new_settings[3] = new_settings[3] & ~termios.ECHO
termios.tcsetattr(master, termios.TCSADRAIN, new_settings)

以下を使用して、古い設定を復元できます。

termios.tcsetattr(master, termios.TCSADRAIN, old_settings)
于 2012-01-24T08:03:37.460 に答える
5

誰かがこの質問を見つけて、jszakmeister の答えがうまくいかなかった場合、これが私にとってうまくいったものです。

openptyエコーをオンにして正規モードで pty を作成するようです。これは期待できるものではありません。tty.setrawこの単純な openpty エコー サーバーの例のように、関数を使用してモードを変更できます。

master, slave = os.openpty()
tty.setraw(master, termios.TCSANOW)
print("Connect to:", os.ttyname(slave))

while True:
    try:
        data = os.read(master, 10000)
    except OSError:
        break
    if not data:
        break
    os.write(master, data)
于 2017-10-10T15:06:43.400 に答える