Буферизация неполных высокоскоростных операций чтения - PullRequest
1 голос
/ 17 февраля 2012

Я читаю данные ~ 100 байт на 100 Гц из последовательного порта.Мой буфер составляет 1024 байта, поэтому часто мой буфер используется не полностью.Однако иногда я получаю икоты с последовательного порта, и буфер заполняется.

Мои данные организованы как [header] data [checkum].Когда мой буфер заполняется, иногда сообщение / данные разделяются на две операции чтения из последовательного порта.

Это простая проблема, и я уверен, что есть много разных подходов.Я опережаю график, поэтому я хотел бы исследовать различные подходы.Не могли бы вы, ребята, назвать несколько парадигм, которые охватывают буферизацию в высокоскоростных данных, которые, возможно, потребуется собрать из двух операций чтения?Обратите внимание, что основное отличие, которое я вижу в этой проблеме от, скажем, другой буферизации, которую я сделал (получение изображений, tcp / ip), заключается в том, что там нам гарантированы полные пакеты / сообщения.Здесь «пакет» может быть разделен между операциями чтения, которые мы узнаем только после того, как начнем анализ данных.

О, да, обратите внимание, что данные, буферизованные в результате чтения, должны быть проанализированы, поэтомупросто, данные должны быть смежными, когда они достигают синтаксического анализа.(Плюс я не думаю, что это ответственность парсера)

Некоторые идеи, которые у меня были:

  1. Перенести неиспользованные байты в мой оригинальный буфер, а затем заполнить его чтением после левогоболее байтов из предыдущего чтения.(Например, мы читаем 1024 байта, 24 байта остаются в конце, это частичное сообщение, memcpy в начало read_buffer_, передаем начало + 24 для чтения и чтения в 1024 - 24)
  2. Создайте свой собственный класс, который просто получает блоки данных.Он имеет два указателя: чтение / запись и большой кусок памяти (1024 * 4).Когда вы передаете данные, класс корректно обновляет указатель записи и переносится в начало своего буфера, когда достигает конца.Я думаю, как кольцевой буфер?
  3. Я думал, может быть, используя std::vector<unsigned char>.Динамическое распределение памяти, гарантированно непрерывное.

Спасибо за информацию, ребята!

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

Определите некоторый класс прикладного протокола APU 'APU', который будет представлять ваши '[header] данные [контрольную сумму]'. Дайте ему некоторую функцию «add», которая принимает параметр char и возвращает «valid» bool. В вашей ветке последовательного чтения создайте APU и прочитайте некоторые данные в свой 1024-байтовый буфер. Выполните итерацию данных в буфере, помещая их в APU add (), пока либо функция APU add () не вернет true, либо итерация не будет завершена. Если add () возвращает true, у вас есть полный APU - поставьте его в очередь для обработки, создайте еще один и начните add () - добавьте в него оставшиеся байты буфера. Если итерация завершена, вернитесь назад, чтобы прочитать больше последовательных данных.

Метод add () будет использовать конечный автомат или другой механизм для создания и проверки входящих байтов, возвращая true только в случае полного проверенного набора данных с правильной контрольной суммой. Если какая-то часть проверки завершается неудачно, APU сбрасывается и ожидает обнаружения действительного заголовка.

APU может, возможно, анализировать сами данные, либо побайтно во время ввода данных add (), непосредственно перед тем, как add () возвращает значение true, либо, возможно, как отдельный метод parse (), вызываемый позже. Возможно, каким-то другим потоком обработки APU.

0 голосов
/ 17 февраля 2012

При быстром чтении с последовательного порта вам, как правило, нужен какой-то механизм подтверждения связи для управления потоком данных.Это может быть аппаратное обеспечение (например, RTS / CTS), программное обеспечение (Xon / Xoff) или управление по протоколу более высокого уровня.Если вы читаете большой объем данных на скорости без рукопожатия, ваш UART или последовательный контроллер должен иметь возможность считывать и буферизовать все доступные данные на этой скорости, чтобы не потерять их.На 16550-совместимых UART, которые вы видите на ПК с Windows, этот буфер составляет всего 14 байтов, следовательно, требуется рукопожатие или ОС реального времени.

...