Domanda

Devo testare un'applicazione con porta seriale su Linux, tuttavia, la mia macchina di prova ha solo una porta seriale.

Esiste un modo per aggiungere una porta seriale virtuale a Linux e testare la mia applicazione emulando un dispositivo tramite una shell o uno script?

Nota:Non riesco a rimappare la porta, è codificata su ttys2 e devo testare l'applicazione così come è scritta.

È stato utile?

Soluzione

A questo scopo è possibile utilizzare un pty ("pseudo-teletype", dove una porta seriale è una "vera teletype").Da un'estremità, aperto /dev/ptyp5, quindi allega il tuo programma a /dev/ttyp5; ttyp5 agirà proprio come una porta seriale, ma invierà/riceverà tutto ciò che fa tramite /dev/ptyp5.

Se ne hai davvero bisogno per parlare con un file chiamato /dev/ttys2, quindi sposta semplicemente il tuo vecchio /dev/ttys2 fuori mano e creare un collegamento simbolico da ptyp5 A ttys2.

Naturalmente è possibile utilizzare un numero diverso da ptyp5.Forse scegline uno con un numero elevato per evitare duplicati, poiché anche tutti i tuoi terminali di accesso utilizzeranno ptys.

Wikipedia ha di più su ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

Altri suggerimenti

A complemento della risposta di @ slonik.

Puoi testare socat per creare una porta seriale virtuale eseguendo la seguente procedura (testata su Ubuntu 12.04):

Apri un terminale (chiamiamolo Terminale 0) ed eseguilo:

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

Il codice sopra restituisce:

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]

Apri un altro terminale e scrivi (Terminale 1):

cat < /dev/pts/2

il nome della porta di questo comando può essere modificato in base al PC.dipende dall'output precedente.

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 

dovresti usare il numero disponibile nell'area evidenziata.

Apri un altro terminale e scrivi (Terminale 2):

echo "Test" > /dev/pts/3

Ora torna al Terminale 1 e vedrai la stringa "Test".

Usa socat per questo:

Per esempio:

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

C'è anche tty0tty http://sourceforge.net/projects/tty0tty/ che è un vero e proprio emulatore null modem per Linux.

È un semplice modulo del kernel: un piccolo file sorgente.Non so perché abbia ottenuto solo il pollice in giù su sourceforge, ma per me funziona bene.La cosa migliore è che emula anche i pin hardware (RTC/CTS DSR/DTR).Implementa anche i comandi iotcl TIOCMGET/TIOCMSET e TIOCMIWAIT!

Su un kernel recente potresti ricevere errori di compilazione.Questo è facile da aggiustare.Basta inserire alcune righe nella parte superiore del sorgente module/tty0tty.c (dopo gli include):

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

Quando il modulo viene caricato, crea 4 coppie di porte seriali.I dispositivi vanno da /dev/tnt0 a /dev/tnt7 dove tnt0 è connesso a tnt1, tnt2 è connesso a tnt3, ecc.Potrebbe essere necessario correggere le autorizzazioni dei file per poter utilizzare i dispositivi.

modificare:

Immagino di essere stato un po' veloce con il mio entusiasmo.Sebbene il driver sembri promettente, sembra instabile.Non lo so per certo, ma penso che si sia schiantato un computer nell'ufficio su cui stavo lavorando da casa.Non posso controllare finché non torno in ufficio lunedì.

La seconda cosa è che TIOCMIWAIT non funziona.Il codice sembra essere copiato da un codice di esempio "tiny tty".La gestione di TIOCMIWAIT sembra a posto, ma non si riattiva mai perché manca la chiamata corrispondente a wake_up_interruptible().

modificare:

L'incidente in ufficio è stato davvero colpa dell'autista.Mancava un'inizializzazione e il codice TIOCMIWAIT completamente non testato ha causato un arresto anomalo della macchina.

Ho passato ieri e oggi a riscrivere il driver.Ci sono stati molti problemi, ma ora funziona bene per me.Manca ancora il codice per il controllo del flusso hardware gestito dal driver, ma non mi serve perché gestirò personalmente i pin utilizzando TIOCMGET/TIOCMSET/TIOCMIWAIT dal codice della modalità utente.

Se qualcuno è interessato alla mia versione del codice, mandami un messaggio e te lo invierò.

Potresti voler dare un'occhiata Tibbo VSPDL per creare una porta seriale virtuale Linux utilizzando un driver del kernel: sembra piuttosto nuovo ed è già disponibile per il download (versione beta).Non sono sicuro della licenza a questo punto, o se vogliono renderla disponibile commercialmente solo in futuro.

Esistono altre alternative commerciali, come ad esempio http://www.ttyredirector.com/.

Nell'Open Source, Riserial (GPL) può anche fare quello che vuoi, usando Unix PTY.Trasmette i dati seriali in "forma grezza" a una presa di rete;L'impostazione simile a STTY dei parametri del terminale deve essere eseguita durante la creazione della porta, modificarli successivamente come descritto in RFC 2217 non sembra essere supportato.Dovresti essere in grado di eseguire due istanze remserial per creare un nullmodem virtuale come com0com, tranne per il fatto che dovrai impostare in anticipo la velocità della porta, ecc.

Socat (anche GPL) è come una variante estesa di Remserial con molte molte più opzioni, incluso un metodo "PTY" per reindirizzare il PTY a qualcos'altro, che può essere un'altra istanza di Socat.Per Unit tets, socat è probabilmente più carino di remserial perché puoi direttamente i file cat nel PTY.Vedi il Esempio PTY sulla manpage.UN la patch esiste sotto "contrib" per fornire il supporto RFC2217 per la negoziazione delle impostazioni della linea seriale.

Utilizzando i collegamenti pubblicati nelle risposte precedenti, ho codificato un piccolo esempio in C++ utilizzando una porta seriale virtuale.Ho inserito il codice in GitHub: https://github.com/cymait/virtual-serial-port-example .

Il codice è abbastanza autoesplicativo.Innanzitutto, crei il processo master eseguendo ./main master e verrà stampato sullo stderr utilizzato dal dispositivo.Successivamente, invochi ./main slave device, dove device è il dispositivo stampato nel primo comando.

E questo è tutto.Hai un collegamento bidirezionale tra i due processi.

Usando questo esempio puoi testare l'applicazione inviando tutti i tipi di dati e vedere se funziona correttamente.

Inoltre, puoi sempre collegare simbolicamente il dispositivo, quindi non è necessario ricompilare l'applicazione che stai testando.

Saresti in grado di utilizzare un adattatore USB->RS232?Ne ho alcuni e usano solo il driver FTDI.Quindi, dovresti essere in grado di rinominare /dev/ttyUSB0 (o ​​qualunque cosa venga creata) come /dev/ttyS2 .

Mi vengono in mente tre opzioni:

Implementare RFC 2217

RFC2217 copre una porta com allo standard TCP/IP che consente a un client su un sistema di emulare una porta seriale sui programmi locali, inviando e ricevendo in modo trasparente dati e segnali di controllo a un server su un altro sistema che dispone effettivamente della porta seriale.Ecco un panoramica di alto livello.

Quello che faresti è trovare o implementare un driver della porta com client che implementi il ​​lato client del sistema sul tuo PC: sembra essere una vera porta seriale ma in realtà trasferisce tutto a un server.Potresti riuscire a ottenere questo driver gratuitamente da Digi, Lantronix, ecc. a supporto dei loro veri server di porta seriale autonomi.

Dovresti quindi implementare il lato server della connessione localmente in un altro programma, consentendo al client di connettersi e di emettere i dati e i comandi di controllo secondo necessità.

Probabilmente non è banale, ma la RFC è disponibile e potresti riuscire a trovare un progetto open source che implementa uno o entrambi i lati della connessione.

Modifica il driver della porta seriale di Linux

In alternativa, il sorgente del driver della porta seriale per Linux è prontamente disponibile.Prendilo, elimina i pezzi di controllo hardware e fai in modo che un driver esegua due porte /dev/ttySx, come un semplice loopback.Quindi collega il tuo programma reale al ttyS2 e il tuo simulatore all'altro ttySx.

Utilizzare due cavi USB<-->seriale in un loopback

Ma la cosa più semplice da fare in questo momento?Spendi $ 40 su due dispositivi USB con porta seriale, collegali insieme (modem nullo) e avrai effettivamente due porte seriali reali: una per il programma che stai testando, una per il tuo simulatore.

-Adamo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top