Jak połączyć się z portem szeregowym tak prostym, jak przy użyciu SSH?


86

Czy istnieje sposób na połączenie z terminalem szeregowym, tak jak w przypadku SSH? Musi istnieć prostszy sposób niż narzędzia takie jak Minicom

$ serial /dev/ttyS0 

Wiem, że mogę catwyprowadzać dane wyjściowe, /dev/ttyS0ale w ten sposób możliwa jest tylko jedna komunikacja, od portu do konsoli. A echodo portu jest dokładnie tak samo, ale odwrotnie, do portu.

Jak mogę zrealizować dwukierunkową komunikację z portem szeregowym w najprostszy możliwy sposób w systemach Unix / Linux?


2
Świetne odpowiedzi ludzie!. Niestety, nikt nie wydaje się w pełni odpowiadać mojemu celowi podczas pracy z systemami osadzonymi z ograniczonym zestawem poleceń. Znalazłem jednak inny sposób, używając skryptu powłoki, który dodaję jako jedną z odpowiedzi na moje pytanie.
ihatetoregister

Odpowiedzi:


69

Znajduję screennajbardziej przydatny program do komunikacji szeregowej, ponieważ i tak używam go do innych celów. Zazwyczaj jest to po prostu screen /dev/ttyS0 <speed>, chociaż domyślne ustawienia mogą być inne dla twojego urządzenia. Umożliwia także przesyłanie czegokolwiek do sesji, wchodząc w tryb poleceń i wykonując czynności exec !! <run some program that generates output>.


3
+1 dla ekranu! Zobacz także: serverfault.com/q/81544/11086
Josh

1
Zobacz także noah.org/wiki/Screen_notes#using_screen_as_a_serial_terminal i podręcznik strony stty (1), musiałem dodać dodatkowe opcje (np. Parzystość), aby działało.
Lekensteyn,

3
czuje się zawstydzony, że źle podłączyłem TX / RX: o
Lekensteyn,

screenjest niesamowity, ale nie wydaje mi się, żeby było to prostsze niż minicom:-)
Ciro Santilli 29 改造 中心 法轮功 六四 事件

1
@CiroSantilli 刘晓波 死 六四 事件 法轮功 - Screen może nie być prostszy niż Minicom, ale ponieważ już korzystam z Screen, dla mnie mniej skomplikowane jest robienie seryjnych rzeczy z Screenem, całkowicie eliminując potrzebę Minicom.
yeti

48

tło

Głównym powodem, dla którego potrzebny jest jakikolwiek program minicomdo komunikacji przez port szeregowy, jest konieczność skonfigurowania portu przed nawiązaniem połączenia. Gdyby nie został odpowiednio skonfigurowany, polecenia cati echonie zrobiłyby dla ciebie tego, czego można się spodziewać. Zauważ, że po uruchomieniu programu podobnego minicomdo portu pozostaną minicomużywane ustawienia . Możesz sprawdzić ustawienia komunikacji za pomocą takiego sttyprogramu:

stty < /dev/ttyS0

Jeśli dobrze to zrobiłeś; po uruchomieniu komputera i przed uruchomieniem jakiegokolwiek innego programu, takiego jak minicom,ustawienia komunikacji, będą miały ustawienia domyślne. Prawdopodobnie różnią się one od potrzebnych do nawiązania połączenia. W tej sytuacji wysłanie poleceń catlub echodo portu albo spowoduje powstanie śmieci, albo w ogóle nie zadziała.

Uruchom sttyponownie po użyciu minicom, a zauważysz, że ustawienia są ustawione zgodnie z tym, czego program używał.

Minimalna komunikacja szeregowa

Zasadniczo potrzebne są dwie rzeczy do dwukierunkowej komunikacji przez port szeregowy: 1) konfiguracja portu szeregowego i 2) otwarcie pseudo-tty odczytu-zapisu.

Najbardziej podstawowym programem, jaki znam, jest taki picocom. Możesz także użyć narzędzia, takiego jak setserialskonfigurować port, a następnie wchodzić z nim w interakcję bezpośrednio z powłoki.


5
picocompozwoli ci także połączyć się z portem szeregowym bez jego ponownej konfiguracji ( --noinit) i pozwoli ci wyjść bez przywracania konfiguracji portu szeregowego ( --noresetlub użyj Ctrl-A/, Ctrl-Qaby wyjść picocom). Odkryłem, że picocomjest o wiele łatwiejszy w użyciu niż minicom. Z powodów, których nie zorientowałem się, Minicom kiedyś po prostu nie wysyła ani nie odbiera danych na porcie, który działał chwilę wcześniej lub z którym Picocom nie ma problemów. Prawdopodobnie jest to jakaś tajemnicza opcja konfiguracji, ale cokolwiek to jest, nie mogę tego rozgryźć (a takie zachowanie miało miejsce na więcej niż jednej maszynie).
Michael Burr

+1 za picocom! Odkryłem, że nie byłem w stanie pisać poleceń na urządzeniu szeregowym bez poprawnych zakończeń linii: Potrzebowałem użyć --omap crcrlf --echoopcji
2561747,

24

Jeśli UUCP jest zainstalowany w systemie, możesz użyć polecenia cu , np

 $ cu -l /dev/ttyS0 -s 9600

Użyj ~^Dlub, ~.aby wyjść.
iman

24

Znalazłem sposób, używając skryptu powłoki , który umieszcza się catjako proces w tle i pętlę while, która odczytuje dane wejściowe użytkownika i wysyła echoje do portu. Zmodyfikowałem go, aby był bardziej ogólny i idealnie pasował do mojego celu.

#!/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
Również zrobiłem nieco zmodyfikowaną wersję poniżej której można również wysłać Ctrl + C i Ctrl + Z.
Fritz

@ Fritz Ładne znalezisko! Więc jeśli dobrze to zrozumiem, proces w tle nigdy nie zostanie zabity, ponieważ $? wydaje się, że nie rozwija się do niczego, prawda?
ihatetoregister

1
@ihatetoregister: Niezupełnie poprawne. Proces w tle zostaje zabity, ale nie z powodów, których można się spodziewać. $?rozwija się do kodu wyjścia ostatniego polecenia niebędącego tłem (w tym przypadku stty -F $1 $2), więc rozwija się do 0, gdy nie wystąpił błąd. W ten sposób staje się ostatnia linia, kill 0która z kolei wydaje się zabijać obecną powłokę i wszystkie jej dzieci (zachowuje się inaczej w interaktywnych powłokach, jak sądzę). Aby poznać wszystkie szczegóły, zobacz następujące wyjaśnienie: unix.stackexchange.com/questions/67532/...
Fritz

1
Jednak prawdziwa gotcha w twoim skrypcie polega na tym, że proces w tle jest zabijany tylko wtedy, gdy naciśniesz Ctrl + D, aby zakończyć skrypt, ponieważ to kończy whilepętlę. Jeśli zabijesz go za pomocą Ctrl + C lub za pomocą killpolecenia, catproces pozostanie aktywny. Aby to naprawić, musisz użyć trappolecenia, aby wykonać kill $bgPidpo wyjściu powłoki, tak jak robi to mój skrypt poniżej . Szczerze mówiąc, nie miałbym nic przeciwko, gdybyś po prostu dodał cały mój skrypt do swojego postu. Próbowałem to zrobić, ale edycja została odrzucona.
Fritz

Czy możesz wyjaśnić, gdzie pojawia się połączenie, ponieważ zostało to skomentowane w Twojej odpowiedzi
Chris Halcrow,

14

Spróbuj http://tio.github.io

„tio” to prosta aplikacja terminalowa TTY, która posiada prosty interfejs wiersza poleceń, umożliwiający łatwe podłączenie do urządzeń TTY w celu uzyskania podstawowych danych wejściowych / wyjściowych.

Typowe zastosowanie jest bez opcji. Na przykład:

tio /dev/ttyS0

Co odpowiada najczęściej używanym opcjom:

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

Posiada pełną obsługę automatycznego uzupełniania powłoki dla wszystkich opcji.


3
Używam msys2Windows można zainstalować tioz pacman -S tioponieważ jest wśród dostępnych pakietów domyślnie. screen, picocomitp. nie są. Dzięki!
Kohányi Róbert

12

Ten skrypt jest oparty na innej odpowiedzi , ale wysyła wszystko przez port szeregowy (oprócz Ctrl + Q), a nie tylko pojedyncze polecenia, po których następuje Enter. Dzięki temu możesz używać Ctrl + C lub Ctrl + Z na zdalnym hoście i używać interaktywnych programów „GUI”, takich jak aptitude lub alsamixer. Można go zamknąć, naciskając 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

BTW, pakiet putty (który działa w systemie Linux) obejmuje obsługę szeregową.


4

Innym problemem, który może wystąpić, może być konieczność ustawienia konta użytkownika w grupie „dialout” w celu uzyskania dostępu do portu szeregowego.

sudo usermod -a -G dialout $USER

3

Putty działa dobrze w systemie Linux i oferuje pewną wygodę, szczególnie w przypadku komunikacji szeregowej. Ma jedną wadę, której nie byłem w stanie rozwiązać bezpośrednio: nie kopiuj-wklej z samego okna Putty. Wersja systemu Windows ma piękne automatyczne kopiowanie do schowka po podświetleniu, kliknięcie prawym przyciskiem myszy, aby wkleić zachowanie (i istnieją doskonałe wtyczki zarówno dla chrome, jak i firefox, aby umożliwić takie samo zachowanie), ale w Linuksie nie ma miłości do kopiowania AFAIK.

Jeśli brak kopii stanowi problem (dotyczy mnie), włącz logowanie i otwórz standardowe okno terminala, # tail -f putty.loga tekst dwukierunkowy jest dostępny dla standardowej akcji copypasta.


1
Uważam, że Putty pod Linuksem nie wkleja „schowka” (co kopiujesz za pomocą Ctrl-C), ale wstawi „środkową selekcję” (co aktualnie wybrałeś w jakimś programie) za pomocą środkowej myszy. Podobnie możesz wybrać postacie na ekranie Putty, aby zdefiniować podstawowy wybór. Ale jeśli chcę, aby tekst z ekranu Putty został przeniesiony na jakąś maszynę wirtualną, potrzebuję go jako schowka, więc muszę użyć programu pośredniczącego, aby otrzymać tekst z głównego zaznaczenia, a następnie skopiować go do schowka.
mężczyzna z kosmosu w Cardiff


2

To zależy od tego, co chcesz zrobić. Czy chcesz uruchomić powłokę lub aplikację interaktywnie z terminala, połączyć się z innym komputerem za pośrednictwem linii szeregowej, zautomatyzować komunikację z urządzeniem przez port szeregowy?

Jeśli chcesz komunikacji dwukierunkowej, zakładam, że chcesz czegoś interaktywnego z człowiekiem na terminalu. Możesz skonfigurować system, aby zezwalał na logowanie z terminala przez port szeregowy, ustawiając sesję getty (1) na porcie szeregowym - getty jest narzędziem do konfigurowania terminala i zezwala na logowanie. Umieść wpis w pliku inittab (5) , aby uruchomić go na odpowiednim porcie szeregowym respawn.

Jeśli chcesz połączyć się z urządzeniem i zainicjować zautomatyzowane rozmowy dwukierunkowe, możesz sprawdzić, czy oczekujesz, że dostaniesz to, czego chcesz. Użyj stty (1), aby skonfigurować port do właściwej parzystości, prędkości transmisji i innych odpowiednich ustawień.

Jeśli chcesz komunikować się interaktywnie z innym komputerem przez port szeregowy, potrzebujesz oprogramowania do emulacji terminala. To robi całkiem sporo - konfiguruje port, interpretuje ANSI lub inne sekwencje poleceń terminala (ANSI nie był jedynym standardem obsługiwanym przez terminale szeregowe). Wiele emulatorów terminali obsługuje również protokoły przesyłania plików, takie jak kermit lub zmodem.

Wejścia i wyjścia komunikacji szeregowej i I / O terminali są dość złożone; możesz przeczytać więcej niż kiedykolwiek chciałeś wiedzieć na ten temat w serialu Howto.


1

Możesz rzucić okiem

http://serialconsole.sourceforge.net

Pro: nie ma oczywistych problemów związanych z bezpieczeństwem, takie jak minicom lub picocom (jeśli nie masz problemu daje użytkownikom dostęp do powłoki, nie ma problemu, ale najprawdopodobniej zrobić masz, jeśli chcesz skonfigurować serwer terminali ... )


1

Musisz mieć pewność, że masz prawidłowe uprawnienia do odczytu na urządzeniu, możesz to zobaczyć za pomocą:

$ls -l /dev/[serial device]

Opieram się na skrypcie, który znalazłeś i dokonałeś pewnych modyfikacji.

W przypadku systemów programistycznych, z których już korzystałem, potrzebowały:

  • Brak parzystości i
  • Jeden bit stopu

Te wartości są domyślne w skrypcie.

Aby się połączyć, możesz użyć tego w następujący sposób:

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

Przykład:

$./connect.sh /dev/ttyUSB0 19200

Scenariusz:

#!/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: Musisz wiedzieć, jaki rodzaj linii jest używany w twoim systemie odbiorczym, ponieważ to określi, jak będziesz musiał wysyłać polecenia w moim przypadku Potrzebowałem systemu Windows takiego jak LF, co oznacza, że ​​muszę wysłać

command\r

Wartości ASCII dla:

  • LF: 0Ah, przesunięcie linii „\ n”
  • CR: 0Dh, powrót carrige „\ r”
  • BS: 08h, spacja „<-”

1
(1)  #!/bin/shjest ignorowane, jeśli nie jest to pierwszy wiersz pliku. (2) Poważnie? Używasz 1określić nawet parytetu i 2określić dziwne ? (3) Zwykle jest komunikat „użycie” lub „pomoc”, który dokumentuje wszystkie parametry, nie tylko te obowiązkowe. (4) Należy zawsze podać swój powłoki referencje zmienne (np "$1", "$2", "$3", "$4", "$stopb", "$par", "$bgPid", a nawet "$?"i "$!"), chyba że masz dobry powód, aby nie, i jesteś pewien, że wiesz co robisz.
Scott,


1

Zastanawiam się, dlaczego nikt nie wspomniał o ser2net .

Przykład /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

Możesz podłączyć się do portu szeregowego tak łatwo jak:

telnet localhost 3000

Lub zdalnie:

telnet <ip> 3000

Lub nawet skonfiguruj przekierowanie portów na routerze i udostępniaj go w Internecie, abyś mógł się z nim połączyć z dowolnego miejsca (pomińmy kwestie bezpieczeństwa, mówię o elastyczności).


0

Inną łatwą opcją jest dostęp do maszyny przez ssh za pomocą -Xflagi i uruchomienie programu takiego jak putty lub gtkterm.

Więc:

$ ssh -X <user>@<machine_address>

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

$ gtkterm

Powinien uruchomić interfejs graficzny na komputerze klienckim, a stamtąd można uzyskać dostęp do portu szeregowego, jakbyś był na hoście.

Oświadczenie: Wypróbowałem to tylko na maszynach ubuntu. Zgaduję, że nie będzie działać z maszynami bez interfejsów graficznych.

Z podręcznika ssh:

-X

Umożliwia przekazywanie X11. Można to również określić dla każdego hosta w pliku konfiguracyjnym. Przekazywanie X11 powinno być włączone ostrożnie. Użytkownicy z możliwością obejścia uprawnień do plików na zdalnym hoście (dla bazy danych autoryzacji X użytkownika) mogą uzyskać dostęp do lokalnego wyświetlacza X11 za pośrednictwem przekierowanego połączenia. Osoba atakująca może wówczas być w stanie wykonywać czynności, takie jak monitorowanie naciśnięć klawiszy. Z tego powodu przekazywanie X11 podlega domyślnie ograniczeniom rozszerzenia X11 SECURITY. Więcej informacji można znaleźć w opcji ssh -Y i dyrektywie ForwardX11Trusted w ssh_config (5).

-Y

Umożliwia zaufane przekazywanie X11. Zaufane przekazywanie X11 nie podlega kontrolom rozszerzenia X11 SECURITY.

Więc użyj, -Yjeśli bezpieczeństwo stanowi problem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.