Устранение пробелов в потоковых данных USB - PullRequest
6 голосов
/ 27 июля 2010

У нас есть аппаратная система с некоторыми ПЛИС и контроллером FTDI USB.Аппаратные средства передают данные через USB-порт на ПК со скоростью около 5 МБ / с, а программное обеспечение выполняет задачу синхронизации, проверки CRC и записи данных в файл.

Микросхема FTDI имеет «занят»Пин, который идет высоко, пока его ждет ПК, чтобы сделать свой бизнес.В FTDI и в других местах аппаратного обеспечения имеется ограниченный объем буферизации.

Занятость увеличивается до тех пор, пока аппаратная часть не может буферизовать (50-100 мс), поэтому мы теряем данные.Чтобы избавить нас от необходимости перепроектировать оборудование, меня попросили «исправить» эту проблему!

Я думаю, что мой код достаточно быстр, поскольку у нас он работает до 15 МБ / с, так чтооставляет где-то узкое место IO.Мы просто слишком многого ожидаем от ПК / ОС?

Вот моя точка ввода данных.Иногда мы получаем бит или байт.Если контрольная сумма не вычисляется, я перемещаюсь до тех пор, пока это не произойдет.byte [] данные почти всегда 4k.

    void ftdi_OnData(byte[] data)
    {
        List<byte> buffer = new List<byte>(data.Length);
        int index = 0;

        while ((index + rawFile.Header.PacketLength + 1) < data.Length)
        {
            if (CheckSum.CRC16(data, index, rawFile.Header.PacketLength + 2)) // <- packet length + 2 for 16bit checksum
            {
                buffer.AddRange(data.SubArray<byte>(index, rawFile.Header.PacketLength));                 
                index += rawFile.Header.PacketLength + 2; // <- skip the two checksums, we dont want to save them...
            }
            else
            {
                index++; // shift through
            }
        }

        rawFile.AddData(buffer.ToArray(), 0, buffer.Count);
    }

Ответы [ 3 ]

4 голосов
/ 27 июля 2010

Совет: не записывайте в файл .... очередь.

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

  • В потоке обрабатывает данные USB, проверяет контрольные суммы и т. Д. Он ставит в очередь (ТОЛЬКО) результаты в потокобезопасную очередь.
  • Другой поток читает данные из очереди и записывает их в файл, возможно, буферизированный.

Закончено;)

100 мс - много времени для приличных операций. Я успешно обработал около 250 000 пакетов данных ввода-вывода в секунду (финансовые данные), используя C # без проблем.

По сути, убедитесь, что ваши IO-потоки делают ТОЛЬКО это и используют вашу внутреннюю память в качестве буфера. Особенно это касается аппаратного обеспечения на одном конце потока, который должен делать ТОЛЬКО это, ВОЗМОЖНО, если необходимо, с высоким приоритетом.

2 голосов
/ 27 июля 2010

Чтобы получить хорошую пропускную способность чтения в Windows по USB, вам обычно нужно иметь несколько асинхронных операций чтения (или очень больших операций чтения, что часто менее удобно), помещенных в очередь в стек USB-устройств. Я не совсем уверен, что драйверы / библиотеки FTDI делают внутренне в этом отношении.

Традиционно я написал механизмы с массивом структур OVERLAPPED и массивом буферов и продолжал перетаскивать их в ReadFile, как только они освобождались. Примерно 5-6 лет назад я выполнял чтение со скоростью 40 МБ / с на USB2, поэтому современные ПК, безусловно, должны справляться.

Очень важно, чтобы вы (или ваши драйверы / библиотеки) не попали в цикл «начать чтение, закончить чтение, разобраться с данными, начать другое чтение», потому что вы обнаружите, что шина простоя на обширные промежутки времени. Анализатор USB покажет вам, если это происходит.

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

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

Все эти контрольные суммы и конкатенации с выделением сопутствующей памяти, сборкой мусора и т. Д. Могут выполняться на другой стороне потенциально 100-мегабайтного пространства буфера времени / пространства на ПК. На данный момент вы вполне можете просить ваш FPGA / аппаратный буфер учесть время, затрачиваемое на выполнение всяких громоздких вещей на ПК, что можно сделать гораздо позже.

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

0 голосов
/ 27 июля 2010

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

Вы разработали остальную часть своего кода, чтобы избежать более дорогих сборок мусора 2-го поколения? Насколько велики ваши буферы, они в куче больших объектов? Вы эффективно их используете?

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