2009-06-13 2 views
4

Я отправляю данные из приложения linux через последовательный порт во встроенное устройство.Структура данных для хранения данных последовательного порта в прошивке

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

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

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

+1

уточните: каковы спецификации встроенной системы? С какой скоростью он работает? Сколько инструкций может быть реалистично выполнено? – none

ответ

12

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

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

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

Некоторые общие советы:

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

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

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

+0

Я не уверен, что приведение в действие IRQ всегда: - доступно - желательно – shodanex

+1

IMHO, опрошенный IO затруднительный, поскольку он требует, чтобы код мог проверять следующий символ во времени. Однако на действительно маленьком процессоре это может быть ваш единственный вариант. На больших процессорах опрос может быть значительно менее эффективным, чем использование прерываний или DMA. – RBerteig

1

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

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

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

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

-2

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

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

+0

Что? Как это отвечает на вопрос? –

1

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

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

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

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

Так кольцевой буфер хорошо и вы должны образом улучшить: - способ взаимодействия с аппаратным - протокол (длина пакета, acknoledgment и т.д ...)

+0

Да, перед заменой базовой структуры данных, сначала убедитесь, что это действительно узкое место, которое вы видите – none

1

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

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

+0

Согласен. Я потратил слишком много часов, когда встроенные приложения пытались исправить что-то, где проблема была где-то еще. – guzelo

0

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

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

0

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

Смежные вопросы