Come connettersi a una porta seriale semplice come usare SSH?


86

C'è un modo per connettersi a un terminale seriale proprio come faresti con SSH? Deve esserci un modo più semplice di strumenti come Minicom, come questo

$ serial /dev/ttyS0 

So di poter catprodurre l'output, /dev/ttyS0ma in questo modo è possibile solo una comunicazione, dalla porta alla console. E echofuori al porto è lo stesso ma viceversa, al porto.

Come posso realizzare la comunicazione bidirezionale con una porta seriale nel modo più semplice possibile su Unix / Linux?


2
Grandi risposte alle persone !. Sfortunatamente nessuno sembra adattarsi perfettamente al mio scopo quando lavoro con sistemi embedded con un numero limitato di comandi. Tuttavia, ho trovato un altro modo utilizzando uno script shell che aggiungo come una delle risposte alla mia domanda.
ihatetoregister,

Risposte:


69

Trovo screenil programma più utile per la comunicazione seriale poiché lo uso comunque per altre cose. Di solito è solo screen /dev/ttyS0 <speed>, anche se le impostazioni predefinite potrebbero essere diverse per il tuo dispositivo. Ti permette anche di reindirizzare qualsiasi cosa nella sessione accedendo alla modalità comando e facendo exec !! <run some program that generates output>.


3
+1 per lo schermo! Inoltre, vedi: serverfault.com/q/81544/11086
Josh

1
Vedi anche noah.org/wiki/Screen_notes#using_screen_as_a_serial_terminal e la pagina di manuale stty (1), ho dovuto aggiungere opzioni extra (es. Parità) per farlo funzionare.
Lekensteyn,

3
mi vergogno di aver collegato erroneamente il TX / RX: o
Lekensteyn

screenè fantastico, ma non penso che sia più semplice di minicom:-)
Ciro Santilli 29 改造 中心 法轮功 六四 事件

1
@CiroSantilli 刘晓波 死 六四 事件 法轮功 - Lo schermo potrebbe non essere più semplice di Minicom ma poiché uso già Screen, per me è meno complicato fare le mie cose seriali con Screen, eliminando completamente la necessità di Minicom.
yeti,

48

sfondo

Il motivo principale per cui è necessario un programma come minicomquello di comunicare su una porta seriale è che la porta deve essere impostata prima di avviare una connessione. Se non fosse stato impostato in modo appropriato, i comandi cate echonon farebbero per te quello che potresti aspettarti. Si noti che una volta eseguito un programma simile minicom, la porta viene lasciata con le impostazioni minicomutilizzate. È possibile eseguire una query sulle impostazioni di comunicazione utilizzando il sttyprogramma in questo modo:

stty < /dev/ttyS0

Se l'hai fatto bene; dopo aver avviato il computer e prima di eseguire qualsiasi altro programma come minicom,le impostazioni di comunicazione saranno alle loro impostazioni predefinite. Questi sono probabilmente diversi da quelli necessari per stabilire la connessione. In questa situazione, l'invio dei comandi cato echoalla porta produrrà immondizia o non funzionerà affatto.

Esegui di sttynuovo dopo l' uso minicome noterai che le impostazioni sono impostate su ciò che il programma stava usando.

Comunicazione seriale minima

Fondamentalmente, sono necessarie due cose per avere una comunicazione bidirezionale attraverso una porta seriale: 1) configurare la porta seriale e 2) aprire la pseudo-tty lettura-scrittura.

Il programma più semplice che conosco è questo picocom. Puoi anche usare uno strumento come setserialimpostare la porta e quindi interagire con essa direttamente dalla shell.


5
picocominoltre ti permetterà di connetterti a una porta seriale senza riconfigurarla ( --noinit) e ti permetterà di uscire senza ripristinare la configurazione della porta seriale ( --noreseto usare Ctrl-A/ Ctrl-Qper uscire picocom). Ho trovato picocommolto più facile da usare rispetto a minicom. Per motivi che non ho capito, a volte Minicom semplicemente non invierà né riceverà dati su una porta che ha funzionato qualche istante prima o con cui Picocom non ha problemi. Probabilmente è un'opzione di configurazione arcana, ma qualunque cosa sia non riesco a capirlo (e questo comportamento si è verificato su più di una macchina).
Michael Burr,

+1 per picocom! Ho scoperto che non ero in grado di scrivere comandi sul dispositivo seriale senza i finali di linea corretti: avevo bisogno di usare le --omap crcrlf --echoopzioni
user2561747

24

Se UUCP è installato sul sistema, è possibile utilizzare il comando cu , ad es

 $ cu -l /dev/ttyS0 -s 9600

Utilizzare ~^Do ~.per uscire.
iman

24

Ho trovato un modo usando uno script di shell qui che viene messo catcome processo in background e un ciclo while che legge l'input dell'utente e echolo invia alla porta. L'ho modificato per essere più generale e si adattava perfettamente al mio scopo.

#!/bin/sh

# connect.sh

# Usage:
# $ connect.sh <device> <port speed>
# Example: connect.sh /dev/ttyS0 9600

# Set up device
stty -F $1 $2

# Let cat read the device $1 in the background
cat $1 &

# Capture PID of background process so it is possible to terminate it when done
bgPid=$!

# Read commands from user, send them to device $1
while read cmd
do
   echo "$cmd" 
done > $1

# Terminate background read process
kill $bgPid

1
Inoltre, ho creato una versione leggermente modificata di seguito che può anche inviare Ctrl + C e Ctrl + Z.
Fritz,

@Fritz Nice find! Quindi, se lo capissi bene, il processo in background non verrebbe mai ucciso perché $? non sembra espandersi a qualcosa di giusto?
ihatetoregister,

1
@ihatetoregister: non del tutto corretto. Il processo in background viene interrotto, ma non per i motivi che ci si potrebbe aspettare. $?si espande nel codice di uscita dell'ultimo comando non in background (in questo caso stty -F $1 $2), quindi si espande a 0 quando non si sono verificati errori. Quindi, l'ultima linea diventa kill 0che a sua volta sembra uccidere la shell corrente e tutti i suoi figli (si comporta in modo diverso nelle shell interattive credo). Per tutti i dettagli vedere la seguente spiegazione: unix.stackexchange.com/questions/67532/…
Fritz,

1
Inoltre, il vero gotcha nel tuo script è che il processo in background viene interrotto solo se premi Ctrl + D per terminare il tuo script, perché questo termina il whileciclo in modo pulito. Se lo uccidi con Ctrl + C o con il killcomando, il catprocesso rimane attivo. Per risolvere il problema, è necessario utilizzare il trapcomando per eseguire kill $bgPidquando la shell esce, come fa il mio script in basso . Onestamente, non mi dispiacerebbe nemmeno se avessi appena aggiunto tutto il mio script al tuo post. Ho provato a farlo, ma la modifica è stata respinta.
Fritz,

Potresti chiarire da dove viene la connessione, poiché questo è commentato nella tua risposta
Chris Halcrow,

14

Prova http://tio.github.io

"tio" è una semplice applicazione terminale TTY che presenta un'interfaccia a riga di comando semplice per connettersi facilmente ai dispositivi TTY per input / output di base.

L'uso tipico è senza opzioni. Per esempio:

tio /dev/ttyS0

Che corrisponde alle opzioni comunemente usate:

tio --baudrate 115200 --databits 8 --flow none --stopbits 1 --parity none /dev/ttyS0

Viene fornito con supporto per il completamento automatico della shell completa per tutte le opzioni.


3
Sto usando msys2su Windows ed è possibile installare tiocon pacman -S tioperché è tra i pacchetti disponibili per impostazione predefinita. screen, picocomecc. non lo sono. Grazie!
Kohányi Róbert,

12

Questo script si basa su un'altra risposta , ma invia tutto sulla porta seriale (tranne Ctrl + Q), non solo i singoli comandi seguiti da Enter. Ciò consente di utilizzare Ctrl + C o Ctrl + Z sull'host remoto e di utilizzare programmi "GUI" interattivi come aptitude o alsamixer. Può essere chiuso premendo Ctrl + Q.

#!/bin/bash

if [[ $# -lt 1 ]]; then
    echo "Usage:"
    echo "  femtocom <serial-port> [ <speed> [ <stty-options> ... ] ]"
    echo "  Example: $0 /dev/ttyS0 9600"
    echo "  Press Ctrl+Q to quit"
fi

# Exit when any command fails
set -e

# Save settings of current terminal to restore later
original_settings="$(stty -g)"

# Kill background process and restore terminal when this shell exits
trap 'set +e; kill "$bgPid"; stty "$original_settings"' EXIT

# Remove serial port from parameter list, so only stty settings remain
port="$1"; shift

# Set up serial port, append all remaining parameters from command line
stty -F "$port" raw -echo "$@"

# Set current terminal to pass through everything except Ctrl+Q
# * "quit undef susp undef" will disable Ctrl+\ and Ctrl+Z handling
# * "isig intr ^Q" will make Ctrl+Q send SIGINT to this script
stty raw -echo isig intr ^Q quit undef susp undef

# Let cat read the serial port to the screen in the background
# Capture PID of background process so it is possible to terminate it
cat "$port" & bgPid=$!

# Redirect all keyboard input to serial port
cat >"$port"

7

A proposito, il pacchetto putty (che funziona su Linux) include il supporto seriale.


4

Un altro problema che può verificarsi è che potrebbe essere necessario impostare il proprio account utente sul gruppo "dialout" per accedere alla porta seriale.

sudo usermod -a -G dialout $USER

3

Putty funziona bene su Linux e offre qualche comodità, specialmente per le comunicazioni seriali. Ha uno svantaggio che non sono stato in grado di risolvere direttamente: nessuna copia e incolla dalla stessa finestra di Putty. La versione di Windows ha una bella copia automatica negli Appunti in evidenza, fai clic con il tasto destro per incollare il comportamento (e ci sono plugin eccellenti sia per Chrome che per Firefox per abilitare lo stesso comportamento), ma su Linux, nessuna copia ama AFAIK.

Se la mancanza di copia è un problema (lo è per me), attiva l'accesso al mastice e apri una finestra terminale standard # tail -f putty.loge il testo bidirezionale è disponibile per l'azione copypasta standard.


1
Trovo che Putty sotto Linux non incolli "gli appunti" (ciò che copi con control-C), ma inserirà "la selezione primaria" (ciò che hai attualmente selezionato in alcuni programmi) con il mouse centrale. Allo stesso modo puoi selezionare i personaggi nella schermata di Putty per definire la selezione principale. Ma se voglio che il testo da una schermata Putty venga trasferito su qualche VM, ho bisogno che sia negli Appunti, quindi devo usare un programma intermedio per ricevere il testo dalla selezione principale e quindi copiarlo negli Appunti.
cardiff space man


2

Dipende da quello che vuoi fare. Vuoi eseguire una shell o un'applicazione in modo interattivo dal terminale, collegarti a un altro computer sulla linea seriale, automatizzare la comunicazione con un dispositivo tramite una porta seriale?

Se vuoi una comunicazione bidirezionale, presumo che tu voglia qualcosa di interattivo con un essere umano sul terminale. È possibile configurare il sistema in modo da consentire gli accessi da un terminale tramite una porta seriale impostando una sessione getty (1) sulla porta seriale - getty è lo strumento per impostare un terminale e consentire l'accesso su di esso. Inserisci una voce nel tuo file inittab (5) per eseguirlo sulla porta seriale appropriata su una respawnbase.

Se vuoi connetterti a un dispositivo e avviare conversazioni bidirezionali automatiche, puoi vedere se aspettarti ti darà quello che vuoi. Utilizzare stty (1) per configurare la porta sulla giusta parità, baud rate e altre impostazioni pertinenti.

Se si desidera comunicare in modo interattivo con un altro computer tramite la porta seriale, sarà necessario il software di emulazione terminale. Questo fa parecchio: imposta la porta, interpreta ANSI o altre sequenze di comandi del terminale (ANSI era lungi dall'essere l'unico standard supportato dai terminali seriali). Molti emulatori di terminali supportano anche protocolli di trasferimento file come kermit o zmodem.

I dettagli delle comunicazioni seriali e degli I / O dei terminali sono piuttosto complessi; puoi leggere più di quanto tu abbia mai voluto sapere sull'argomento nel howto seriale.


1

Potresti dare un'occhiata

http://serialconsole.sourceforge.net

Pro: non ha ovvi problemi di sicurezza come minicom o picocom (se non hai problemi a fornire agli utenti l'accesso alla shell, nessun problema, ma molto probabilmente ne hai uno se vuoi configurare un terminal server ... )


1

Devi essere sicuro di avere i permessi di scrittura in lettura corretti sul dispositivo, puoi vederlo con:

$ls -l /dev/[serial device]

Mi affido allo script che hai trovato e apportato alcune modifiche.

Per i sistemi di sviluppo che ho usato ormai, avevano bisogno di:

  • Nessuna parità e
  • Un po 'di stop

Questi valori sono quelli predefiniti nello script.

Quindi, per connetterti, puoi usarlo nel modo seguente:

./connect.sh /dev/[serial device] [baud speed]

Esempio:

$./connect.sh /dev/ttyUSB0 19200

script:

#!/bin/bash

# connect.sh


#Taken from example modified by: ihatetoregister
# On stack exchange, thread:
# http://unix.stackexchange.com/questions/22545/how-to-connect-to-a-serial-port-as-simple-as-using-ssh
# Modified by Rafael Karosuo <rafaelkarosuo@gmail.com>
#   - parity enabling and amount of stop bits
#   - no execution without minimum params
#   - exit code for stty
#   - bgPid fix, used $! instead of $? to take the PID of cat proc in background.
#   - exit command to end the program
#   - CR termination and strip of NL added by READ command, in order to make $cmd\r\n format instead of \n$cmd\n


# Usage:
# $./connect.sh <device> <port speed> [# Stop bits] [parity]

# Stop bits 1|2
# Parity even | odd

# If no last two params, then default values stopbits=1, parity=disab

# Example: 
# connect.sh /dev/ttyS0 9600 1 even, this will use 1 stop bit and even parity
# connect.sh /dev/ttyS0 9600, this will take default values for parity and stopbit


#Check if at least port and baud params provided
if [ -z "$1" ] || [ -z "$2" ]; then
    printf "\nusage: ./connect.sh <device> <port speed> [# Stop bits 1|2] [parity even|odd]\n\tNeed to provide at least port and baud speed parameters.\n\texample:connect.sh /dev/ttyS0 9600\n\n"
    exit 1;
else
    case "$3"   in
        2) stopb="cstopb";;
        *) stopb="-cstopb";;
    esac

    if [ "$4" = "even" ]; then
        par="-parodd"
    elif [ "$4" = "odd" ]; then
        par="parodd"
    else
        par="-parity"
    fi
    printf "\nThen stty -F $1 $2 $stopb $par\n";
fi

# Set up device
stty -F "$1" "$2" "$stopb" "$par" -icrnl

# Check if error ocurred
if [ "$?" -ne 0 ]; then
    printf "\n\nError ocurred, stty exited $?\n\n"
    exit 1;
fi

# Let cat read the device $1 in the background
cat -v "$1" &

# Capture PID of background process so it is possible to terminate it when done
bgPid="$!"

# Read commands from user, send them to device $1
while [ "$cmd" != "exit" ]
do
   read cmd
   echo -e "\x08$cmd\x0D" > "$1" #strip off the \n that read puts and adds \r for windows like LF

done

# Terminate background read process
kill "$bgPid"

PS: devi sapere che tipo di feed di linea sta usando il tuo sistema di ricezione poiché questo determinerà come dovrai inviare i comandi nel mio caso avevo bisogno di un Windows come LF, significa che devo inviare

command\r

Valori ASCII per:

  • LF: 0Ah, avanzamento riga "\ n"
  • CR: 0Dh, ritorno carrige "\ r"
  • BS: 08h, spazio dietro "<-"

1
(1)  #!/bin/shviene ignorato se non è la prima riga del file. (2) Davvero? Stai usando 1specificare anche la parità e 2per specificare strano ? (3) È convenzionale avere un messaggio "utilizzo" o "aiuto" che documenta tutti i parametri, non solo quelli obbligatori. (4) Si dovrebbe sempre citare la shell riferimenti variabili (ad esempio, "$1", "$2", "$3", "$4", "$stopb", "$par", "$bgPid", e anche "$?"e "$!") a meno che non si dispone di una buona ragione per non farlo, e siete sicuri di sapere cosa si sta facendo.
Scott,


1

Mi chiedo perché nessuno abbia menzionato ser2net .

Esempio /etc/ser2net.conf:

3000:telnet:600:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT
3001:telnet:600:/dev/ttyUSB1:115200 8DATABITS NONE 1STOPBIT
3002:telnet:600:/dev/ttyUSB2:115200 8DATABITS NONE 1STOPBIT
3003:telnet:600:/dev/ttyUSB3:115200 8DATABITS NONE 1STOPBIT

Puoi collegarti alla porta seriale in modo semplice come:

telnet localhost 3000

O da remoto:

telnet <ip> 3000

Oppure imposta il port forwarding sul tuo router ed esponilo a Internet, in modo da poterti connettere da qualsiasi luogo (salta i problemi di sicurezza, sto parlando di flessibilità).


0

Un'altra opzione semplice è accedere alla macchina tramite ssh con la -Xbandiera ed eseguire un programma come putty o gtkterm.

Così:

$ ssh -X <user>@<machine_address>

$ sudo apt-get install gtkterm (if not installed already)

$ gtkterm

Dovrebbe avviare l'interfaccia grafica sul PC client e da lì è possibile accedere alla porta seriale come se si trovasse nell'host.

Disclaimer: provato solo con macchine Ubuntu. Immagino che non funzionerà con macchine senza interfacce grafiche.

Dal manuale di ssh:

-X

Abilita l'inoltro X11. Questo può anche essere specificato su base per host in un file di configurazione. L'inoltro X11 deve essere abilitato con cautela. Gli utenti con la possibilità di ignorare le autorizzazioni dei file sull'host remoto (per il database di autorizzazioni X dell'utente) possono accedere al display X11 locale tramite la connessione inoltrata. Un utente malintenzionato può quindi essere in grado di eseguire attività come il monitoraggio della pressione dei tasti. Per questo motivo, l'inoltro X11 è soggetto alle limitazioni dell'estensione X11 SECURITY per impostazione predefinita. Per ulteriori informazioni, fare riferimento all'opzione ssh -Y e alla direttiva ForwardX11Trusted in ssh_config (5).

-Y

Abilita l'inoltro X11 affidabile. Gli inoltri X11 affidabili non sono soggetti ai controlli dell'estensione X11 SECURITY.

Quindi usa -Yse la sicurezza è un problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.