Tecniche di delimitazione / sincronizzazione del protocollo seriale


24

Poiché al giorno d'oggi la comunicazione seriale asincrona è ampiamente diffusa tra i dispositivi elettronici, credo che molti di noi abbiano di tanto in tanto posto una domanda del genere. Considerare un dispositivo elettronico De un computer PCcollegato con una linea seriale (RS-232 o simile) e necessario per scambiare informazioni in modo continuo . Cioè PCsta inviando un frame di comando ciascuno X mse Dsta rispondendo con report di stato / frame di telemetria ciascuno Y ms(il report può essere inviato come risposta alle richieste o in modo indipendente - non importa davvero qui). I frame di comunicazione possono contenere qualsiasi dato binario arbitrario . Supponendo che i frame di comunicazione siano pacchetti a lunghezza fissa.

Il problema:

Poiché il protocollo è continuo, il lato ricevente potrebbe perdere la sincronizzazione o semplicemente "unirsi" nel mezzo di un frame inviato in corso, quindi non saprà dove si trova l'inizio del frame (SOF). A dato che i dati hanno un significato diverso in base alla sua posizione rispetto al SOF, i dati ricevuti verranno danneggiati, potenzialmente per sempre.

La soluzione richiesta

Schema affidabile di delimitazione / sincronizzazione per rilevare il SOF con tempi di recupero brevi (cioè non dovrebbe richiedere più di, diciamo 1 frame per risincronizzare).

Le tecniche esistenti di cui sono a conoscenza (e che ne uso alcune) di:

1) Header / checksum - SOF come valore byte predefinito. Checksum alla fine del frame.

  • Pro: semplice.
  • Contro: non affidabile. Tempo di recupero sconosciuto.

2) Riempimento byte:

  • Pro: recupero affidabile e veloce, può essere utilizzato con qualsiasi hardware
  • Contro: non adatto per comunicazioni basate su frame di dimensioni fisse

3) Marking 9th bit - antepone ogni byte con bit aggiuntivo, mentre SOF contrassegnato con 1e i byte di dati sono contrassegnati con 0:

  • Pro: recupero affidabile e veloce
  • Contro: richiede supporto hardware. Non supportato direttamente dalla maggior parte PCdell'hardware e del software.

4) Contrassegno 8 ° bit - tipo di emulazione di quanto sopra, mentre si utilizza l'8 ° bit anziché il 9 °, che lascia solo 7 bit per ogni parola di dati.

  • Pro: recupero affidabile e veloce, può essere utilizzato con qualsiasi hardware.
  • Contro: richiede uno schema di codifica / decodifica dalla / alla rappresentazione convenzionale a 8 bit alla / dalla rappresentazione a 7 bit. Abbastanza dispendioso.

5) Basato sul timeout : presuppone che il SOF sia il primo byte proveniente dopo un determinato tempo di inattività.

  • Pro: nessun sovraccarico di dati, semplice.
  • Contro: non così affidabile. Non funzionerà bene con sistemi di temporizzazione scadenti come, ad esempio, PC Windows. Potenziale sovraccarico del throughput.

Domanda: quali sono le altre tecniche / soluzioni possibili per risolvere il problema? Puoi indicare i contro nell'elenco sopra che possono essere facilmente risolti, rimuovendoli così? Come progettate (o vorreste) il vostro protocollo di sistema?

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 è solo 1/8 più dispendioso di 3.
Nick Johnson,

@NickJohnson Accetto, ma mi sta solo suggerendo di aggiungere anche la cosa "Wasteful" in (3) :)
Eugene Sh.

Non credo che tu abbia spiegato completamente le tue ipotesi sugli errori di comunicazione. Supponete che la comunicazione sia "perfetta", cioè senza errori, o "sufficientemente perfetta" che tutti gli errori vengano rilevati e identificati dall'hardware di comunicazione (ad esempio, le comunicazioni utilizzano la parità e sono solo errori di bit)?
bagliore

Beceiver può unirsi nel mezzo di un byte e può interpretare il bit 8 come ad esempio il bit 4. La marcatura a 9 bit non è pertanto affidabile.
Timothy Baldwin,

@gbulmer Il presupposto originale è che il canale è perfetto e il problema può sorgere solo a causa della mancata sincronizzazione iniziale. In base a questi presupposti, l '"affidabilità" a cui mi riferivo riguarda solo la risincronizzazione. Nell'elenco sopra tutte queste tecniche garantiscono il 100% di successo tranne la prima. Ma probabilmente lo schema di controllo degli errori e l'inquadratura non dovrebbero essere separati in questo modo.
Eugene Sh.

Risposte:


15

Come progettate (o vorreste) il vostro protocollo di sistema?

Nella mia esperienza, ognuno dedica molto più tempo al debug dei sistemi di comunicazione di quanto si aspettasse. E quindi suggerisco vivamente che ogni volta che è necessario effettuare una scelta per un protocollo di comunicazione, si sceglie qualsiasi opzione che renda il sistema più facile da eseguire il debug, se possibile.

Ti incoraggio a giocare con la progettazione di alcuni protocolli personalizzati: è divertente e molto istruttivo. Tuttavia, ti incoraggio anche a guardare i protocolli preesistenti. Se avessi bisogno di comunicare i dati da un luogo a un altro, farei del mio meglio per utilizzare un protocollo preesistente che qualcun altro ha già dedicato molto tempo al debug.

Scrivere il proprio protocollo di comunicazione da zero è molto probabile che si scontri con molti degli stessi problemi comuni che tutti hanno quando scrivono un nuovo protocollo.

Esistono una dozzina di protocolli di sistema integrati elencati in Good Protocolli basati su RS232 per la comunicazione da embedded a computer : qual è il più vicino ai tuoi requisiti?

Anche se alcune circostanze hanno reso impossibile utilizzare esattamente qualsiasi protocollo preesistente, ho maggiori probabilità di far funzionare qualcosa più rapidamente iniziando con un protocollo che si adatta quasi ai requisiti e quindi modificandolo.

cattive notizie

Come ho detto prima :

Sfortunatamente, è impossibile per qualsiasi protocollo di comunicazione avere tutte queste caratteristiche interessanti:

  • trasparenza: la comunicazione dei dati è trasparente e "8 bit clean" - (a) ogni possibile file di dati può essere trasmesso, (b) sequenze di byte nel file sempre gestite come dati e mai interpretate erroneamente come qualcos'altro, e (c ) la destinazione riceve l'intero file di dati senza errori, senza aggiunte o eliminazioni.
  • copia semplice: la creazione di pacchetti è più semplice se copiamo semplicemente i dati alla cieca dal campo di origine del pacchetto senza modifiche.
  • inizio univoco: il simbolo di inizio del pacchetto è facile da riconoscere, poiché è un byte costante noto che non si verifica mai in nessun'altra parte nelle intestazioni, nell'intestazione CRC, nel payload dei dati o nel CRC dei dati.
  • 8 bit: utilizza solo byte a 8 bit.

Sarei sorpreso e felice se ci fosse un modo per un protocollo di comunicazione di avere tutte queste caratteristiche.

buone notizie

Quali sono le altre tecniche / soluzioni possibili per risolvere il problema?

Spesso rende il debug molto, molto più semplice se un essere umano in un terminale di testo può sostituire uno qualsiasi dei dispositivi di comunicazione. Ciò richiede che il protocollo sia progettato per essere relativamente indipendente dal tempo (non scade durante le pause relativamente lunghe tra i tasti digitati da un essere umano). Inoltre, tali protocolli sono limitati al tipo di byte che un essere umano può facilmente scrivere e quindi leggere sullo schermo.

Alcuni protocolli consentono l'invio di messaggi in modalità "testo" o "binaria" (e richiedono che tutti i possibili messaggi binari abbiano un messaggio di testo "equivalente" che significa la stessa cosa). Questo può aiutare a rendere il debug molto più semplice.

Alcune persone sembrano pensare che limitare un protocollo per usare solo i caratteri stampabili sia "dispendioso", ma i risparmi nel tempo di debug spesso ne valgono la pena.

Come già accennato, se si consente al campo di dati di contenere qualsiasi byte arbitrario, inclusi i byte di inizio dell'intestazione e di fine dell'intestazione, quando un ricevitore viene acceso per la prima volta, è probabile che il ricevitore si sincronizzi erroneamente su quello che sembra un byte di inizio dell'intestazione (SOH) nel campo dati nel mezzo di un pacchetto. Di solito il destinatario riceve un checksum non corrispondente alla fine di quel pseudo-pacchetto (che è in genere a metà strada attraverso un secondo pacchetto reale). È molto allettante scartare semplicemente l'intero pseudo-messaggio (compresa la prima metà di quel secondo pacchetto) prima di cercare il SOH successivo - con la conseguenza che il destinatario potrebbe rimanere fuori sincrono per molti messaggi.

Come ha sottolineato alex.forencich, un approccio molto migliore è che il destinatario scarti byte all'inizio del buffer fino al SOH successivo. Ciò consente al destinatario (dopo aver eventualmente elaborato diversi byte SOH in quel pacchetto di dati) di sincronizzarsi immediatamente sul secondo pacchetto.

Puoi indicare i contro nell'elenco sopra che possono essere facilmente risolti, rimuovendoli così?

Come ha sottolineato Nicholas Clark, il byte stuffing overhead (COBS) ha un overhead fisso che funziona bene con frame di dimensioni fisse.

Una tecnica che viene spesso trascurata è un byte marker di fine frame dedicato. Quando il ricevitore si accende nel mezzo di una trasmissione, un byte marker di fine frame dedicato aiuta il ricevitore a sincronizzarsi più velocemente.

Quando un ricevitore viene acceso nel mezzo di un pacchetto e il campo dati di un pacchetto contiene byte che sembrano essere un inizio di pacchetto (l'inizio di uno pseudo-pacchetto), il trasmettitore può inserire una serie di byte marker di fine frame dopo quel pacchetto in modo che tali byte pseudo-inizio-pacchetto nel campo dati non interferiscano con la sincronizzazione immediata e la decodifica corretta del pacchetto successivo , anche quando si è estremamente sfortunati e il checksum di quello pseudo-pacchetto appare corretto.

In bocca al lupo.


Questa risposta vale la pena riconsiderare la risposta precedentemente accettata (scusate, @DaveTweed) e l'articolo collegato è sicuramente una spiegazione sull'argomento. Grazie per aver dedicato del tempo e scriverlo.
Eugene Sh.

1
bello che tu indichi COBS, quindi non devo scrivere una risposta :-)
Nils Pipenbrinck

11

Gli schemi di byte-stuffing hanno funzionato alla grande per me nel corso degli anni. Sono belli perché sono facili da implementare nel software o nell'hardware, puoi utilizzare un cavo standard da USB a UART per inviare pacchetti di dati e hai la garanzia di ottenere un frame di buona qualità senza doversi preoccupare timeout, hot-swap o qualsiasi altra cosa del genere.

Vorrei sostenere un metodo di riempimento dei byte combinato con un byte di lunghezza (lunghezza del pacchetto modulo 256) e un CRC a livello di pacchetto, quindi utilizzare UART con un bit di parità. Il byte di lunghezza garantisce il rilevamento di byte rilasciati, che funziona bene con il bit di parità (poiché la maggior parte degli UART eliminerà tutti i byte che non superano la parità). Quindi il CRC a livello di pacchetto offre maggiore sicurezza.

Per quanto riguarda l'overhead del byte-stuffing, hai esaminato il protocollo COBS? È un modo geniale per eseguire il stuffing di byte con un overhead fisso di 1 byte per ogni 254 trasmessi (oltre a frame, CRC, LEN, ecc.).

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


Questo è un modo eccellente per evitare l'esplosione del byte-stuffing nel doppio dei dati nel peggiore dei casi. Ho usato schemi simili ma più specifici dell'applicazione, ma è bello vederlo descritto in modo standard. Da ora in poi
userò COBS

1
Grazie anche a me per aver segnalato COBS, un piccolo algoritmo molto pulito.
Nick Johnson,

6

La tua opzione n. 1, SOH più checksum, è affidabile e ripristina sul prossimo frame non danneggiato.

Suppongo che tu sappia già la lunghezza di un messaggio o che la lunghezza sia codificata nei byte immediatamente dopo SOH. I byte di controllo vengono visualizzati alla fine del messaggio. È inoltre necessario un buffer sul lato di ricezione per i dati lunghi almeno quanto il messaggio più lungo.

Ogni volta che vedi un byte SOH in testa al buffer, è potenzialmente l'inizio di un messaggio. Si esegue la scansione attraverso il buffer per calcolare il valore di controllo per quel messaggio e vedere se corrisponde ai byte di controllo nel buffer. In tal caso, il gioco è fatto; in caso contrario, si eliminano i dati dal buffer fino a quando non si arriva al byte SOH successivo.

Nota che se un messaggio ha effettivamente degli errori nei dati, questo algoritmo lo eliminerà, ma probabilmente lo faresti comunque. Se l'algoritmo di controllo include la correzione in avanti dell'errore, è possibile controllare ogni potenziale allineamento del messaggio per errori correggibili.

Se i messaggi hanno una lunghezza fissa, è possibile rinunciare del tutto al byte SOH: basta testare OGNI possibile posizione iniziale per un valore di controllo valido.

È inoltre possibile rinunciare all'algoritmo di controllo e mantenere solo il byte SOH, ma ciò rende l'algoritmo meno deterministico. L'idea è che per allineamenti di messaggi validi, il SOH apparirà sempre all'inizio di un messaggio. Se si dispone di un allineamento errato, è improbabile che il byte successivo nel flusso di dati sia un altro SOH (dipende dalla frequenza con cui SOH appare nei dati del messaggio). È possibile selezionare i byte SOH validi solo su questa base. (Questo è fondamentalmente il modo in cui funziona l'inquadramento su servizi di telecomunicazioni sincroni come T1 ed E1.)


Immagino che l'affidabilità sia alquanto probabilistica? A seconda della forza del codice di controllo degli errori / correzione si può incontrare cornici che sembrano corrette in un flusso di byte casuali / arbitrario.
Eugene Sh.

Certo, è possibile. Ma in pratica, è relativamente facile scegliere un algoritmo di controllo che è abbastanza forte.
Dave Tweed

Se hai una percentuale di errori di dati diversa da zero, c'è sempre una possibilità diversa da zero che accetti comunque un messaggio non valido.
Nick Johnson,

@NickJohnson Supponendo un canale perfettamente pulito, ci saranno ancora (teoricamente) discrepanze con questo approccio. Naturalmente la loro probabilità può essere trascurabile.
Eugene Sh.

1
So che lo sai già, e lo hai già menzionato di passaggio, ma la versione in cui non memorizzi un intero messaggio o sei semplicemente pigro su come decodifichi, è meno affidabile. Se si risincronizza al successivo byte SOH dopo il checksum non corrispondente, invece del successivo byte SOH dopo il "falso" SOH, si hanno ottime possibilità di scartare l' inizio del messaggio reale e rimanere fuori sincrono per molti messaggi o, nel caso peggiore, per sempre.
Hobbs,

5

Un'opzione non menzionata ma ampiamente utilizzata (soprattutto su Internet) è la codifica ASCII / testo (in realtà, la maggior parte delle implementazioni moderne presuppone UTF-8). Nella mia esperienza, i ragazzi dell'hardware odiano farlo, ma le persone del software tendono a preferire questo quasi a qualsiasi altra cosa (principalmente per la tradizione Unix di fare tutto basato sul testo).

Il vantaggio della codifica del testo è che è possibile utilizzare caratteri non stampabili per l'inquadramento. Ad esempio, il più semplice sarebbe usare qualcosa di simile 0x00per indicare l'inizio del frame e 0xffper la fine del frame.

Ho visto due modi principali in cui i dati sono codificati come testo:

  1. Quando viene richiesto a un utente hardware / assembly di eseguire questa operazione, molto probabilmente verrà implementato come codifica esadecimale. Questo sta semplicemente convertendo i byte nei loro valori esadecimali in ASCII. Il sovraccarico è grande. Fondamentalmente, trasmetterai due byte per ogni byte di dati effettivo.

  2. Quando viene chiesto a un ragazzo del software di farlo, probabilmente verrà implementato come codifica base64. Questa è la codifica di fatto di Internet. Utilizzato per qualsiasi cosa, dagli allegati e-mail MIME alla codifica dei dati URL. Il sovraccarico è esattamente del 33%. Molto meglio della semplice codifica esadecimale.

In alternativa, puoi abbandonare completamente i dati binari e trasmettere il testo. In questo caso la tecnica più comune è quella di delimitare i dati con newline (solo "\n"o "\r\n"). I comandi NMEA (GPS), Modem AT e i sensori ADAM Adventech ne sono alcuni degli esempi più comuni.

Tutti questi protocolli / framing testuali hanno i seguenti pro e contro:

Pro:

  • Facile da eseguire il debug
  • Facile da implementare in un linguaggio di scripting
  • L'hardware può essere semplicemente testato utilizzando Hyperterminal / minicom
  • Facile da implementare sull'hardware (a meno che non sia un micro davvero piccolo come un PIC)
  • Può essere una cornice di dimensioni fisse o di dimensioni variabili.
  • Inquadratura prevedibile e tempi di ripristino della sincronizzazione rapidi (ripristina alla fine del frame corrente)

con:

  • Sovraccarico molto elevato rispetto alla pura trasmissione binaria (anche in questo caso, l'I / O di testo può anche "comprimere" numeri come l'invio di un byte "0" (0x30) anziché quattro byte 0x00000000)
  • Non così pulito da implementare su micro molto piccoli come il PIC (a meno che la tua libreria non includa un sprintf() funzione)

Personalmente per me i professionisti superano pesantemente i contro. La facilità di debug da sola conta come 5 punti (quindi quel singolo punto supera già entrambi i contro).


Poi ci sono soluzioni non così accuratamente pensate che spesso vengono dai ragazzi del software: inviare dati codificati senza pensare all'inquadramento.

Ho dovuto interfacciarmi con l'hardware che ha inviato XML grezzo in passato. L'XML era tutto l'inquadramento che c'era. Fortunatamente, è abbastanza facile capire i limiti del frame dai <xml></xml>tag. Il grande svantaggio per me è che utilizza più di un byte per l'inquadramento. Inoltre, l'inquadramento stesso potrebbe non essere risolto poiché il tag può contenere attributi: <tag foo="bar"></tag>quindi dovresti bufferizzare nel caso peggiore per trovare l'inizio del frame.

Recentemente ho visto persone iniziare a inviare JSON da porte seriali. Con JSON l'inquadratura è nella migliore delle ipotesi un'ipotesi. Hai solo il carattere "{"(o "[") per rilevare il frame ma sono anche contenuti nei dati. Quindi hai bisogno di un parser di discesa ricorsivo (o almeno un contatore di parentesi graffe) per capire il frame. Almeno è banale sapere se il frame corrente termina prematuramente: "}{"o "]["è illegale in JSON e quindi indica che il vecchio frame è terminato e che è stato avviato un nuovo frame.


Per le codifiche di testo, c'è anche base85 , che ha solo il 25% di overhead invece del 33%.
Dave Tweed

Lo considererei un sottoinsieme / variazione del 4o metodo.
Eugene Sh.

@EugeneSh .: Tecnicamente è un sottoinsieme di bytestuffing. Poi di nuovo dal momento che lo consideri un sottoinsieme di marcatori di bit, puoi capire perché questa ambiguità lo rende una categoria a sé stante. Inoltre, non è possibile considerare la maggior parte delle implementazioni della codifica del testo come un sottoinsieme della marcatura dei bit poiché i bit di marcatura non vengono mai utilizzati (ad esempio, io di solito uso <e >come delimitatori e credo che la posta elettronica utilizzi le nuove righe. Nota: sì, la posta elettronica è un formato correttamente inquadrato che può essere trasmesso tramite RS232. Un mio amico gestiva un server di distribuzione della posta per la sua casa usando RS232)
slebetman

4

Quello che descrivi come "marcatura dell'Xth bit" può essere generalizzato in altri codici che hanno la proprietà di espandere i dati con una frazione costante, lasciando alcune parole in codice libere da usare come delimitatori. Spesso questi codici offrono anche altri vantaggi; I CD usano una modulazione da otto a quattordici , che garantisce una lunghezza massima di 0 bit tra ogni 1. Altri esempi includono codici di blocco Forward Error Correction , che usano bit aggiuntivi per codificare anche le informazioni di rilevamento e correzione degli errori.

Un altro sistema che non hai menzionato è quello di utilizzare informazioni fuori banda, come una linea di selezione chip, per delimitare transazioni o pacchetti.


I codici di correzione degli errori sono un po 'da parte della domanda. Dovrebbero comunque essere aggiunti a uno di questi schemi. Le "informazioni fuori banda" a cui ti riferisci sono le stesse del "controllo del flusso hardware" immagino?
Eugene Sh.

@EugeneSh. - In realtà, l'uso dei bit di controllo degli errori per l'inquadramento è perfettamente valido, sebbene computazionalmente costoso dal lato della ricezione. Basta fare il calcolo dell'errore per ogni possibile allineamento dei dati e quello che ha successo è un allineamento valido su un frame non corrotto. Naturalmente, se il frame è danneggiato, non lo troverai.
Dave Tweed

@DaveTweed Bene, è praticamente quello che intendevo con la prima tecnica. O ti sto fraintendendo?
Eugene Sh.

No, non stai fraintendendo; ecco di cosa stavo parlando. Tuttavia, il tuo "truffatore" è sbagliato: è affidabile e può essere reso robusto anche rispetto agli errori di trasmissione effettivi.
Dave Tweed

@DaveTweed E i tempi di recupero? Hai qualche esempio di come può essere reso robusto?
Eugene Sh.

3

Un'altra opzione è quella che è nota come codifica di riga . La codifica di linea fornisce al segnale determinate caratteristiche elettriche che facilitano la trasmissione (bilanciamento CC e garanzie di massima durata) e supportano i caratteri di controllo per l'inquadramento e la sincronizzazione dell'orologio. I codici di linea sono utilizzati in tutti i protocolli seriali moderni ad alta velocità: 10M, 100M, 1G e 10G Ethernet, seriale ATA, FireWire, USB 3, PCIe, ecc. I codici di linea comuni sono 8b / 10b , 64b / 66b e 128b / 130b. Esistono anche codici di linea più semplici che non forniscono informazioni sull'inquadramento, solo bilanciamento DC e sincronizzazione dell'orologio. Esempi di questi sono Machester e NRZ. Probabilmente vuoi usare 8b / 10b se vuoi sincronizzare rapidamente; gli altri codici di linea non sono progettati per la sincronizzazione in fretta. L'uso di un codice di linea come quello che offre quanto sopra richiederà l'uso di hardware personalizzato per la trasmissione e la ricezione.

Per quanto riguarda l'opzione 5, si suppone che il seriale standard RS232 supporti l'invio e la ricezione di interruzioni in cui la linea è inattiva per un paio di volte byte. Tuttavia, questo potrebbe non essere supportato su tutti i sistemi.

Generalmente il metodo di inquadratura più semplice e affidabile è l'opzione 1, in combinazione con un campo di lunghezza e una semplice routine CRC o checksum. La routine di decodifica è semplice: scarta i byte fino a quando non ottieni un byte iniziale, leggi il campo della lunghezza, attendi l'intero frame, controlla il checksum, mantieni se buono. Se il checksum è errato, iniziare a scartare i byte dal buffer fino a quando non si ottiene un byte iniziale e ripetere. Il problema principale con questa tecnica è trovare un inizio di frame byte che in realtà non è un inizio di frame byte. Per alleviare questo problema, una tecnica consiste nell'evitare i byte con lo stesso valore dell'inizio del byte del frame con un altro carattere di controllo e quindi modificare il byte con escape in modo che abbia un valore diverso. In questo caso, dovrai anche fare la stessa cosa con il nuovo byte di controllo.


Questa è la stessa della risposta di Nick Johnson.
Dave Tweed
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.