Port Serial Virtual untuk Linux

128

Saya perlu menguji aplikasi port serial di Linux, namun, mesin uji saya hanya memiliki satu port serial.

Apakah ada cara untuk menambahkan port serial virtual ke Linux dan menguji aplikasi saya dengan meniru perangkat melalui shell atau skrip?

Catatan: Saya tidak dapat memetakan ulang port, itu kode keras pada ttys2 dan saya perlu menguji aplikasi seperti yang tertulis.

JeffV
sumber

Jawaban:

75

Anda dapat menggunakan pty ("pseudo-teletype", di mana port serial adalah "teletype nyata") untuk ini. Dari satu ujung, buka /dev/ptyp5, lalu lampirkan program Anda ke /dev/ttyp5; ttyp5akan bertindak seperti port serial, tetapi akan mengirim / menerima semua yang dilakukannya melalui / dev / ptyp5.

Jika Anda benar-benar membutuhkannya untuk berbicara dengan sebuah file bernama /dev/ttys2, maka cukup pindahkan file lama Anda /dev/ttys2dan buat symlink dari ptyp5ke ttys2.

Tentu saja Anda dapat menggunakan beberapa nomor selain ptyp5. Mungkin pilih satu dengan angka tinggi untuk menghindari duplikat, karena semua terminal login Anda juga akan menggunakan ptys.

Wikipedia memiliki lebih banyak tentang ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

apenwarr
sumber
8
Di linux Anda dapat menggunakan panggilan sistem openpty / forkpty. Lihat halaman manual
Matthew Smith
8
cara membuat pasangan port serial virtual dengan menggunakan alat baris perintah?
linjunhalida
8
perhatikan bahwa banyak parameter port serial, misalnya baudrate, parity, hw flow control, ukuran karakter (?) tidak diimplementasikan dalam pty, sehingga tidak mungkin untuk menguji aplikasi Anda jika ada kesalahan transmisi serial.
Dima Tisnek
10
Ini berguna, tetapi menjelaskan pseudo-terminal "gaya lama" BSD. Pseudo-terminal "gaya baru" UNIX 98 beroperasi sedikit berbeda — lihat ptshalaman manual untuk lebih detil.
Craig McQueen
3
@LaszloPapp Saya minta maaf, saya berbohong sepanjang waktu
Matthew Smith
160

Melengkapi jawaban @ slonik.

Anda dapat menguji socat untuk membuat Virtual Serial Port dengan melakukan prosedur berikut (diuji di Ubuntu 12.04):

Buka terminal (sebut saja Terminal 0) dan jalankan:

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

Kode di atas mengembalikan:

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]

Buka terminal lain dan tulis (Terminal 1):

cat < /dev/pts/2

nama port perintah ini dapat diubah sesuai dengan pc. itu tergantung pada keluaran sebelumnya.

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 

Anda harus menggunakan nomor yang tersedia di area yang disorot.

Buka terminal lain dan tulis (Terminal 2):

echo "Test" > /dev/pts/3

Sekarang kembali ke Terminal 1 dan Anda akan melihat string "Test".

cantoni
sumber
Ini bekerja lebih baik untuk saya daripada jawaban slonik, karena itu otomatis diberikan ke file port COM virtual, dan tidak bergema.
gbmhunter
7
Jika Anda ingin menggunakan nama file yang dapat direproduksi link=/path/to/linksetelah setiap deklarasi perangkat (setelah echo = 0). Dengan demikian, ini dapat digunakan dalam pengujian otomatis. (seperti yang dilakukan slonik dalam jawaban mereka)
Patrick B.
Ini bekerja persis seperti yang disebutkan. Ini membantu saya terima kasih.
nim118
1
Untuk membuat pty yang link ke port serial nyata: socat -d -d pty,raw,echo=0 /dev/ttyUSB5,raw,echo=0.
Penghe Geng
dapatkah saya membuat port serial dengan nama seperti, /dev/ttyS0bukan /dev/pts/1?
mrid
48

Gunakan socat untuk ini:

Sebagai contoh:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11
slonik
sumber
Ini bekerja dengan baik untuk saya, diuji dengan minicom! Sepertinya input ke satu terminal digema ke keduanya (jadi itu akan muncul kembali di terminal input juga).
gbmhunter
1
Saya tidak memiliki perilaku gema yang sama ... minicom memiliki fitur "gema lokal" ... tetapi ketika dinonaktifkan, ia bekerja persis seperti port serial yang sebenarnya. terima kasih atas tipnya.
cptHammer
16

Ada juga tty0tty http://sourceforge.net/projects/tty0tty/ yang merupakan emulator modem null nyata untuk linux.

Ini adalah modul kernel sederhana - file sumber kecil. Saya tidak tahu mengapa itu hanya mendapat jempol di sourceforge, tetapi itu bekerja dengan baik untuk saya. Hal terbaik tentang itu adalah juga mengemulasi pin perangkat keras (RTC / CTS DSR / DTR). Ia bahkan mengimplementasikan perintah TIOCMGET / TIOCMSET dan TIOCMIWAIT iotcl!

Pada kernel terbaru, Anda mungkin mendapatkan kesalahan kompilasi. Ini mudah untuk diperbaiki. Cukup masukkan beberapa baris di bagian atas sumber module / tty0tty.c (setelah disertakan):

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

Ketika modul dimuat, itu membuat 4 pasang port serial. Perangkat-perangkat tersebut adalah / dev / tnt0 ke / dev / tnt7 di mana tnt0 terhubung ke tnt1, tnt2 terhubung ke tnt3, dll. Anda mungkin perlu memperbaiki izin file agar dapat menggunakan perangkat.

edit:

Saya kira saya sedikit cepat dengan antusiasme saya. Meski pengemudi terlihat menjanjikan, sepertinya tidak stabil. Saya tidak tahu pasti, tetapi saya pikir mesin itu menabrak mesin di kantor yang saya kerjakan dari rumah. Saya tidak dapat memeriksa sampai saya kembali ke kantor pada hari Senin.

Hal kedua adalah TIOCMIWAIT tidak berfungsi. Kode tersebut tampaknya disalin dari beberapa kode contoh "tiny tty". Penanganan TIOCMIWAIT tampaknya ada, tetapi tidak pernah bangun karena panggilan terkait ke wake_up_interruptible () hilang.

edit:

Kecelakaan di kantor itu benar-benar kesalahan pengemudi. Ada inisialisasi yang hilang, dan kode TIOCMIWAIT yang belum teruji menyebabkan kerusakan mesin.

Saya menghabiskan kemarin dan hari ini menulis ulang pengemudi. Ada banyak masalah, tapi sekarang berhasil dengan baik untuk saya. Masih ada kode yang hilang untuk kontrol aliran perangkat keras yang dikelola oleh pengemudi, tetapi saya tidak membutuhkannya karena saya akan mengelola pin sendiri menggunakan TIOCMGET / TIOCMSET / TIOCMIWAIT dari kode mode pengguna.

Jika ada yang tertarik dengan versi kode saya, kirimi saya pesan dan saya akan mengirimkannya kepada Anda.

Peter Remmers
sumber
2
Saya tertarik untuk melihat kode Anda. Bisakah Anda berkontribusi kembali ke proyek tty0tty? Namun, saya lebih suka melihat orang-orang memperbaiki kode pseudo-terminal di kernel Linux. Misalnya menambahkan dukungan handshaking hardware dan TIOCMIWAIT.
Craig McQueen
3
"Jika ada yang tertarik dengan versi kode saya, kirimi saya pesan dan saya akan mengirimkannya kepada Anda." Ya, saya tertarik! Bisakah Anda menunjukkannya di suatu tempat, misalnya di GitHub?
Craig McQueen
7
Saya mengunggah driver ke: github.com/pitti98/nullmodem Maaf, butuh waktu lama untuk membalas. Saya tidak terlalu aktif di stackoverflow dan mengabaikan komentar Anda!
Peter Remmers
Tidak, saya menulisnya karena saya membutuhkannya dan berhenti setelah cukup baik untuk melakukan apa yang saya inginkan. Sekarang publik, saya harap ini berguna untuk orang lain, dan mungkin seseorang mengambil di mana saya meninggalkannya.
Peter Remmers
8

Anda mungkin ingin melihat Tibbo VSPDL untuk membuat port serial virtual linux menggunakan driver Kernel - sepertinya cukup baru, dan tersedia untuk diunduh sekarang (versi beta). Tidak yakin tentang lisensinya saat ini, atau apakah mereka ingin membuatnya tersedia secara komersial di masa mendatang.

Ada alternatif komersial lainnya, seperti http://www.ttyredirector.com/ .

Dalam Open Source, Remserial (GPL) juga dapat melakukan apa yang Anda inginkan, menggunakan Unix PTY. Ini mentransmisikan data serial dalam "bentuk mentah" ke soket jaringan; Pengaturan parameter terminal seperti STTY harus dilakukan saat membuat port, mengubahnya nanti seperti yang dijelaskan di RFC 2217 tampaknya tidak didukung. Anda harus dapat menjalankan dua contoh remserial untuk membuat nullmodem virtual seperti com0com, kecuali Anda harus mengatur kecepatan port dll terlebih dahulu.

Socat (juga GPL) adalah seperti varian yang diperluas dari Remserial dengan lebih banyak pilihan, termasuk metode "PTY" untuk mengarahkan PTY ke sesuatu yang lain, yang dapat menjadi contoh lain dari Socat. Untuk Unit tets, socat mungkin lebih bagus daripada remserial karena Anda bisa langsung memasukkan file ke dalam PTY. Lihat contoh PTY di halaman manual. Sebuah patch ada di bawah "contrib" untuk memberikan dukungan RFC2217 untuk menegosiasikan pengaturan jalur serial.


sumber
6

Menggunakan tautan yang diposting di jawaban sebelumnya, saya mengkodekan sedikit contoh di C ++ menggunakan Virtual Serial Port. Saya memasukkan kode ke GitHub: https://github.com/cymait/virtual-serial-port-example .

Kode ini cukup jelas. Pertama, Anda membuat proses master dengan menjalankan ./main master dan akan mencetak ke stderr yang digunakan perangkat. Setelah itu, Anda memanggil ./main slave device, di mana device adalah perangkat yang dicetak pada perintah pertama.

Dan itu dia. Anda memiliki hubungan dua arah antara kedua proses tersebut.

Dengan menggunakan contoh ini, Anda dapat menguji aplikasi dengan mengirimkan semua jenis data, dan melihat apakah berfungsi dengan benar.

Selain itu, Anda selalu dapat menghubungkan perangkat tersebut, jadi Anda tidak perlu mengkompilasi ulang aplikasi yang Anda uji.

Mauro Ciancio
sumber
1
sementara (read (fd, & inputbyte, 1) == 1) {...} read tidak ditentukan dalam kode Anda. tulis tidak ditentukan. dekat tidak ditentukan.
Mattis Asp
4

Apakah Anda dapat menggunakan adaptor USB-> RS232? Saya punya beberapa, dan mereka hanya menggunakan driver FTDI. Kemudian, Anda harus dapat mengganti nama / dev / ttyUSB0 (atau apa pun yang dibuat) sebagai / dev / ttyS2.

Kesalahan besar
sumber
4

Saya dapat memikirkan tiga opsi:

Terapkan RFC 2217

RFC 2217 mencakup port com ke standar TCP / IP yang memungkinkan klien di satu sistem untuk meniru port serial ke program lokal, sementara secara transparan mengirim dan menerima data dan sinyal kontrol ke server di sistem lain yang sebenarnya memiliki port serial. Berikut adalah ikhtisar tingkat tinggi .

Apa yang akan Anda lakukan adalah menemukan atau mengimplementasikan driver com port klien yang akan mengimplementasikan sisi klien dari sistem pada PC Anda - tampak seperti port serial nyata tetapi pada kenyataannya memindahkan semuanya ke server. Anda mungkin bisa mendapatkan driver ini secara gratis dari Digi, Lantronix, dll untuk mendukung server port serial mandiri yang sebenarnya.

Anda kemudian akan mengimplementasikan sisi server dari koneksi secara lokal di program lain - memungkinkan klien untuk menghubungkan dan mengeluarkan data dan perintah kontrol sesuai kebutuhan.

Ini mungkin tidak sepele, tetapi RFC ada di luar sana, dan Anda mungkin dapat menemukan proyek open source yang mengimplementasikan satu atau kedua sisi koneksi.

Ubah driver port serial linux

Sebagai alternatif, sumber driver port serial untuk Linux sudah tersedia. Ambil itu, buang bagian kontrol perangkat keras, dan minta satu driver itu menjalankan dua port / dev / ttySx, sebagai loopback sederhana. Kemudian hubungkan program Anda yang sebenarnya ke ttyS2 dan simulator Anda ke ttySx lainnya.

Gunakan dua kabel USB <--> Serial dalam satu loopback

Tapi hal termudah untuk dilakukan sekarang? Belanjakan $ 40 untuk dua perangkat USB port serial, sambungkan keduanya (modem null) dan sebenarnya memiliki dua port serial nyata - satu untuk program yang Anda uji, satu untuk simulator Anda.

-Adam

Adam Davis
sumber
1
Sebenarnya kabel USB UART modem null tampak seperti solusi yang cukup elegan bagi saya karena mendukung pengujian lokal (dapatkan hub USB jika Anda kekurangan port) dan debugging jarak jauh.
Maxthon Chan
Saya belum mengulas kualitasnya, tapi ttynvt mengimplementasikan RFC 2217 melalui Linux FUSE
Daniel Santos