Linuxの仮想シリアルポート


127

Linuxでシリアルポートアプリケーションをテストする必要がありますが、テストマシンにはシリアルポートが1つしかありません。

Linuxに仮想シリアルポートを追加し、シェルまたはスクリプトを介してデバイスをエミュレートしてアプリケーションをテストする方法はありますか?

注:ポートを再マップすることはできません。ポートはttys2にハードコーディングされており、アプリケーションが記述されているとおりにテストする必要があります。

回答:


74

これには、pty(シリアルポートが「実際のテレタイプ」である「疑似テレタイプ」)を使用できます。一端からを開き/dev/ptyp5、次にプログラムをに接続します/dev/ttyp5ttyp5シリアルポートのように動作しますが、/ dev / ptyp5を介してすべてのことを送受信します。

と呼ばれるファイルと通信するために本当に必要な場合は/dev/ttys2、古いファイルを/dev/ttys2邪魔にならない場所に移動し、シンボリックリンクをからに作成ptyp5ttys2ます。

もちろん、以外の数を使用することもできますptyp5。すべてのログイン端末もptyを使用するため、重複を避けるために、数字の大きいものを選択することをお勧めします。

ウィキペディアにはptyの詳細があります:http : //en.wikipedia.org/wiki/Pseudo_terminal


8
Linuxでは、openpty / forkptyシステムコールを使用できます。マニュアルページを
マシュー・スミス

8
コマンドラインツールを使用して仮想シリアルポートペアを作成する方法
linjunhalida、2010年

8
ボーレート、パリティ、ハードウェアフロー制御、文字サイズ(?)などの多くのシリアルポートパラメーターはptyに実装されていないため、シリアル伝送エラーが発生した状態でアプリケーションをテストすることはできません。
Dima Tisnek

10
これは役に立ちますが、「古いスタイル」のBSD疑似端末について説明しています。「新しいスタイル」のUNIX 98疑似端末の動作は少し異なりptsます。詳細については、manページを参照してください。
Craig McQueen

3
@LaszloPapp謝罪します、私はずっと嘘をついていました
マシュー・スミス

160

@slonikの回答を補完します。

socatをテストして仮想シリアルポートを作成するには、次の手順を実行します(Ubuntu 12.04でテスト済み)。

ターミナルを開き(ターミナル0としましょう)、それを実行します。

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

上記のコードは次を返します:

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]

別のターミナルを開いて(ターミナル1)に書き込みます。

cat < /dev/pts/2

このコマンドのポート名は、PCに応じて変更できます。それは前の出力に依存します。

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs 

強調表示された領域で利用可能な番号を使用する必要があります。

別のターミナルを開き、次のように入力します(ターミナル2):

echo "Test" > /dev/pts/3

ターミナル1に戻ると、「Test」という文字列が表示されます。


これはslonikの答えよりもうまく機能しました。仮想COMポートファイルに自動的に割り当てられ、エコーしません。
gbmhunter 2014年

7
link=/path/to/link各デバイス宣言の後(echo = 0の後)に再現可能なファイル名を使用する場合。したがって、自動テストで使用できます。(slonikが回答で行うように)
Patrick B.

これは前述のとおりに機能しました。感謝しました。
nim118

1
実際のシリアルポートにリンクするptyを作成するには:socat -d -d pty,raw,echo=0 /dev/ttyUSB5,raw,echo=0
Penghe Geng

/dev/ttyS0ではなく、次のような名前のシリアルポートを作成でき/dev/pts/1ますか?
mrid

48

これにはsocatを使用します。

例えば:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

これは私にとってはうまくいき、minicomでテストされました!1つの端末への入力が両方にエコーされるように見えます(したがって、入力端末にも表示されます)。
gbmhunter 2014年

1
同じエコー動作はありません... minicomには「ローカルエコー」機能がありますが、無効にすると、実際のシリアルポートとまったく同じように動作します。先端をありがとう。
cptHammer

16

Linux用の実際のヌルモデムエミュレータであるtty0tty http://sourceforge.net/projects/tty0tty/もあります。

これは単純なカーネルモジュール-小さなソースファイルです。なぜsourceforgeで不評になったのかはわかりませんが、私にとってはうまくいきます。それについての最も良いことは、ハードウェアピン(RTC / CTS DSR / DTR)もエミュレートすることです。TIOCMGET / TIOCMSETおよびTIOCMIWAIT iotclコマンドも実装しています!

最近のカーネルでは、コンパイルエラーが発生する場合があります。これは簡単に修正できます。module / tty0tty.cソースの先頭に(インクルードの後に​​)数行挿入するだけです:

#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif

モジュールがロードされると、4組のシリアルポートが作成されます。デバイスは/ dev / tnt0から/ dev / tnt7です。ここで、tnt0はtnt1に接続され、tnt2はtnt3に接続されます。デバイスを使用できるようにするには、ファイルのアクセス権を修正する必要がある場合があります。

編集:

私は私の熱意に少し速かったと思います。ドライバーは有望に見えますが、不安定なようです。よくわかりませんが、自宅で作業していたオフィスのマシンがクラッシュしたと思います。月曜日にオフィスに戻るまでチェックできません。

2つ目は、TIOCMIWAITが機能しないことです。コードは、「小さなtty」のサンプルコードからコピーされたようです。TIOCMIWAITの処理は整っているようですが、wake_up_interruptible()への対応する呼び出しがないため、ウェイクアップしません。

編集:

オフィスでの墜落は本当に運転手の責任でした。初期化が欠落しており、完全にテストされていないTIOCMIWAITコードが原因でマシンがクラッシュしました。

昨日と今日、ドライバーを書き直しました。多くの問題がありましたが、今ではうまくいきます。ドライバーによって管理されるハードウェアフロー制御のコードはまだありませんが、ユーザーモードコードからTIOCMGET / TIOCMSET / TIOCMIWAITを使用して自分でピンを管理するので、それは必要ありません。

私のバージョンのコードに誰かが興味を持っている場合は、私にメッセージを送ってください。それをお送りします。


2
私はあなたのコードを見てみたいです。それをtty0ttyプロジェクトに貢献してくれませんか?ただし、Linuxカーネルの疑似端末コードを改善してほしいと思います。たとえば、ハードウェアハンドシェイクサポートとTIOCMIWAITを追加します。
Craig McQueen

3
「誰かが私のバージョンのコードに興味を持っているなら、私にメッセージを送ってください、それをあなたに送ります。」はい、興味があります!GitHubなどのどこかでポイントできますか?
Craig McQueen 2013

7
ドライバを次の場所にアップロードしました: github.com/pitti98/nullmodemました。返信に時間がかかりすぎて申し訳ありません。私はstackoverflowにあまり積極的ではなく、あなたのコメントを見落としました!
Peter Remmers 2013年

いいえ、私はそれが必要だったのでそれを書いて、それが私がやりたいことをするのに十分良かったら止めました。これが公開されたので、他の誰かにも役立つことを願っています。多分誰かが私が残した場所をピックアップしています。
Peter Remmers 2013年

8

カーネルドライバーを使用してLinux仮想シリアルポートを作成するためのTibbo VSPDLを確認することをお勧めします。これはかなり新しいようで、今すぐダウンロードできます(ベータ版)。この時点でのライセンスについて、または将来的にのみ商用利用できるようにするかどうかは不明です。

http://www.ttyredirector.com/などの他の商用の代替手段があります

オープンソースでは、Remserial(GPL)もUnix PTYを使用して、必要な処理を実行できます。シリアルデータを「生の形式」でネットワークソケットに送信します。STTYに似た端末パラメータの設定は、ポートの作成時に行う必要があります。RFC2217に記載されているように、後で変更することはサポートされていないようです。事前にポート速度などを設定する必要があることを除いて、com0comのような仮想ヌルモデムを作成するために2つのレムリアルインスタンスを実行できるはずです。

Socat(またはGPL)は、Remserialの拡張バリアントのようなもので、PTYを他の何かにリダイレクトするための「PTY」メソッドを含み、Socatの別のインスタンスにすることができます。Unit tetsの場合、ファイルをPTYに直接catできるため、socatはremserialより優れている可能性があります。マンページのPTYの例を参照してください。パッチが存在するシリアルラインの設定を交渉するためのRFC2217のサポートを提供するために、「寄贈」の下に。


6

以前の回答で投稿されたリンクを使用して、仮想シリアルポートを使用するC ++で小さな例をコーディングしました。コードをGitHubにプッシュしました:https : //github.com/cymait/virtual-serial-port-example

コードはかなり自明です。まず、。/ main masterを実行してマスタープロセスを作成すると、デバイスが使用しているstderrに出力されます。その後、。/ mainスレーブデバイスを呼び出します。ここで、deviceは最初のコマンドで出力されたデバイスです。

以上です。2つのプロセス間に双方向リンクがあります。

この例を使用すると、あらゆる種類のデータを送信してアプリケーションをテストし、正しく機能するかどうかを確認できます。

また、いつでもデバイスをシンボリックリンクできるため、テストするアプリケーションを再コンパイルする必要はありません。


1
while(read(fd、&inputbyte、1)== 1){...} readはコードで定義されていません。書き込みは未定義です。closeは未定義です。
Mattis Asp 2018年

4

USB-> RS232アダプターを使用できますか?いくつかありますが、彼らはFTDIドライバーを使用しています。その後、/ dev / ttyUSB0(または作成されたもの)の名前を/ dev / ttyS2に変更できるはずです。


4

私は3つのオプションを考えることができます:

RFC 2217を実装する

RFC 2217は、あるシステムのクライアントがローカルプログラムへのシリアルポートをエミュレートし、実際にシリアルポートを持つ別のシステムのサーバーにデータと制御信号を透過的に送受信できるようにする、TCP / IP標準へのCOMポートをカバーしています。ここだ高レベルの概要は、

あなたがすることはあなたのPCのシステムのクライアント側を実装するクライアントCOMポートドライバーを見つけるか実装することです-実際のシリアルポートのように見えますが実際にはすべてをサーバーに送っています。実際のスタンドアロンシリアルポートサーバーをサポートするDigi、Lantronixなどからこのドライバーを無料で入手できる場合があります。

次に、接続のサーバー側をローカルで別のプログラムに実装します。これにより、クライアントが接続し、必要に応じてデータと制御コマンドを発行できるようになります。

それはおそらく些細なことではありませんが、RFCはそこにあり、接続の片側または両側を実装するオープンソースプロジェクトを見つけることができるかもしれません。

Linuxシリアルポートドライバーを変更する

または、Linuxのシリアルポートドライバーソースをすぐに利用できます。それを取り、ハードウェアの制御部分をすっきりさせて、1つのドライバーが単純なループバックとして2つの/ dev / ttySxポートを実行するようにします。次に、実際のプログラムをttyS2に接続し、シミュレータを他のttySxに接続します。

ループバックで2本のUSB <->シリアルケーブルを使用する

しかし、今する最も簡単なことは?2つのシリアルポートUSBデバイスに40ドルを費やして、それらを一緒に配線し(ヌルモデム)、実際には2つの実際のシリアルポートを持っています。1つはテストするプログラム用、もう1つはシミュレーター用です。

-アダム


1
実際には、ヌルモデムUSB UARTケーブルはローカルテスト(ポートが不足している場合はUSBハブを入手)とリモートデバッグの両方をサポートしているので、私にとって非常にエレガントなソリューションのように見えます。
Maxthon Chan

品質は確認していませんが、ttynvtは Linux FUSEを介してRFC 2217を実装しています
Daniel Santos
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.