Newsgroup: it.hobby.elettronica.digitale
Titolo: Quale protocollo flessibile per una rete di nodi half-duplex

Sono partato da comp.arch.embedded 
(
groups.google.com/forum/?fromgroups#!topic/comp.arch.embedded/vLKKGvdH6oI
), 
ma mi sembrava utile discuterne anche qui.
 
Stavo mettendo su una "classica" rete RS485 a 2 fili (anche se il 
livello fisico poco importa) con 1 master ed N slave.  Durante 
l'implementazione del protocollo su uno slave basato su un piccolo e 
lento micro a 8 bit, mi sono chiesto come dimensionare il buffer di 
ricezione.  Potevo farlo come al solito "a senso", ma ho fatto l'errore 
di adottare un approccio un po' più scientifico, ed ora non so più che 
pesci prendere :-)
 
Se il micretto gestisce frame di lunghezza max 10 byte, posso definire 
un buffer da 15 e sono a posto... e no!  Su un half-duplex tutti gli 
slave ricevono tutti i frame, anche quelli di altri (evviva la privacy). 
  E se sulla rete ci sono nodi più potenti (il master è sicuramente 
"potente") che possono gestire frame da 100-200 byte?  Devo allocare 
100-200 byte sul micretto?  E dove li trovo?  Devo limitare la lunghezza 
massima dei frame sulla rete a quella gestibile dai micretti?
 
Non solo, immaginate che:
   1. all'istante 0ms il master mandi un frame di 30 byte allo slave 1
   2. all'istante 10ms, slave 1 risponde con 10 byte
   3. subito dopo aver ricevuto la risposta, il master
      trasmette 10 byte allo slave 2
Se il micretto entra in una routine che dura 100ms all'istante 0ms, 
quando esce deve aver memorizzato 50 byte, quando la lunghezza del più 
grande frame è solo 30 byte!!
 
In altre parole, sembra che la dimensione del buffer su un qualsiasi 
nodo dipenda anche dalla dimensione massima del frame più lungo (anche 
diretto ad altri slave), dai tempi di risposta degli slave veloci e da 
quanto veloce è il master a trasmettere un successivo frame... povero 
micretto!
 
Si può risolvere la cosa elegantemente e permettere la connivenza di 
micretti e microni complicando leggermente l'ISR di ricezione sugli 
slave e definendo il protocollo in modo che dai primi byte già si 
capisca a chi è indirizzato il frame.  Se è per il micretto, allora il 
frame verrà salvato nel buffer (che potrà essere dimensionato sulla 
massima lunghezza dei frame gestiti da *quello* slave e non dagli 
altri), altrimenti verrà scartato fino all'ultimo byte.
 
E come capisco la fine di un frame?  E' sufficiente delimitare i frame 
con un byte di SYNC: per esempio, un frame inizia e finisce con un 
carattere di SYNC e i caratteri di SYNC ed ESC presenti nel payload si 
trasformano in sequenze di escape ESC ESC_SYNC e ESC ESC_ESC (tipo SLIP).
 
Che si fa se i frame sono protetti da CRC?  Come faccio nell'ISR a 
guardare l'indirizzo destinazione se non controllo prima la CRC?  Poco 
male, lo guardo lo stesso.
Se il frame è per un microne e l'indirizzo destinazione è corrotto e 
coincidente con un micretto, potrei correre il rischio di memorizzare un 
frame grande nel buffer piccolo del micretto, ma all'overflow del buffer 
lo andrei a scartare (tanto non era sicuramente per il micretto).
Se, invece, il frame è per il micretto ma l'indirizzo destinazione è 
corrotto, il frame non verrà memorizzato/processato e il master non 
vedrà risposta, con conseguente ritrasmissione.
 
Quindi semplice implementazione: un buffer/array buf[] dove memorizzo 
tutti i frame per me (lo vedo dal primo byte dopo il SYNC) partendo da 
buf[0].  Ad ogni SYNC e buffer non vuoto (per gestire il doppio SYNC), 
disattivo la ricezione, processo il frame (con tutto comodo), trasmetto 
la risposta, resetto il puntatore a buf[0] e riattivo la ricezione. 
Semplice e pulito.
 
Però c'è un altro inghippo... nella rete ho dei frame broadcast che, per 
ovvie ragioni, non hanno risposta.  Il master potrebbe inviare un bel 
SET CLOCK a tutti gli slave e poi iniziare a fare un polling.  Se il 
master non fa una pausa dopo un frame di broadcast, al micretto arrivano 
ben 2 frame prima che possa processarli e allora l'implementazione di 
prima non va bene.
 
Ok, risolvo facilmente dicendo al master di prendersi un caffè dopo un 
frame di broadcast (quanto durerebbe questo caffè? dovrebbe essere 
dimensionato sullo slave più lento)... ma perchè dargli questo 
privilegio?  Lo pago per lavorare, non per prendersi il caffè.
 
Allora inizio a pensare che l'implementazione della ricezione può essere 
fatta su una FIFO: ogni byte che appartiene ad un frame per me o 
broadcast viene pushato nella FIFO.  La routine di gestione dei 
pacchetti farà pop, un byte alla volta... ma come farà a distinguere la 
fine di un pacchetto (la decodifica dei caratteri di SYNC è stata già 
fatta al volo nell'ISR, perchè devo leggere l'indirizzo destinazione), 
visto che potrebbe esserci un secondo?
 
Allora penso che posso aggiungere un secondo livello di framing, uno 
nell'altro: uno a livello più basso per l'ISR e l'altro a livello più 
alto per la funzione di gestione della rete... ma ho la sensazione di 
stare esagerando!
 
Voi vi fate tutti sti problemi?
 
 

 Voi vi fate tutti sti problemi?
 
 
Non esiste una soluzione ottimale per tutte le situazioni.
Nel caso specifico, individua i vincoli che non puoi cambiare e su 
quelli basati per dimensionare il resto.
 
A mio modesto parere, a meno di numeri elevatissimi, in generale 
conviene investire qualche cent in più per non essere strozzati con le 
risorse hardware e implementare un firmware semplice e lineare piuttosto 
che sputare sangue per risparmiare una manciata di byte.
 
Ciao!
Marco
 
 

 Voi vi fate tutti sti problemi?
 
Sinceramente, no, non capisco il problema.
 
Ti dico come faccio di solito io.
 
Sotto ISR metto i caratteri in una fifo lunga al massimo quando il 
massimo pacchetto che voglio gestire.
 
Se la fifo ï¿œ piena, i caratteri successivi li butto via.
 
Poi c'ï¿œ un processo da qualche parte che snocciola i dati dalla fifo e 
controlla per i vari STX, ETX, CRC e indirizzo di destinazione.
 
Se il pacchetto contiene l'indirizzo dello slave lo processo, altrimenti no.
 
Puï¿œ succedere che lo slave perda qualche pacchetto perchï¿œ intasato da 
quello che passa sulla rete, ma come dicevi tu il master ï¿œ piï¿œ furbo e 
puï¿œ effettuare una ritrasmissione se non riceve risposta.
 
Cosa c'ï¿œ che non va in questo approccio?
 
Ciao
 
 
 

 guardare l'indirizzo destinazione se non controllo prima la CRC?
 
Mi sembra che tu voglia dare un respiro estremamente generale a cose che
non hanno bisogno di esserlo. Bisogna differenziare caso per caso in base
al "key driver" specifico della tua applicazione (efficienza, transfer
rate, fault tolerance, ecc); non ha senso inventarsi un protocollo che vada
bene per trasferire due temperature a 1 Hz o dieci video 1080p
multiplexati.
 
Quasi tutti i protocolli semplici che ho visto hanno dei frame composti da
tre parti: un header fisso iniziale, un blocco di dati di dimensione
variabile, e un CRC finale. Quindi basta che tutti i micretti ricevano
l'header, dove c'č scritto tutto quello che gli serve per sapere se gli
interessa e la lunghezza del pacchetto. Se non gli interessa, i byte
successivi del pacchetto saranno ricevuti ma ignorati.
 
-- 
Fletto i muscoli e sono nel vuoto.

 che sputare sangue per risparmiare una manciata di byte.
 
Sì, è chiaro.
Ma alla fine devi pur sempre dimensionare i buffer in modo scientifico, 
cioè in modo che deterministicamente, se non ci sono errori di 
trasmissione, il frame non venga perso.  Non penso che alla NASA (o 
anche alla Volkswagen) si mettano a dimensionare i buffer "a naso".
 

 Cosa c'è che non va in questo approccio?
 
Magari mi sbaglio, ma IMHO non è detto che funzioni!  Attenzione, è il 
classico approccio che avrei usato io, ma poi mi sono messo a pensare...
 
Per quello che hai detto, lo slave S1 che gestisce al massimo pacchetti 
di lunghezza massima di 10 byte, avrà un buffer di 10 byte, giusto?  Ma 
in una rete half-duplex tutti vedono tutto, quindi quello slave S1 
vedrà/riceverà anche il frame da 100 byte diretto allo slave S2.
 
Tu dici che non è un problema, quando la FIFO è piena gli altri byte 
vengono scartati.  Ma intato ti sei riempito la FIFO con byte inutili e, 
magari, quando arriva il frame per te il processo che snocciola i dati 
della FIFO non è stato ancora chiamato (immagina che S1 abbia processi 
"lenti", mentre S2 è velocissimo a rispondere) e così perdi il tuo frame.
 
Tu dici che ogni tanto può capitare, tanto ci sono le ritrasmissioni... 
però, se la rete è fatta in un certo modo, questi eventi capitano 
deterministicamente.
 
Immagina il master M, lo slave S1 e lo slave S2.  Rete a 9600bps 
(8,n,1).  S1 gestisce pacchetti massimi di 10 byte, quindi ha un buffer 
di 10 byte.
   - All'istante 0 S1 entra in un processo bloccante P che dura 100ms
   - Subito dopo, M invia 30 byte (31ms) a S2
   - All'istante 35ms, S2 risponde con 10 byte (10ms)
   - All'istante 35+10=45ms, M riceve tutta la risposta da S2
   - All'istante 50ms, M invia 10 byte (10ms) a S1
   - All'istante 50+10=60ms, S2 è ancora nel processo P e la FIFO
     è piena e il "suo" frame è stato perso
 
Forse questa sequenza "sfigata" di eventi non capita praticamente mai, 
perchè gli slave sono tutti uguali (sia come micro che come firmware). 
Però non è sempre così.
 
Poi il master potrebbe prendere il respiro prima di iniziare una nuova 
transazione sulla rete, ma per massimizzare il thoughput sarebbe meglio 
che non lo facesse.
 

 successivi del pacchetto saranno ricevuti ma ignorati.
 
Ma anche in questo caso, a livello di progetto, il protocollo *deve* 
specificare altro per poter funzionare.  E cioè deve dire come risolve 
il problema del controllo di flusso.
 
Non è pensabile che il master invii in continuazione pacchetti ad uno 
stesso slave alla massima velocità (la larghezza di banda del canale 
fisico della rete), altrimenti lo slave, prima o poi, inizierà a perdere 
dati per FIFO full.
 
Una possibilità è quella di prevedere sempre una risposta ad ogni 
pacchetto di "andata".  In pratica la risposta, oltre a darmi 
eventualmente dati utili, mi darebbe l'ok ad inviare il successivo 
pacchetto.  Appunto il controllo di flusso.
 
Ma così escludo la possibilità dei pacchetti broadcast che non hanno 
risposta.  E se voglio i broadcast?  Allora non posso fidarmi della 
risposta per avere l'ok per la successiva trasmissione.  E allora come fare?
 
Soluzione semplice e non efficiente: tempo d'attesa tra un pacchetto 
broadcast e il successivo.  Ma come quantificare questo tempo d'attesa? 
  Dovrebbe dipendere dal tempo massimo che il più lento slave può 
impiegare ad elaborare un pacchetto broadcast e a liberare la FIFO, 
almeno in parte.
 
Soluzione più raffinata che tentavo di ideare: lo slave S dovrebbe avere 
un buffer delle dimensioni di N broadcast consecutivi trasmessi senza 
interruzione (anche N deve essere specificato nel protocollo) + 1 
pacchetto massimo per il singolo slave.
Gli N broadcast andrebbero in tutte le FIFO di tutti gli slave, mentre 
il pacchetto "normale" andrebbe solo nella FIFO dello slave indirizzato 
(sempre insieme agli N broadcast).
 
Ragionavo su come il processo che si snocciola la FIFO potesse 
individuare gli N+1 pacchetti originali se le delimitazioni sono state 
eliminate durante la ricezione.
Ma anche qui si potrebbero trovare altre soluzioni: aggiungo altre 
delimitazioni a livello più alto, oppure evito di tagliare le 
delimitazioni del livello fisico (anche se serve decodificarle per 
guardare all'header e all'indirizzo), o altro ancora di più complicato.
 
 
Sì lo so, è un periodo in cui non so cos'altro fare :-)
 

 errore di sintassi o qualcosa di simile).
 
 
Sicuramente. Mi riferivo al caso di pacchetti binari eventualmente senza 
delimitatori.
 
 
Ciao!
Marco
 

     è piena e il "suo" frame è stato perso
 
Per processo bloccante intendi che il µC non può nemmeno rispondere ad un
interrupt dalla UART?
Non mi sono mai trovato in questa situazione perchè se prevedo la RS485
l'hardware deve sempre essere dimensionato per supportarla pienamente.
 
In qualche caso dove ci potevano essere delle criticità è stato aggiunto un
AtTiny2313 o Tiny4313 solo per gestire la comunicazione seriale e ridurre i
compiti alla CPU principale.
 
 
--
ciao
  Stefano

 vedo il problema.
 
Tu scrivevi:
 
 > Questo dipende dalle risorse che hai a disposizione. Puoi anche
 > tentare una soluzione ibrida. Quando hai terminato di ricevere un
 > messaggio fai solo il controllo del crc (se c'è) e del destinatario.
 > Se non è indirizzato a te, sovrascrivi il buffer.
 
Stai cioè proponendo di memorizzare nella FIFO l'intero messaggio e solo 
*dopo* aver ricevuto *tutti* i byte, controllare CRC e destinatario e 
quindi scartare quello che non è per me.
 

 interrupt dalla UART?
 
No, è chiaro che l'interrupt di ricezione è sempre abilitato e quindi 
tutti i byte vengono salvati.  Con processo bloccante volevo dire che 
non era possibile elaborare il pacchetto ricevuto (quindi liberare la 
FIFO, nel caso di pacchetto destinato ad altri) prima di uscire dalla 
funzione.
 
Sempre supponendo di non fare alcun controllo sulla destinazione nell'ISR.
 

 quindi scartare quello che non è per me.
 
 
In risposta al tuo esempio in cui comparivano solo messaggi di max 30 
byte. Se passano anche messaggi più lunghi può banalmente valere il 
filtro sulla lunghezza di cui sopra.
 
Marco
 
 


Non potresti fare un controllo sul numero di byte ricevuto oppure, 
meglio ancora, un buffer ciclico nel quale eventuali messaggi non 
destinati al micro piccolo, vengono automaticamente scartati dalla 
funzione di scrittura in buffer?
ciao
Angelo
 


 
Il bello era proprio la coesistenza pacifica tra nodi ad alta capacità 
di calcolo e ciofeche.

Il 01/06/2013 00:20, pozz ha scritto:
 > Certamente, però potrei trovare un protocollo che massimizzi il
 > throughput a parità di capacità della rete, minimizzando le risorse dei
 > singoli nodi.
 >
 > In altre parole, se ho una RS485 a 9600bps, l'ideale sarebbe poter
 > inviare dati a quella velocità.  Se, però, il protocollo, per come è
 > definito, deve prevedere delle pause o dei feedback/ack, il throughput
 > diminuisce.
Mi pare una questione di lana caprina: il thoughput di dati ha senso
in funzione dell' applicazione . Se parli di frame che devono
essere trasmessi in real-time in modo sincrono, posso anche capire,
se parli di una rete di sensori, magari di temperature o altri
parametri che magari variano a tempi biblici, non ha senso.
 
 > Un po' come per Ethernet.  Ho un canale a 100Mbps (per esempio) e cerco
 > di fare in modo di massimizzare il throughput, indipendemente se
 > l'applicazione è un VoIP, uno streaming, un web browsing o chissà
 > cos'altro.
Affatto. Devo solo garantire che la banda a disposizione sia
sufficiente per la mia applicazione. E' accettabilissimo avere
una banda sottoutilizzata se economicamente sostenibile.
 
 >
 > Ma anche in questo caso, a livello di progetto, il protocollo *deve*
 > specificare altro per poter funzionare.  E cioè deve dire come risolve
 > il problema del controllo di flusso.
Se il protocollo e' master-slave, il controllo del flusso e' garantito
dalla risposta dello slave indirizzato. Eventuali anomalie sono gestite
da timeout sulla risposta (e si, non si puo' fare altrimenti :-)
 >
 > Non è pensabile che il master invii in continuazione pacchetti ad uno
 > stesso slave alla massima velocità (la larghezza di banda del canale
 > fisico della rete), altrimenti lo slave, prima o poi, inizierà a perdere
 > dati per FIFO full.
Ovviamente una query deve tenere conto della tipologia di slave
usati, inoltre se e' un master, non avrà un solo slave da pollare e
anche se ne avesse solo uno, ha senso fare polling alla frequenza
effettiva di produzione dati dello slave :-)
 
 >
 > Una possibilità è quella di prevedere sempre una risposta ad ogni
 > pacchetto di "andata".  In pratica la risposta, oltre a darmi
 > eventualmente dati utili, mi darebbe l'ok ad inviare il successivo
 > pacchetto.  Appunto il controllo di flusso.
:-)
 >
 > Ma così escludo la possibilità dei pacchetti broadcast che non hanno
 > risposta.  E se voglio i broadcast?  Allora non posso fidarmi della
 > risposta per avere l'ok per la successiva trasmissione.  E allora come
 > fare?
un broadcast su una rete half-duplex si fa normalmente prevedendo che
il pacchetto broadcast non sia confermato (tipo UDP) da nessuno.
Se prevedi che le operazioni di broadcast necessitino di tempo per
concludersi, allora inserici un tempo di inibizione.
E comunque lo slave eventualmente interrogato in 'anticipo' puo'
semplicemente ignorare il frame ricevuto ed eventualmente ritornare
un messaggio di busy :-)
 
 >
 > Sì lo so, è un periodo in cui non so cos'altro fare :-)
 >
Perche' diavolo complicarsi la vita ? vedi su.
Se ti servono messaggi broadcast *confermati* , siamo fuori strada
(non e' che non si possa fara, ma non non ne vale la pena)
SE ti servono, cambia media e invece del 485 usa il CAN, che si trova
anche in micretti da 0.8€
 
aa
 

 di calcolo e ciofeche.
 
Ho recuperato il PDF delle specifiche del protocollo.  E' interessante, 
anche se non spiega precisamente come fa un micretto a gestire 
pacchettoni (probabilmente come abbiamo già detto numerose volte, è 
implicito che guardi l'header e ignori i pacchetti che non sono per lui).
 
Parla di un byte di sincronismo con cui inizia ogni pacchetto, ma non ho 
capito come fa per evitare che capiti nel payload.  Forse con il 
preambolo, ma anche quello può capitare all'interno dei dati.
 
COmunque ha qualche spunto interessante.
 

Il 02/06/2013 16:13, pozz ha scritto:
 > Ho recuperato il PDF delle specifiche del protocollo.  E' interessante,
 > anche se non spiega precisamente come fa un micretto a gestire
 > pacchettoni (probabilmente come abbiamo già detto numerose volte, è
 > implicito che guardi l'header e ignori i pacchetti che non sono per lui).
 
Direi di si. Tra l'altro non sarebbe neppure indispensabile che il 
micretto riceva/gestisca tutti i pacchetti, ma che, a seconda del 
contesto, stia in ascolto solo in momenti sensati in base allo stato del 
dialogo con il corrispondente (tanto quello che si dicono gli altri nel 
frattempo potrebbe non interessare)....
 
 > Parla di un byte di sincronismo con cui inizia ogni pacchetto, ma non ho
 > capito come fa per evitare che capiti nel payload.  Forse con il
 > preambolo, ma anche quello può capitare all'interno dei dati.
 
...e questo porta al problema del sync, che viene ridotto con sistemi 
probabilistici (preamboli, toggle bit/bytes, timeout ecc) ma non da mai 
la certezza del 100% di agganciarsi al primo colpo... a meno di usare 
bit stuffing come nell'X25, operazione indolore in una trasmissione bit 
oriented, molto più incasinata in una trasmissione byte oriented.
 

 che non lo facesse.
 
Il primo passo da fare ï¿œ non avere processi bloccanti, per esempio 
usando un kernel, anche cooperativo. Quando un processo ï¿œ in attesa di 
I/O deve essere switchato di contesto. Questo ï¿œ importante piï¿œ che fare 
le cose sotto IRQ (che ï¿œ peggio, perchï¿œ occupi CPU inutilmente e 
potresti perdere altri IRQ).
 
Una volta che hai ridotto la latenza media la maggior parte dei problemi 
sono risolti. Per quelle poche volte che lo slave non risponderï¿œ, ï¿œ 
comunque prevista la ritrasmissione da parte del master, per cui non ci 
sono problemi.
 
 
Ciao
 
 

 usando un kernel, anche cooperativo.
 
 
Su un micro che fa fatica ad allocare 50 byte in RAM? :)
 
Marco
 
 


Certo, perchï¿œ no, immagino che farï¿œ poche cose e lo spazio in RAM 
scalerï¿œ di conseguenza.
 

 sono problemi.
 
E' vero, se ho funzioni brevissime la probabilitï¿œ di incappare nella mia 
sequenza sfigata si abbassa... ma non ï¿œ nulla.  E' proprio cosï¿œ che si 
definiscono seriamente i protocolli di rete, andando avanti a probabilitï¿œ?
 
Una cosa ï¿œ prevedere le ritrasmissioni per far fronte ad errori di 
comunicazione che hanno tipicamente un comportamento aleatorio (disturbi 
elettromagnetici, ...) ed una cosa ï¿œ utilizzare le ritrasmissioni per 
risolvere problemi di protocollo che possono essere previsti a tavolino 
e magari risolti con un'altra strategia.
 
Piï¿œ ci penso e piï¿œ mi convinco che per risolvere a priori in modo 
deterministico la mia sequenza sfigata, bisogna evitare che uno slave 
memorizzi i pacchetti destinati ad altri (e per questo ï¿œ necessario fare 
una minima decodifica del pacchetto nell'ISR di ricezione) oppure 
salomonicamente impedire al master di iniziare una nuova transazione 
(domanda/risposta) sulla rete prima che sia passato un buon timeout 
(500ms?) dall'ultima risposta.
 

(500ms?) dall'ultima risposta.
 
Nelle applicazioni con la RS485 usiamo ambedue le cose che hai detto, solo il
timeout � pi� breve (300 mS), ma � un problema da poco, nei log che monitorano
la comunicazione la ritrasmissioni sono praticamente sempre zero, e ci sono
anche tratte abbastanza lunghe (+ di 500m).
 
Abbiamo optoisolato, ma questi sono altri problemi, il protocollo non c'entra.
 
 
--
ciao
  Stefano

 (500ms?) dall'ultima risposta.
 
Secondo il mio modesto parere stai cercano di risolvere un problema nel 
livello sbagliato. Determinare la lunghezza del buffer a priori ï¿œ 
impossibile e la soluzione di fare controlli nella ISR va nella 
direzione sbagliata (aumento del jitter sulla latenza).
 
Ciao!
 
 
 

 Tutta l'elaborazione la fai poi off-line in un altro processo.
 
Forse ho capito il tuo concetto: se il processo che gestisce i pacchetti 
viene richiamato nel caso peggiore entro T dall'ultima chiamata (ï¿œ 
quello che tu forse chiami latenza), ï¿œ sufficiente garantire un buffer 
che tenga almeno
 
   T / (10 / B)
 
dove B ï¿œ il baudrate (bps) e 10 sono i bit per simbolo (start, 8 bit di 
dati e stop).
 
Se riesco a fare dei processi molto snelli che mi permettono di avere un 
valore di T massimo di 10ms a 9600bps, dovrei avere un buffer di soli 10 
byte, che salgono perï¿œ a piï¿œ di 100 a 115.2kbps.
 
IMHO questo approccio puï¿œ essere implementato se riesci a fare uno 
studio serio della latenza e del jitter, ma nella pratica per me risulta 
*molto* complicata.
Un modo per misurare il ritardo tra due chiamate successive del processo 
che gestisce la rete ï¿œ quello di visualizzarlo su un oscilloscopio 
tramite pin.  Abilito la persistenza infinita e dopo un po' di tempo 
vado a vedere il ritardo massimo.
Il problema ï¿œ che questo ritardo dipende spesso dalle condizioni d'uso. 
  Per esempio, se c'ï¿œ un display e tasti e lo uso, in quel momento la 
latenza potrebbe aumentare.
 
Probabilmente il metodo piï¿œ preciso per valutare T non ï¿œ misurarlo, ma 
calcolarlo... auguri!  E' un po' come calcolare a priori la dimensione 
minima dello stack... mai riuscito a fare una cosa del genere.
 
Quindi il tuo metodo della FIFO sufficientemente grande che memorizza 
*tutti* i pacchetti in circolazione ï¿œ fattibile se puoi allocare 
centinaia di byte senza problemi e se hai processi molto brevi.  In 
questo caso, puoi evitare di far di conto ed essere quasi sicuro di non 
avere problemi di ritrasmissioni.
 
L'altro metodo (quello di scartare nell'ISR i pacchetti destinati ad 
altri) ti evita queste misure/calcoli complicati e ti dï¿œ la certezza di 
non avere problemi.  La dimensione della FIFO ï¿œ sufficiente che sia 
esattamente uguale a quella del pacchetto massimo da noi gestito.  Poi 
la latenza del processo che gestisce i pacchetti potrebbe essere anche 
elevata (naturalmente elevato sarï¿œ il tempo di risposta).
 

 elevata (naturalmente elevato sarà il tempo di risposta).
No, per scartare un pacchetto non e' necessario mememorizzarlo tutto,
anzi! Un protocollo e' una macchina a stati, per cui banalmente quando
riconosci che il pacchetto non e' per te', gli N byte a seguire sarano
scatati ( se e' previsto un header con lunghezza).
Se il protocollo prevede un STX univoco, bastera' tornare allo stato di 
attesa STX, se no si scartano i byte del pacchetto.
Eventualmente va gestito un timeout di frame per essere sicuri di
non rimanere appesi in caso di perdita di caratteri.
AA.
 
 
 
 

 non rimanere appesi in caso di perdita di caratteri.
 
Sì, è esattamente quello che volevo dire io quando scrivevo "scartare
nell'ISR i pacchetti destinati ad altri". Cioè nell'ISR ho una
semplice macchina
a stati che mi dice se sono in attesa di un nuovo pacchetto, se sto
ricevendo
un pacchetto per me (quindi da memorizzare) oppure sto ricevendo un
pacchetto per altri (quindi da scartare).
 
Francesco puntava sul fatto che una implementazione semplice che
memorizza senza filtri tutti i byte di tutti pacchetti (per me e per
altri)
in una FIFO è più che sufficiente.

 *molto* complicata.
 
Uno studio del genere, come dici, può essere fatto solo in modo 
probabilistico; questo perché non usi un kernel.
 
Se già ne usassi uno anche solo cooperativo, la latenza media si abbassa 
di almeno un ordine di grandezza. Se poi usi un kernel preemptive hai 
addirittura garanzie di real time, ovvero sei in grado di dire con 
precisione e in modo predeterminato (niente prove o statistiche), con 
quanta latenza il tuo processo di elaborazione dati sarà attivato. Con 
un kernel preemptive, in processori tipici embedded come quelli che usi 
tu, la latenza è dell'ordine dei microsecondi, quindi ci staresti 
ampiamente.
 

 micro... qualche risorsa da leggere?
 
 
http://webhome.csc.uvic.ca/~mcheng/466/spring.2012/handouts/Technical%20References/Patterns%20For%20Time-Triggered%20Embedded%20Systems.pdf
 
 
hth
 
 
-- 
Mai mettersi a discutere con un idiota:
- prima ti porta al suo livello e poi ti batte con l'esperienza;
- chi ascolta potrebbe non capire la differenza.