Як Arduino обробляє переповнення послідовного буфера? Це викидає найновіші вхідні дані чи найдавніші? Скільки байтів може містити буфер?
Як Arduino обробляє переповнення послідовного буфера? Це викидає найновіші вхідні дані чи найдавніші? Скільки байтів може містити буфер?
Відповіді:
Для апаратних послідовних портів ви можете побачити в HardwareSerial.cpp, що розмір буфера змінюється в залежності від обсягу оперативної пам’яті, доступного для конкретного AVR:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Для послідовного порту програмного забезпечення в SoftwareSerial.h розмір буфера приймача _SS_MAX_RX_BUFF
визначається як 64 байти. В обох випадках він припиняє спробу вставити отримані дані у чергу, коли вона заповнена, тож ви можете отримати суміш зі старими та новими даними залежно від того, як ви отримуєте дані з черги.
В ідеалі було б найкраще забезпечити, щоб буфер завжди спорожнявся оперативно, щоб уникнути заповнення буфера. Можливо, подивіться на таймери та реалізуйте просту машину стану, якщо ваша проблема пов’язана з іншим кодом, що блокує основний цикл.
З джерела HardwareSerial видно, що якщо вхідний байт знаходить буфер кільця повним, він відкидається:
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;
}
}
У мене складається враження, що якщо я передаю дані в Arduino і не матиму активного "знімача" даних на стороні Arduino, то якщо в буфер надійде більше даних, ніж може вміститися, вони будуть відкинуті. Ви можете це підтвердити?
Так, це буде відкинуто. Немає програмного або апаратного контролю потоку, якщо ви не реалізуєте свій власний.
Однак, використовуючи 64-байтовий буфер і отримуючи дані при (скажімо, 9600 бодах), ви отримуєте один байт кожні 1,04 мс, а значить, для заповнення буфера потрібно 66,6 мс. На процесорі 16 МГц ви повинні мати можливість перевіряти буфер досить часто, щоб він не заповнювався. Все, що вам потрібно зробити - це перемістити дані з буфера HardwareSerial до свого власного, якщо ви не хочете обробляти їх зараз.
З #if (RAMEND < 1000)
перевірки видно, що процесори з 1000+ байтами оперативної пам’яті отримують 64-байтовий буфер, тим менше ОЗУ отримає 16-байтовий буфер.
Дані, які ви записуєте, розміщуються в буфері одного розміру (16 або 64 байти). У разі надсилання, якщо буфер заповнює код "блокує", чекаючи переривання, щоб відправити наступний байт з послідовного порту.
Якщо переривання буде вимкнено, цього ніколи не відбудеться, значить, ви не робите послідовних роздруківків всередині програми переривання служби.
1/960 = 0.001042 s
- це один байт кожні 1,04 мс.