Cosa causa gli errori UART?


8

Vorrei sapere perché si verificano errori UART e quando si dovrebbero verificare tali errori. C'è un post qui che chiede come gestire singoli errori, come sovraccarico, parità, ecc ... Sono chiaro sul perché si verifica il sovraccarico di dati, perché si verifica l'errore di parità, ma vorrei sapere qual è la causa principale. La mia domanda è più focalizzata sul perché potrebbero verificarsi questi errori (ragioni fisiche) e su quando si dovrebbe fare un errore controllando un fattore per la loro applicazione.

Finora il mio programma sembra funzionare benissimo (senza controllo errori), ma so che il rumore può rovinare le cose. Come posso simulare condizioni che potrebbero causare il fallimento delle porte UART Rx / Tx?

Risposte:


8

Esistono diverse potenziali fonti di rumore in qualsiasi circuito. Alcuni dei più comuni includono:

  • Alimentatori mal regolati;
  • Alimentatori a commutazione;
  • Disaccoppiamento capacitivo insufficiente delle barre di alimentazione vicino all'MCU;
  • Accoppiamento induttivo di fonti elettromagnetiche vicine (compresi 50 o 60Hz dall'alimentazione di rete; anche se il circuito è alimentato a batteria, avvertirà questa interferenza quando è abbastanza vicino a una fonte di alimentazione);
  • Sorgenti RF vicino alla frequenza di risonanza di una traccia sul circuito stampato o una delle sue armoniche;
  • Instradamento di tracce ad alta corrente sul circuito stampato vicino alle linee di segnale;
  • Eccetera.

Inoltre (come menzionato @jippie), l'inclinazione dell'orologio è una causa molto comune di errori in qualsiasi tipo di comunicazione seriale che utilizza una velocità di dati predeterminata. Se si utilizza un cristallo esterno e si interfaccia a un altro sistema che può ragionevolmente essere accurato, è meno probabile che causi problemi. Gli oscillatori interni, tuttavia, possono avere tolleranze di vari ordini di grandezza peggiori dei cristalli e tendono a variare maggiormente negli intervalli di temperatura.

Esistono diversi test di base che possono essere eseguiti su un sistema in esecuzione per determinare l'immunità al rumore di base (e inclinare) dell'interfaccia, tra cui:

  • Congelamento (raffreddare il circuito fino alla classificazione minima dei suoi componenti);
  • Cottura (calore alla massima valutazione);
  • Esposizione all'IME :
    • Posizionare la scheda sulla parte superiore del cavo di alimentazione di un riscaldatore di spazio in esecuzione;
    • Digitare una radio CB nelle immediate vicinanze della scheda;
    • Posiziona la scheda accanto al router wireless;
    • Utilizzare un cavo di collegamento lungo (anziché un cavo seriale correttamente costruito) per la connessione UART.

Ce ne sono molti altri - in realtà, ci sono grandi laboratori di test dedicati alla qualificazione EMC .

In generale, a meno che non sia accettabile un livello minimo di perdita di dati, è sempre prudente includere una sorta di controllo degli errori nel codice delle comunicazioni. Anche un semplice checksum è meglio di niente.


6

Una fonte comune di errori su UART oltre alla qualità del livello del segnale (rumore, tempi di salita / discesa) è l'inclinazione dell'orologio. Se l'orologio del trasmettitore e l'orologio del ricevitore non derivano dalla stessa sorgente (come nella maggior parte dei casi), uno funzionerà più velocemente dell'altro. Quando l'errore di temporizzazione è troppo grande, potresti occasionalmente leggere un bit sbagliato.


Cosa causerebbe l'inclinazione dell'orologio, se il microcontrollore fosse lasciato solo in una scatola nera, nel mezzo di chissà dove?
user791953

1
Orologi locali funzionanti gratuitamente. Ogni oscillatore ha la sua precisione. L'orologio MCU può essere suddiviso in una frequenza utilizzabile per UART, ma a volte è spento da una piccola percentuale. Questo è a sua volta causato dal fatto che il divisore è un numero intero.
jippie,

Per esempio. Orologio MCU = 16MHz, baudrate UART = 9600Bd. Quindi l'UART viene comunemente sincronizzato con 153600Hz. 16000000/153600 non è un numero intero, quindi il baudrate sarà disattivato.
jippie,

Bene, questo darà una piccola percentuale di errore. Immagino di essere stato abbastanza fortunato da non aver riscontrato errori, ma se si tratta di dati critici, i controlli dovrebbero essere eseguiti sempre.
user791953

Baudrate inferiore, clock rate superiore (aumenta la risoluzione di campionamento e l'accuratezza del timing).
jippie,

1

La maggior parte degli errori deriva da tre cause: (1) il segnale generato dal trasmettitore non rappresentava dati validi; (2) il segnale del trasmettitore non è stato ricevuto come generato, o (3) il ricevitore non era pronto a gestire i dati quando sono stati ricevuti. La causa più comune che ho riscontrato per il problema n. 1 è un trasmettitore che viene riconfigurato o spento durante la trasmissione dei dati. Il problema n. 2 può facilmente verificarsi per segnali che viaggiano attraverso il "mondo esterno" a causa di cose come l'interferenza radio (i telefoni cellulari possono essere sorprendentemente cattivi!), Ma generalmente non dovrebbero verificarsi per segnali confinati su una singola scheda. Il problema n. 3 può verificarsi perché troppi byte arrivano più velocemente di quanto possano essere elaborati o perché il ricevitore viene riconfigurato, spento o avviato durante una trasmissione.

In molti casi, è difficile eliminare completamente tutti questi problemi; il proprio obiettivo dovrebbe essere quello di garantire che il "danno" totale da essi causato (probabilità di occorrenza, tempi di danno per occorrenza) sia accettabilmente basso. Ciò può essere fatto più facilmente scegliendo una stima pessimistica dell'affidabilità, e quindi progettando un protocollo in modo che l'impatto sulle prestazioni del sistema anche dei peggiori guasti che fossero coerenti con le proprie stime sarebbe entro limiti accettabili.


0

Gli errori di inquadramento possono essere causati da ciò che menziona @jippie: il ricevitore ha rilevato il bit di inizio e dove si aspetta il bit di arresto i dati vengono invertiti. Ciò può anche essere dovuto alla corruzione dei dati causata da interferenze di linea che incidono sul bit di stop. È sempre necessario verificarlo per ogni byte ricevuto.

Si verificano errori di parità quando viene implementata la parità sul collegamento dati e si verifica un danneggiamento che causa una mancata corrispondenza della parità nei dati ricevuti. È sempre necessario verificarlo per ogni byte ricevuto.

Anche l'interruzione della ricezione è considerata un errore, anche se in realtà indica che i dati in entrata sono scesi allo zero logico per più di 1 byte di dati. Normalmente 1 logico è lo stato "ambientale" tra byte di dati successivi e rimane in questo modo. Penso sia un ritorno ai vecchi sistemi di telegrafia. Non mi preoccuperei di controllare questo a meno che tu non stia usando questa "funzione" per indicare (dire) un comando di reset al ricevitore.

L'errore di sovraccarico si verifica quando viene ricevuto un nuovo byte prima che il byte precedente fosse letto da una CPU. Leggermente diverso quando è coinvolto un FIFO ma equivale alla stessa cosa: i dati ricevuti validi vengono persi a causa della lentezza della CPU. Controllalo sempre prima di leggere un byte e se il byte fa parte di un messaggio (o comando) più lungo, elimina l'intero messaggio / comando e in qualche modo richiedi al trasmettitore di inviare nuovamente l'intero messaggio / comando.

In fase di esecuzione non si tratta in realtà di un errore, ma indica all'UART di invio che il buffer di trasmissione è vuoto, ovvero che richiede un nuovo byte da trasmettere. Non è necessario controllare questo.


Capisco quali sono questi errori e perché si verificano, la mia domanda è più vicina a quando si dovrebbe fornire un controllo degli errori.
user791953

@ user791953 - fatto
Andy aka

A proposito, underrun non è un problema con la maggior parte dei protocolli, ma alcuni protocolli usano una linea inattiva per indicare la fine del pacchetto. In tali casi, un underrun sul lato di trasmissione può indurre il ricevitore a pensare erroneamente che il pacchetto termini prima che si supponga.
supercat

0

Per gestire questi errori, è necessario implementare un protocollo logico di livello superiore. qualcosa di simile a TCP, o controllare lo stack OSI per idee.

fondamentalmente, due parti importanti per cominciare sono i checksum e i timeout. utilizzare un algoritmo per calcolare un valore ridondante che rappresenta, in una forma più piccola, il contenuto di ciascun messaggio. quindi controlla questo nel messaggio ricevuto. se le somme non corrispondono, è possibile che si sia verificato un errore nell'inquadratura, un po 'di rumore, ecc. ecc. e sarà necessario eliminare il messaggio e tentare una sorta di recupero, reinvio, segnale NACK (non confermato), ecc.

inoltre, assicurarsi di implementare i timeout nel protocollo di livello superiore. se si verifica un errore di framing, l'UART potrebbe non ripristinarsi mai e iniziare nuovamente l'elaborazione. potrebbe essere in attesa del bit di stop su un frame che il mittente UART pensa sia già stato inviato, ma è stato danneggiato da rumore, inclinazione dell'orologio, ecc. questo invierà qualsiasi codice di input in un ciclo infinito. assicurati di avere un limite ragionevole per quanto tempo la tua lettura di input dovrebbe attendere fino a quando non decidi di abbandonare questo messaggio, e di nuovo, riprova, NACK, abbandona, ecc.


I timeout devono essere implementati su almeno un lato di qualsiasi protocollo di livello superiore; in molti casi, è meglio implementarli esattamente da un lato. Avere una parte in attesa per sempre di dati che non arrivano mai è solo un problema se invece ci fosse qualcos'altro di utile che avrebbe potuto fare. Se X richiede Y per alcuni dati, X dovrà essere pronto a inviare nuovamente la sua richiesta nel caso in cui Y non li ricevesse. Y, tuttavia, non dovrà preoccuparsi se X ottiene la sua risposta. Se X non lo capisce, X chiederà nuovamente i dati. Il fatto che X non richieda nuovamente i dati significa che Y non ha bisogno di inviarli nuovamente.
supercat

@supercat giusto, questo è un buon modello, ma sto puntando di più verso il basso livello di codifica riga per riga. avrai sempre un ciclo che legge i dati e cerchi di capire se un messaggio completo è pronto, se un messaggio completo non è mai lì, può bloccare il sottosistema di input, indipendentemente dal fatto che non ci sia nient'altro che in attesa di essere fatto. in questo caso, il sottosistema di input deve almeno rendersi conto che si è verificato un errore, scaricare tutti i dati di gabage e ottenere il ripristino per un altro tentativo.
Andyz Smith,

Se ogni pacchetto inizia con una sequenza di byte che è sempre identificabile in qualsiasi contesto e se il destinatario non ha nulla di utile che può fare fino a quando non riceve un pacchetto completo, perché dovrebbe interessarsi se trascorrono alcune ore dopo aver ricevuto un pacchetto parziale? La prossima volta che qualcuno tenta di inviare un pacchetto reale, il destinatario vedrà l'indicatore di inizio pacchetto e abbandonerà il pacchetto parziale.
supercat

@supercat perché allora hai un loop che cerca più cose. sta ancora cercando la fine del pacchetto parziale e sta cercando l'inizio di un pacchetto nuovo, non corrotto. questo rende la logica molto più complessa in termini di codifica pratica, se poi, fare mentre.
Andyz Smith,

Non sono sicuro di quale sia la difficoltà. Se si sta utilizzando un loop di byte di ricezione, si dovrà uscire da esso se si verifica un timeout o viene visualizzato un byte iniziale. Entrambi i comportamenti devono essere gestiti in modo identico, tranne per il fatto che la sequenza di avvio dovrebbe impostare un flag, quindi il codice successivo che lo cercherebbe non si preoccuperà.
supercat
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.