Структура данных для хранения данных последовательного порта в прошивке - PullRequest
5 голосов
/ 13 июня 2009

Я отправляю данные из приложения Linux через последовательный порт на встроенное устройство.

В текущей реализации в прошивке используется байтовый циклический буфер. (Ничего, кроме массива с указателем чтения и записи) По мере поступления байтов он записывается в циклический буфер.

Теперь приложение для ПК, похоже, слишком быстро отправляет данные для обработки микропрограммой. Пропущены байты, в результате чего микропрограмма возвращает WRONG_INPUT слишком много раз.

Я думаю, что скорость передачи данных (115200) не является проблемой. Может помочь более эффективная структура данных на стороне прошивки. Есть предложения по выбору структуры данных?

Ответы [ 7 ]

13 голосов
/ 13 июня 2009

Круговой буфер - лучший ответ. Это самый простой способ смоделировать аппаратный FIFO в чистом программном обеспечении.

Реальная проблема, скорее всего, заключается в том, как вы собираете байты из UART для помещения в буфер, или в переполнении этого буфера.

При скорости 115200 бод с обычным 1 стартовым битом, 1 стоповым битом и 8 битами данных вы можете видеть до 11520 байт в секунду, поступающих на этот порт. Это дает в среднем около 86,8 мкс на байт для работы. На ПК это может показаться много времени, но в небольшом микропроцессоре это может быть не так уж много общих инструкций или в некоторых случаях очень много обращений к регистру ввода-вывода. Если вы переполните свой буфер, потому что байты поступают в среднем быстрее, чем вы можете их использовать, у вас будут ошибки.

Несколько общих советов:

  • Не выполнять опрашиваемый ввод / вывод.
  • Используйте прерывание Rx Ready.
  • Включить прием FIFO, если доступно.
  • Полностью очистить FIFO в обработчике прерываний.
  • Сделать кольцевой буфер достаточно большим.
  • Рассмотрим управление потоком.

Важно определить размер своего кольцевого буфера, достаточного для хранения полного сообщения. Если в вашем протоколе известны ограничения на размер сообщения, то вы можете использовать более высокие уровни протокола для управления потоком и выживания без проблем, чтобы заставить поток XON / XOFF работать правильно во всех пограничных случаях или RTS / CTS работать как положено в обоих концах провода, который может быть почти таким же волосатым.

Если вы не можете сделать кольцевой буфер таким большим, тогда вам понадобится какой-то тип управления потоком.

1 голос
/ 14 июня 2009

Прежде чем пытаться решить проблему, сначала необходимо выяснить, в чем проблема на самом деле. В противном случае вы можете потратить время на то, чтобы починить то, что на самом деле не сломано.

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

1 голос
/ 13 июня 2009

Что вы подразумеваете под встроенным устройством? Я думаю, что большинство современных DSP и процессоров легко справляются с такой нагрузкой. Проблема не в циклическом буфере, а в том, как вы собираете байты из последовательного порта.

Есть ли в вашем UART аппаратный fifo? Если да, то вам следует включить его. Если у вас есть прерывание на байт, вы можете быстро столкнуться с проблемами, особенно если вы работаете с ОС или с виртуальной памятью, где стоимость IRQ может быть достаточно высокой.

Если ваша принимающая прошивка очень простая (без многозадачности) и у вас нет аппаратного fifo, режим опроса может быть лучшим решением, чем управляемый прерываниями, потому что тогда ваш процессор выполняет только прием данных UART, и нет прерываний.

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

Итак, круговой буфер в порядке, и вы должны улучшить его: - Как вы взаимодействуете с оборудованием - протокол (длина пакета, подтверждение и т. Д.)

1 голос
/ 13 июня 2009

Нет ничего лучше кольцевого буфера.

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

Если вывод ПК выполняется пакетами, это может помочь сделать буфер достаточно большим для обработки одного пакета.

Последний вариант - реализовать некоторую форму управления потоком.

0 голосов
/ 18 ноября 2009

Использование кругового буфера в сочетании с IRQ - отличное предложение. Если ваш процессор генерирует прерывание при каждом получении байта, возьмите этот байт и сохраните его в буфере. То, как вы решите очистить этот буфер, зависит от того, обрабатываете ли вы поток данных или пакеты данных. Если вы обрабатываете поток, просто попросите фоновый процесс удалить байты из буфера и обработать их в порядке очереди. Если вы обрабатываете пакеты, просто продолжайте заполнять буфер, пока не получите полный пакет. В прошлом я успешно использовал пакетный метод. Я бы также реализовал некоторый тип управления потоком, чтобы сигнализировать ПК, если что-то пошло не так, как полный буфер, или если время обработки пакета велико, чтобы указать ПК, когда он готов к следующему пакету.

0 голосов
/ 15 июня 2009

Круговой буфер с IO, управляемым прерываниями, будет работать на самых маленьких и самых медленных из встроенных целей.

Сначала попробуйте с самой низкой скоростью передачи, а затем - с высокой скоростью.

0 голосов
/ 13 июня 2009

Вы можете реализовать что-то вроде дейтаграммы IP, которая содержит длину данных, идентификатор и контрольную сумму.

Редактировать : Затем вы можете жестко запрограммировать некоторую фиксированную длину для пакетов, например, 1024 байта или что-то еще, что имеет смысл для устройства. Сторона ПК будет тогда проверять, заполнена ли очередь на устройстве каждый раз, когда она записывает в пакет. Сторона микропрограммного обеспечения запускает контрольную сумму, чтобы увидеть, все ли данные действительны, и считывает до длины данных.

...