Posted at

socatで仮想シリアルポートを作る

More than 1 year has passed since last update.

ソケットをいじくり回すのに便利なsocatですが、

仮想シリアルポートの操作にもとっても便利でした。

元ネタ:

create virtual serial port with socat in linux

https://www.youtube.com/watch?v=iFmD-CeB96A

なお、この記事のコードは、

Windows10のVirtualbox上のArch Linuxと、Python3.6.4でテストを行っています。


仮想シリアルポート作成

$ socat -d -d pty,raw,echo=0 pty,raw,echo=0

2018/03/31 01:36:38 socat[8626] N PTY is /dev/pts/14
2018/03/31 01:36:38 socat[8626] N PTY is /dev/pts/15
2018/03/31 01:36:38 socat[8626] N starting data transfer loop with FDs [5,5] and [7,7]

これで、/dev/pts/14/dev/pts/15の2つのシリアルポートが内部的に繋がっていることになります。

テストのために、他に2つのシェルを開き、それぞれで以下のコマンドを実行します。

$ cat < /dev/pts/14

$ echo "Pseudo serial port test" > /dev/pts/15

catしているほうのシェルで、echoした文字列が確認出来るかと思います。

1415という数字は、上でsocatを実行したときのログを参照し適宜変更する必要があります。


シリアルポートにアクセスするプログラムのテストに

作成した仮想シリアルポートは、実シリアルポートと同様の方法でアクセスが可能です。

ここでは、PythonのPyserialとの接続をテストしてみます。

まずはPyserialの送信を。


入力

import serial

port_name = '/dev/pts/15'

sp = serial.Serial(port_name, 9600)

message = 'Test message from pyserial\n'

sp.write(message.encode('ascii'))
sp.close()



出力

$ cat < /dev/pts/14

Test message from pyserial

次はPyserialの受信を。


入力

$ python -c "print('Test message from shell')" > /dev/pts14



出力

import serial

port_name = '/dev/pts/15'

sp = serial.Serial(port_name, 9600)

line = sp.readline()
print(line)
sp.close()


こんな感じで、各種シリアルポートの送受信テストに気軽に使えるかと思います。