Как Arduino обрабатывает переполнение последовательного буфера?

Как Arduino обрабатывает переполнение последовательного буфера? Выбрасывает ли он новейшие входящие данные или самые старые? Сколько байтов может удерживать буфер?

24 голоса | спросил HighLife 24 Maypm14 2014, 20:19:58

2 ответа


12

Для аппаратных последовательных портов вы можете увидеть в 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 байта. В обоих случаях он перестает пытаться вставлять полученные данные в очередь, когда он заполнен, поэтому вы можете получить соединение со старыми и новыми данными в зависимости от того, как вы извлекаете данные из очереди.

В идеале было бы лучше убедиться, что буфер всегда очищается в кратчайшие сроки, чтобы избежать заполнения буфера. Может быть, взгляните на таймеры и внедрите простую машину состояний, если ваша проблема связана с другим кодом, блокирующим основной цикл.

ответил PeterJ 25 Maypm14 2014, 12:38:17
5

Получение

Из источника HardwareSerial вы можете видеть, что если входящий байт обнаруживает, что кольцевой буфер заполнен, он отбрасывается:

 inline void store_char (unsigned char c, ring_buffer * buffer)
{
  int i = (unsigned int) (buffer-> head + 1)% SERIAL_BUFFER_SIZE;

  //если мы должны хранить полученный символ в местоположении
  //непосредственно перед хвостом (это означает, что голова продвигается к
  //текущее местоположение хвоста), мы собираемся переполнить буфер
  //и поэтому мы не пишем персонажа или не продвигаем голову.
  if (i! = buffer-> tail) {
    buffer-> буфер [buffer-> head] = c;
    buffer-> head = i;
  }
}
  

У меня создается впечатление, что если я передам данные в Arduino и у вас нет активного «съемника» данных на стороне Arduino, тогда, если поступит больше данных, чем может поместиться в буфер, оно будет отброшено. Можете ли вы это подтвердить?

Да, он будет отброшен. Нет управления программным или аппаратным потоком, если вы не реализуете свои собственные.

Однако с 64-байтным буфером и получением данных (скажем) 9600 бод вы получаете один байт каждые 1,04 мс, и, таким образом, для заполнения буфера требуется 66,6 мс. На процессоре с частотой 16 МГц вы должны иметь возможность достаточно часто проверять буфер, чтобы он не заполнялся. Все, что вам действительно нужно сделать, - это перемещать данные из буфера HardwareSerial самостоятельно, если вы не хотите обрабатывать его прямо сейчас.

Из #if (RAMEND <1000) вы можете видеть, что процессоры с 1000-байтовым ОЗУ получают 64-байтовый буфер, у которых меньше RAM получают 16-байтовые буфер.


Отправка

Данные, которые вы пишете, помещаются в буфер одного размера (16 или 64 байта). В случае отправки, если буфер заполняет код «блокирует», ожидая прерывания для отправки следующего байта из последовательного порта.

Если прерывания отключены, это никогда не произойдет, поэтому вы не выполняете серийные распечатки внутри процедуры обслуживания прерываний.

ответил Nick Gammon 9 AM00000030000004031 2015, 03:21:40

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132