Jak Arduino obsługuje przepełnienie bufora szeregowego? Czy wyrzuca najnowsze przychodzące dane czy najstarsze? Ile bajtów może pomieścić bufor?
Jak Arduino obsługuje przepełnienie bufora szeregowego? Czy wyrzuca najnowsze przychodzące dane czy najstarsze? Ile bajtów może pomieścić bufor?
Odpowiedzi:
W przypadku sprzętowych portów szeregowych można zobaczyć w HardwareSerial.cpp, że rozmiar bufora różni się w zależności od ilości pamięci RAM dostępnej w danym AVR:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
W przypadku portu szeregowego oprogramowania w SoftwareSerial.h rozmiar bufora odbiornika _SS_MAX_RX_BUFF
jest zdefiniowany jako 64 bajty. W obu przypadkach przestaje próbować wstawiać odebrane dane do kolejki, gdy jest pełna, dzięki czemu można uzyskać mieszanie starych i nowych danych w zależności od sposobu pobierania danych z kolejki.
Najlepiej byłoby upewnić się, że bufor jest zawsze opróżniany w szybki sposób, aby uniknąć zapełnienia bufora. Być może spójrz na liczniki czasu i implementację prostej maszyny stanów, jeśli twój problem jest związany z innym kodem blokującym główną pętlę.
Ze źródła HardwareSerial widać, że jeśli przychodzący bajt znajdzie pełny bufor bufora, zostanie odrzucony:
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;
}
}
Odnoszę wrażenie, że jeśli przesyłam dane do Arduino i nie mam aktywnego „ściągacza” danych po stronie Arduino, to jeśli pojawi się więcej danych, niż można zmieścić w buforze, zostaną one odrzucone. Czy możesz to potwierdzić?
Tak, zostanie odrzucony. Nie ma kontroli oprogramowania ani sprzętu, chyba że wprowadzisz własne.
Jednak przy 64-bajtowym buforze i odbiorze danych z (powiedzmy) 9600 bodów, dostajesz jeden bajt co 1,04 ms, a zatem wypełnienie bufora zajmuje 66,6 ms. W przypadku procesora 16 MHz powinieneś być w stanie często sprawdzać bufor, aby się nie zapełniał. Wszystko, co naprawdę musisz zrobić, to przenieść dane z bufora HardwareSerial do własnego, jeśli nie chcesz ich teraz przetwarzać.
Z #if (RAMEND < 1000)
kontroli wynika, że procesory z ponad 1000 bajtami pamięci RAM otrzymują bufor 64-bajtowy, te mniej pamięci RAM otrzymują bufor 16-bajtowy.
Zapisywane dane są umieszczane w buforze tej samej wielkości (16 lub 64 bajtów). W przypadku wysyłania, jeśli bufor wypełnia kod, „bloki” czekają na przerwanie, aby wysłać kolejny bajt z portu szeregowego.
Wyłączenie przerwań nigdy się nie wydarzy, dlatego nie wykonuje się wydruków seryjnych w ramach procedury obsługi przerwań.
1/960 = 0.001042 s
- to jest jeden bajt co 1,04 ms.