In che modo Arduino gestisce l'overflow del buffer seriale? Elimina i dati in entrata più recenti o i più vecchi? Quanti byte può contenere il buffer?
In che modo Arduino gestisce l'overflow del buffer seriale? Elimina i dati in entrata più recenti o i più vecchi? Quanti byte può contenere il buffer?
Risposte:
Per le porte seriali hardware è possibile vedere in HardwareSerial.cpp che la dimensione del buffer varia in base alla quantità di RAM disponibile sul particolare AVR:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Per una porta seriale del software in SoftwareSerial.h, la dimensione del buffer del ricevitore _SS_MAX_RX_BUFF
è definita come 64 byte. In entrambi i casi smette di tentare di inserire i dati ricevuti nella coda quando è pieno, quindi è possibile ottenere un mix di dati vecchi e nuovi a seconda di come si stanno recuperando i dati dalla coda.
Idealmente, sarebbe meglio assicurarsi che il buffer venga sempre svuotato in modo rapido per evitare il riempimento del buffer. Forse dai un'occhiata ai timer e all'implementazione di una semplice macchina a stati se il tuo problema è legato ad altri codici che bloccano il ciclo principale.
Dalla sorgente di HardwareSerial puoi vedere che se un byte in arrivo trova pieno il buffer dell'anello, viene scartato:
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
Ho l'impressione che se trasmetto dati ad Arduino e non ho un "puller" attivo di dati sul lato Arduino, se arrivano più dati di quanti ne possano stare nel buffer, verranno scartati. Puoi confermarlo?
Sì, verrà scartato. Non esiste alcun controllo del flusso di software o hardware, a meno che non si implementi il proprio.
Tuttavia, con un buffer a 64 byte e ricevendo dati a (diciamo) 9600 baud, si ottiene un byte ogni 1,04 ms, e quindi ci vogliono 66,6 ms per riempire il buffer. Su un processore a 16 MHz dovresti essere in grado di controllare il buffer abbastanza spesso da non riempire. Tutto quello che devi fare è spostare i dati dal buffer HardwareSerial al tuo, se non vuoi elaborarli in questo momento.
Dal #if (RAMEND < 1000)
controllo si può vedere che i processori con oltre 1000 byte di RAM ottengono il buffer da 64 byte, quelli che avranno meno RAM ottengono il buffer da 16 byte.
I dati scritti vengono inseriti in un buffer della stessa dimensione (16 o 64 byte). Nel caso di invio se il buffer riempie il codice "blocchi" in attesa di un interrupt per inviare il byte successivo dalla porta seriale.
Se gli interrupt sono disattivati, ciò non accadrà mai, quindi non si eseguono stampe seriali all'interno di una routine di servizio di interrupt.
1/960 = 0.001042 s
- ovvero un byte ogni 1,04 ms.