Techniki ograniczania / synchronizacji protokołu szeregowego


24

Ponieważ asynchroniczna komunikacja szeregowa jest obecnie szeroko rozpowszechniona wśród urządzeń elektronicznych, uważam, że wielu z nas od czasu do czasu napotyka takie pytanie. Rozważ urządzenie elektroniczne Di komputer PCpodłączony do linii szeregowej (RS-232 lub podobny) i wymagane do ciągłej wymiany informacji . Tj. Wysyła PCkażdą ramkę poleceń X msi Dodpowiada każdą z raportem statusu / ramką telemetryczną Y ms(raport może być wysłany jako odpowiedź na żądanie lub niezależnie - tutaj tak naprawdę nie ma znaczenia). Ramki komunikacyjne mogą zawierać dowolne dane binarne . Zakładając, że ramki komunikacyjne są pakietami o stałej długości.

Problem:

Ponieważ protokół jest ciągły, strona odbierająca może utracić synchronizację lub po prostu „dołączyć” w środku wysyłanej ramki, więc po prostu nie będzie wiedział, gdzie jest początek ramki (SOF). Dane mają inne znaczenie w zależności od ich pozycji względem SOF, otrzymane dane zostaną uszkodzone, potencjalnie na zawsze.

Wymagane rozwiązanie

Niezawodny schemat ograniczania / synchronizacji do wykrywania SOF z krótkim czasem odzyskiwania (tj. Nie powinno to zająć więcej niż, powiedzmy, 1 ramka, aby ponownie zsynchronizować).

Istniejące techniki, które znam (i używam):

1) Nagłówek / suma kontrolna - SOF jako predefiniowana wartość bajtu. Suma kontrolna na końcu ramki.

  • Plusy: proste.
  • Minusy: niewiarygodne. Nieznany czas odzyskiwania.

2) Wypychanie bajtów:

  • Plusy: niezawodne, szybkie odzyskiwanie, można go używać z dowolnym sprzętem
  • Wady: Nie nadaje się do komunikacji opartej na ramkach o stałym rozmiarze

3) Oznaczenie 9-go bitu - dodaj każdy bajt dodatkowym bitem, podczas gdy SOF jest oznaczony, 1a bajty danych są oznaczone 0:

  • Plusy: niezawodne, szybkie odzyskiwanie
  • Minusy: Wymaga wsparcia sprzętowego. Nieobsługiwany bezpośrednio przez większość PCsprzętu i oprogramowania.

4) Oznakowanie 8-go bitu - rodzaj emulacji powyższego, przy użyciu 8-go bitu zamiast 9-tego, co pozostawia tylko 7 bitów na każde słowo danych.

  • Plusy: niezawodne, szybkie odzyskiwanie, można go używać z dowolnym sprzętem.
  • Wady: Wymaga schematu kodowania / dekodowania z / do konwencjonalnej reprezentacji 8-bitowej do / z reprezentacji 7-bitowej. Nieco marnotrawstwo.

5) Na podstawie limitu czasu - załóż SOF jako pierwszy bajt następujący po określonym czasie bezczynności.

  • Plusy: brak narzutu danych, proste.
  • Minusy: Nie tak niezawodny. Nie działa dobrze w przypadku słabych systemów pomiaru czasu, takich jak np. Komputer z systemem Windows. Potencjalny narzut przepustowości.

Pytanie: Jakie są inne możliwe techniki / rozwiązania mające na celu rozwiązanie problemu? Czy możesz wskazać wady na powyższej liście, które można łatwo obejść, usuwając je w ten sposób? Jak (lub chciałbyś) zaprojektować protokół systemowy?

serial  communication  protocol  brushless-dc-motor  hall-effect  hdd  scr  flipflop  state-machines  pic  c  uart  gps  arduino  gsm  microcontroller  can  resonance  memory  microprocessor  verilog  modelsim  transistors  relay  voltage-regulator  switch-mode-power-supply  resistance  bluetooth  emc  fcc  microcontroller  atmel  flash  microcontroller  pic  c  stm32  interrupts  freertos  oscilloscope  arduino  esp8266  pcb-assembly  microcontroller  uart  level  arduino  transistors  amplifier  audio  transistors  diodes  spice  ltspice  schmitt-trigger  voltage  digital-logic  microprocessor  clock-speed  overclocking  filter  passive-networks  arduino  mosfet  control  12v  switching  temperature  light  luminous-flux  photometry  circuit-analysis  integrated-circuit  memory  pwm  simulation  behavioral-source  usb  serial  rs232  converter  diy  energia  diodes  7segmentdisplay  keypad  pcb-design  schematics  fuses  fuse-holders  radio  transmitter  power-supply  voltage  multimeter  tools  control  servo  avr  adc  uc3  identification  wire  port  not-gate  dc-motor  microcontroller  c  spi  voltage-regulator  microcontroller  sensor  c  i2c  conversion  microcontroller  low-battery  arduino  resistors  voltage-divider  lipo  pic  microchip  gpio  remappable-pins  peripheral-pin-select  soldering  flux  cleaning  sampling  filter  noise  computers  interference  power-supply  switch-mode-power-supply  efficiency  lm78xx 

4 to tylko 1/8 bardziej marnotrawstwa niż 3.
Nick Johnson

@NickJohnson Zgadzam się, ale sugeruje tylko dodanie „Wasteful” również w (3) :)
Eugene Sh.

Nie sądzę, abyś w pełni wyjaśnił swoje założenia dotyczące błędów komunikacyjnych. Czy zakładasz, że komunikacja jest „idealna”, tj. Bezbłędna, czy „dostatecznie idealna”, że wszystkie błędy są wykrywane i identyfikowane przez sprzęt komunikacyjny (np. Komunikator używa parzystości, a są to tylko błędy bitowe)?
żarówka

Beceiver może łączyć się w środku bajtu i może na przykład interpretować bit 8 jako bit 4. Oznaczenie 9-bitowe jest zatem zawodne.
Timothy Baldwin,

@gbulmer Oryginalnym założeniem jest to, że kanał jest doskonały, a problem może powstać tylko z powodu początkowej missynchronizacji. Przy tych założeniach „niezawodność”, o której mówiłem, dotyczy wyłącznie ponownej synchronizacji. Na powyższej liście wszystkie te techniki gwarantują 100% sukcesu, z wyjątkiem pierwszej. Ale prawdopodobnie schemat sprawdzania błędów i kadrowanie nie powinny być rozdzielone w ten sposób.
Eugene Sh.

Odpowiedzi:


15

Jak (lub chciałbyś) zaprojektować protokół systemowy?

Z mojego doświadczenia wynika, że ​​wszyscy spędzają dużo więcej czasu na debugowaniu systemów komunikacyjnych, niż się kiedykolwiek spodziewali. Dlatego zdecydowanie sugeruję, aby za każdym razem, gdy trzeba dokonać wyboru protokołu komunikacyjnego, wybieramy dowolną opcję, która ułatwia debugowanie systemu, jeśli to w ogóle możliwe.

Zachęcam do zabawy przy projektowaniu kilku niestandardowych protokołów - jest to zabawne i bardzo edukacyjne. Zachęcam również do zapoznania się z wcześniej istniejącymi protokołami. Gdybym musiał przesyłać dane z jednego miejsca do drugiego, bardzo starałbym się użyć jakiegoś wcześniej istniejącego protokołu, który ktoś inny spędził już dużo czasu na debugowaniu.

Bardzo prawdopodobne jest, że napisanie od podstaw własnego protokołu komunikacyjnego rozwiąże wiele podobnych problemów, które napotykają wszyscy, pisząc nowy protokół.

Istnieje kilkanaście protokołów systemów wbudowanych wymienionych w protokołach Good RS232 opartych na komunikacji wbudowanej w komputer - który z nich jest najbliższy twoim wymaganiom?

Nawet jeśli pewne okoliczności uniemożliwiały dokładne użycie wcześniej istniejącego protokołu, bardziej prawdopodobne jest, że zacznę działać szybciej, zaczynając od protokołu, który prawie odpowiada wymaganiom, a następnie dostosowując go.

złe wieści

Jak już powiedziałem wcześniej :

Niestety żaden protokół komunikacyjny nie ma wszystkich tych przyjemnych funkcji:

  • przezroczystość: komunikacja danych jest transparentna i „8-bitowa czystość” - (a) każdy możliwy plik danych może być przesłany, (b) sekwencje bajtów w pliku zawsze traktowane jako dane i nigdy błędnie interpretowane jako coś innego, oraz (c ) miejsce docelowe otrzymuje cały plik danych bez błędów, bez żadnych dodatków ani usunięć.
  • prosta kopia: tworzenie pakietów jest najłatwiejsze, jeśli po prostu ślepo skopiujemy dane ze źródła do pola danych pakietu bez zmian.
  • unikalny start: symbol początku pakietu jest łatwy do rozpoznania, ponieważ jest znanym stałym bajtem, który nigdy nie występuje nigdzie indziej w nagłówkach, CRC nagłówka, ładunku danych lub CRC danych.
  • 8-bit: używa tylko 8-bitowych bajtów.

Byłbym zaskoczony i zachwycony, gdyby istniał sposób, aby protokół komunikacyjny posiadał wszystkie te funkcje.

dobre wieści

Jakie są inne możliwe techniki / rozwiązania mające na celu rozwiązanie problemu?

Często sprawia to, że debugowanie jest o wiele łatwiejsze, jeśli człowiek w terminalu tekstowym może zastąpić dowolne z komunikujących się urządzeń. Wymaga to zaprojektowania protokołu tak, aby był względnie niezależny od czasu (nie ma limitu czasu podczas stosunkowo długich przerw między naciśnięciami klawiszy wpisywanymi przez człowieka). Ponadto takie protokoły są ograniczone do rodzajów bajtów, które są łatwe do wpisania przez człowieka, a następnie do odczytania na ekranie.

Niektóre protokoły pozwalają na wysyłanie wiadomości w trybie „tekstowym” lub „binarnym” (i wymagają, aby wszystkie możliwe wiadomości binarne miały jakąś „równoważną” wiadomość tekstową, co oznacza to samo). Może to znacznie ułatwić debugowanie.

Wydaje się, że niektórzy uważają, że ograniczenie protokołu do używania tylko znaków drukowalnych jest „marnotrawstwem”, ale oszczędność czasu debugowania często sprawia, że ​​warto.

Jak już wspomniano, jeśli zezwolisz, aby pole danych zawierało dowolny dowolny bajt, w tym bajty początku i końca nagłówka, kiedy odbiornik jest włączany po raz pierwszy, prawdopodobne jest, że odbiornik źle synchronizuje coś, co wygląda jak bajt początku nagłówka (SOH) w polu danych w środku jednego pakietu. Zwykle odbiorca otrzyma niedopasowaną sumę kontrolną na końcu tego pseudopakietu (który zwykle znajduje się w połowie drugiego rzeczywistego pakietu). Bardzo kuszące jest po prostu odrzucić cały pseudo-komunikat (w tym pierwszą połowę drugiego pakietu) przed szukaniem następnej SOH - w rezultacie odbiornik może pozostać niezsynchronizowany dla wielu wiadomości.

Jak zauważył alex.forencich, znacznie lepszym rozwiązaniem jest odrzucanie bajtów przez odbiornik na początku bufora aż do następnego SOH. Umożliwia to odbiornikowi (po ewentualnej pracy przez kilka bajtów SOH w tym pakiecie danych) natychmiastową synchronizację na drugim pakiecie.

Czy możesz wskazać wady na powyższej liście, które można łatwo obejść, usuwając je w ten sposób?

Jak zauważył Nicholas Clark, nadziewanie bajtami spójnego narzutu (COBS) ma stały narzut, który działa dobrze z ramkami o stałym rozmiarze.

Jedną z często pomijanych technik jest dedykowany bajt znacznika końca ramki. Gdy odbiornik jest włączony w środku transmisji, dedykowany bajt znacznika końca ramki pomaga odbiornikowi szybciej synchronizować.

Gdy odbiornik jest włączony w środku pakietu, a pole danych pakietu zawiera bajty, które wydają się być początkiem pakietu (początek pseudo-pakietu), nadajnik może wstawić serię bajtów znacznika końca ramki po tym pakiecie, aby takie pseudo-bajty początku pakietu w polu danych nie zakłócały natychmiastowej synchronizacji i prawidłowego dekodowania następnego pakietu - nawet jeśli masz pecha i sumę kontrolną tego pseudopakietu wydaje się poprawny.

Powodzenia.


Ta odpowiedź jest warta ponownego rozważenia wcześniej zaakceptowanej odpowiedzi (przepraszam, @DaveTweed), a linkowany artykuł jest z pewnością obowiązkowym tematem. Dziękujemy za poświęcenie czasu i napisanie go.
Eugene Sh.

1
miło, że zwróciłeś uwagę na COBS, więc nie muszę pisać odpowiedzi :-)
Nils Pipenbrinck,

11

Programy wypychania bajtów sprawdziły się dla mnie przez lata. Są ładne, ponieważ można je łatwo zaimplementować w oprogramowaniu lub w sprzęcie, do wysyłania pakietów danych można użyć standardowego kabla USB-U-UART i gwarantuje się uzyskanie dobrej jakości ramkowania bez martwienia się o przekroczenia limitu czasu, zamiana na gorąco lub coś podobnego.

Opowiadałbym się za metodą wypychania bajtów w połączeniu z bajtem długości (moduł długości modulo 256) i CRC na poziomie pakietu, a następnie używam UART z bitem parzystości. Bajt długości zapewnia wykrywanie po bajcie, co dobrze działa z bitem parzystości (ponieważ większość UART upuści wszystkie bajty, które nie są parzyste). Następnie CRC na poziomie pakietu zapewnia dodatkowe bezpieczeństwo.

Jeśli chodzi o nakładanie się bajtów, czy spojrzałeś na protokół COBS? To genialny sposób na wypychanie bajtów ze stałym narzutem 1 bajtu na każde 254 przesyłane (plus twoja ramka, CRC, LEN itp.).

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing


Jest to doskonały sposób, aby w najgorszym przypadku uniknąć upychania bajtów eksplodujących do 2x danych. Użyłem podobnych, ale bardziej specyficznych schematów aplikacji, ale wspaniale jest widzieć to opisane w standardowy sposób. Mam zamiar używać COBS od teraz ...
wjl

1
Dziękuję również za wskazanie COBS - bardzo zgrabnego małego algorytmu.
Nick Johnson

6

Twoja opcja nr 1, SOH plus suma kontrolna, JEST niezawodna i odzyskuje na następnej nieuszkodzonej ramce.

Zakładam, że albo znasz już długość wiadomości, albo długość jest zakodowana w bajtach bezpośrednio po SOH. Bajty kontrolne pojawiają się na końcu wiadomości. Potrzebujesz również bufora po stronie odbiorczej dla danych, który jest co najmniej tak długi, jak Twoja najdłuższa wiadomość.

Za każdym razem, gdy widzisz bajt SOH na początku bufora, jest to potencjalnie początek komunikatu. Przeszukujesz bufor, aby obliczyć wartość kontrolną tego komunikatu i sprawdzić, czy pasuje on do bajtów kontrolnych w buforze. Jeśli tak, to koniec; w przeciwnym razie odrzucisz dane z bufora, aż dojdziesz do następnego bajtu SOH.

Zauważ, że jeśli komunikat faktycznie zawiera błędy danych, algorytm go odrzuci - ale prawdopodobnie i tak zamierzałeś to zrobić. Jeśli Twój algorytm sprawdzania zawiera korekcję błędów przesyłania dalej, możesz sprawdzić każde potencjalne wyrównanie komunikatu pod kątem możliwych do naprawienia błędów.

Jeśli komunikaty mają ustaloną długość, możesz zrezygnować z bajtu SOH - po prostu przetestuj KAŻDĄ możliwą pozycję początkową pod kątem prawidłowej wartości kontrolnej.

Możesz także zrezygnować z algorytmu sprawdzania i zachować tylko bajt SOH, ale to sprawia, że ​​algorytm jest mniej deterministyczny. Chodzi o to, że w przypadku prawidłowego wyrównywania wiadomości SOH zawsze będzie pojawiać się na początku wiadomości. Jeśli masz niepoprawne wyrównanie, prawdopodobnie następny bajt w strumieniu danych nie będzie innym SOH (zależy od tego, jak często SOH pojawia się w danych komunikatu). Na tej podstawie możesz wybrać prawidłowe bajty SOH. (Zasadniczo tak działa kadrowanie w synchronicznych usługach telekomunikacyjnych, takich jak T1 i E1.)


Wydaje mi się, że niezawodność jest nieco probabilistyczna? W zależności od siły sprawdzanie błędów / kodu korekcji my może napotkać ramek, które wydają się poprawne w losowej / niepożądanego strumienia bajtów.
Eugene Sh.

Jasne, to możliwe. Ale w praktyce stosunkowo łatwo jest wybrać wystarczająco silny algorytm kontrolny.
Dave Tweed

Jeśli masz niezerową częstotliwość błędów danych, zawsze istnieje niezerowa szansa, że ​​i tak zaakceptujesz nieprawidłowy komunikat.
Nick Johnson

@NickJohnson Zakładając, że kanał jest idealnie czysty, nadal będą (teoretycznie) niedopasowania przy takim podejściu. Oczywiście ich prawdopodobieństwo może być znikome.
Eugene Sh.

1
Wiem, że już o tym wiesz i wspomniałeś o tym mimochodem, ale wersja, w której nie buforujesz całej wiadomości lub po prostu leniwie podchodzisz do dekodowania, jest mniej niezawodna. Jeśli ponownie zsynchronizujesz w następnym bajcie SOH po niedopasowanej sumie kontrolnej, zamiast następnego bajtu SOH po „fałszywym” SOH, masz bardzo dużą szansę na odrzucenie uruchomienia prawdziwej wiadomości i pozostanie niezsynchronizowanym dla wielu wiadomości lub najgorszy przypadek na zawsze.
hobbs

5

Jedną z niewymienionych opcji, ale szeroko stosowaną (szczególnie w Internecie) jest kodowanie ASCII / tekst (w rzeczywistości większość współczesnych implementacji zakłada UTF-8). Z mojego doświadczenia wynika, że ​​faceci od sprzętu nie lubią tego robić, ale ludzie oprogramowania wolą to od prawie wszystkiego innego (dotyczy to głównie tradycji uniksowej polegającej na tworzeniu wszystkich tekstów).

Zaletą kodowania tekstu jest to, że do kadrowania można używać znaków niedrukowalnych. Na przykład najprostszym byłoby użycie czegoś w rodzaju 0x00wskazania początku i 0xffkońca ramki.

Widziałem dwa główne sposoby kodowania danych jako tekstu:

  1. Gdy poprosimy o to faceta od montażu / montażu, najprawdopodobniej zostanie to zaimplementowane jako kodowanie szesnastkowe. Jest to po prostu konwersja bajtów na ich wartości szesnastkowe w ASCII. Koszty ogólne są duże. Zasadniczo prześlesz dwa bajty na każdy rzeczywisty bajt danych.

  2. Gdy poprosi o to programistę, prawdopodobnie zostanie on zaimplementowany jako kodowanie base64. Jest to de facto kodowanie Internetu. Używany do wszystkiego, od załączników MIME do e-maila po kodowanie danych URL. Koszty ogólne wynoszą dokładnie 33%. Znacznie lepsze niż proste kodowanie szesnastkowe.

Alternatywnie możesz całkowicie zrezygnować z danych binarnych i przesłać tekst. W tym przypadku najczęściej stosowaną techniką jest rozdzielanie danych znakiem nowej linii (po prostu "\n"lub "\r\n"). NMEA (GPS), polecenia Modem AT i czujniki Adventech ADAM to tylko niektóre z najczęstszych tego przykładów.

Wszystkie te tekstowe protokoły / ramki mają następujące zalety i wady:

Zawodowiec:

  • Łatwy do debugowania
  • Łatwy do wdrożenia w języku skryptowym
  • Sprzęt można po prostu przetestować za pomocą Hyperterminal / minicom
  • Łatwy do wdrożenia na sprzęcie (chyba że jest to naprawdę mała mikro jak PIC)
  • Może być ramą o stałym rozmiarze lub o różnym rozmiarze.
  • Przewidywalny czas odtwarzania kadrowania i szybkiej synchronizacji (odzyskuje pod koniec bieżącej ramki)

Kon:

  • Bardzo duży narzut w porównaniu do czystej transmisji binarnej (z drugiej strony tekstowe operacje we / wy mogą również „kompresować” liczby, takie jak wysyłanie jednego bajtu "0"(0x30) zamiast czterech bajtów 0x00000000)
  • Nie tak czysty do wdrożenia na bardzo małych mikrofonach, takich jak PIC (chyba że twoja biblioteka zawiera sprintf()funkcję)

Osobiście dla mnie zalety przewyższają wady. Łatwość samego debugowania liczy się jako 5 punktów (tak, że sam pojedynczy punkt już przewyższa obie wady).


Są też nie tak dokładnie przemyślane rozwiązania, często pochodzące od osób zajmujących się oprogramowaniem: wysyłanie zakodowanych danych bez myślenia o kadrowaniu.

W przeszłości musiałem współpracować ze sprzętem, który wysyłał nieprzetworzony XML. XML był całym kadrem. Na szczęście <xml></xml>znaczniki dość łatwo określają granice ramek . Największą wadą dla mnie jest to, że używa więcej niż jednego bajtu do kadrowania. Również samo kadrowanie może nie zostać naprawione, ponieważ znacznik może zawierać atrybuty: <tag foo="bar"></tag>więc musisz znaleźć bufor w najgorszym przypadku, aby znaleźć początek ramki.

Ostatnio widziałem, jak ludzie zaczynają wysyłać JSON z portów szeregowych. W przypadku JSON kadrowanie jest w najlepszym razie zgadywaniem. Masz tylko "{"(lub "[") znak do wykrycia ramki, ale są one również zawarte w danych. Tak więc w końcu potrzebujesz parsera zejścia rekurencyjnego (lub przynajmniej licznika nawiasów klamrowych), aby ustalić ramkę. Przynajmniej trywialne jest sprawdzenie, czy bieżąca ramka kończy się przedwcześnie: "}{"czy "]["w JSON są nielegalne, a tym samym wskazują, że stara ramka się zakończyła i zaczęła się nowa ramka.


W przypadku kodowania tekstu istnieje również base85 , który ma tylko 25% narzutu zamiast 33%.
Dave Tweed

Uznałbym to za podzbiór / wariant czwartej metody.
Eugene Sh.

@EugeneSh .: Technicznie jest to podzbiór bajtowania. Z drugiej strony, ponieważ uważasz, że jest to podzbiór znakowania bitów, możesz zrozumieć, dlaczego ta dwuznaczność czyni z niej kategorię samą w sobie. Ponadto nie można rozpatrywać większości implementacji kodowania tekstu jako podzbioru znakowania bitów, ponieważ bity znakowania nigdy nie są używane (na przykład zwykle używam <i >jako ograniczników i uważam, że poczta e-mail używa znaków nowej linii. Uwaga: tak, poczta e-mail ma poprawnie sformatowaną ramkę które mogą być przesyłane przez RS232.
Mój

4

To, co opisujesz jako „X-bitowe oznaczenie”, można uogólnić na inne kody, które mają właściwość rozszerzania danych o stały ułamek, pozostawiając niektóre słowa kodowe do wykorzystania jako ograniczniki. Często kody te zapewniają również inne korzyści; Płyty CD używają modulacji od ośmiu do czternastu , co gwarantuje maksymalną długość przebiegu równą 0 bitów między nimi 1. Inne przykłady obejmują kody blokowe korekcji błędów przesyłania dalej , które wykorzystują dodatkowe bity również do kodowania informacji o wykrywaniu błędów i korekcji.

Kolejnym systemem, o którym nie wspomniałeś, jest wykorzystywanie informacji poza pasmem, takich jak linia wyboru żetonów, do rozgraniczenia transakcji lub pakietów.


Kody korekcji błędów są nieco poza pytaniem. W każdym razie należy je dodać do każdego z tych programów. „Informacje poza pasmem”, o których mówisz, są takie same jak „sprzętowa kontrola przepływu”.
Eugene Sh.

@EugeneSh. - W rzeczywistości użycie bitów kontroli błędów do ramkowania jest całkowicie poprawne, chociaż obliczeniowo drogie po stronie odbiorczej. Po prostu wykonujesz obliczenia błędów dla każdego możliwego wyrównania danych, a ten, który się powiedzie, jest poprawnym wyrównaniem na nieuszkodzonej ramce. Oczywiście, jeśli rama jest uszkodzona, nie znajdziesz jej.
Dave Tweed

@DaveTweed Cóż, właściwie to miałem na myśli pierwszą technikę. A może źle cię rozumiem?
Eugene Sh.

Nie, nie jesteś nieporozumieniem; o tym mówiłem. Jednak twój „con” jest błędny - JEST niezawodny i może być solidny w odniesieniu do faktycznych błędów transmisji.
Dave Tweed

@DaveTweed Co z czasem odzyskiwania? Czy masz jakieś przykłady tego, jak można uczynić go solidnym?
Eugene Sh.

3

Inną opcją jest tak zwane kodowanie linii . Kodowanie liniowe nadaje sygnałowi pewne właściwości elektryczne, które ułatwiają transmisję (zrównoważone napięcie DC i gwarancja maksymalnej długości przebiegu) i obsługują znaki sterujące dla ramkowania i synchronizacji zegara. Kody linii są stosowane we wszystkich nowoczesnych szybkich protokołach szeregowych - 10M, 100M, 1G i 10G Ethernet, serial ATA, FireWire, USB 3, PCIe itp. Typowe kody linii to 8b / 10b , 64b / 66b i 128b / 130b. Istnieją również prostsze kody linii, które nie dostarczają informacji o kadrowaniu, tylko równowaga DC i synchronizacja zegara. Przykładami są Machester i NRZ. Prawdopodobnie chcesz użyć 8b / 10b, jeśli chcesz szybko zsynchronizować; inne kody linii nie są zaprojektowane tak, aby się zsynchronizować w pośpiechu. Korzystanie z kodu linii, takiego jak powyższy, będzie wymagało użycia niestandardowego sprzętu do transmisji i odbioru.

Jeśli chodzi o opcję 5, standardowy szeregowy RS232 powinien obsługiwać wysyłanie i odbieranie przerw, gdy linia jest bezczynna przez kilka bajtów. Może to jednak nie być obsługiwane we wszystkich systemach.

Zasadniczo najprostszą i najbardziej niezawodną metodą ramkowania jest opcja 1 w połączeniu z polem długości i prostą procedurą CRC lub sumą kontrolną. Procedura dekodowania jest prosta: odrzuć bajty, aż pojawi się bajt początkowy, przeczytaj pole długości, poczekaj na całą ramkę, sprawdź sumę kontrolną, zachowaj, jeśli jest dobra. Jeśli suma kontrolna jest zła, zacznij usuwać bajty z bufora, aż pojawi się bajt początkowy i powtórz. Głównym problemem związanym z tą techniką jest znalezienie początku bajtu ramki, który tak naprawdę nie jest początkiem bajtu ramki. Aby złagodzić ten problem, jedną z technik jest ucieczka bajtów o tej samej wartości co początek bajtu ramki innym znakiem kontrolnym, a następnie zmiana bajtu zmiany znaczenia, aby miał inną wartość. W takim przypadku będziesz musiał zrobić to samo z nowym bajtem kontrolnym.


To jest to samo, co odpowiedź Nicka Johnsona.
Dave Tweed
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.