Как я могу увеличить скорость моего устройства USB CDC?

Я модернизирую процессор во встроенной системе для работы. Это все на С, без ОС. Часть этого обновления включает в себя перенос интерфейса связи между процессором и ПК с IEEE-488 на USB. Я наконец-то написал прошивку USB и уже тестировал ее. Все шло отлично, пока я не попытался протолкнуть много данных, только чтобы обнаружить, что мое USB-соединение медленнее, чем старое соединение IEEE-488. У меня есть устройство USB, перечисляемое как устройство CDC со скоростью передачи 115200 бит / с, но ясно, что я даже не достигаю этой пропускной способности, и я подумал, что это число было фиктивным значением, которое является удержанием от RS232 дней, но я может быть не так. Я контролирую каждый аспект этого от внешнего интерфейса на ПК до встроенного программного обеспечения встроенной системы.

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

Одна из моих проблем заключается в том, что в старой системе у нас была плата, предназначенная для связи. Процессор будет просто записывать данные через шину на эту плату и обрабатывать коммуникации, что означает, что ЦПУ не нужно тратить свободное время на обработку фактических сообщений, но он может разгрузить коммуникации на "сопроцессор" (не процессор, но функционально здесь то же самое). Даже с учетом этой проблемы, хотя я полагал, что мне следует получать более высокие скорости, учитывая, что полная скорость USB составляет порядка МБ / с, а IEEE-488 - порядка КБ / с.

Короче говоря, это скорее фундаментальное системное ограничение или проблема оптимизации программного обеспечения?

1 ответ

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

Вы правы, число бод является фиктивным значением. Если вы создадите адаптер CDC/RS232, вы будете использовать его для настройки оборудования RS232, в этом случае это ничего не значит.

Есть ли более эффективный способ сделать это?

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

В зависимости от ваших требований к задержке вы можете придерживаться кольцевого буфера и выдавать данные из него в функцию USB_Write только при наличии количества байтов ENDPOINT_SZ. Если это приводит к чрезмерной задержке или ваш интерфейс не всегда обменивается данными, вы можете реализовать алгоритм Nagles.

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

Часть NXP, которую вы упомянули в комментариях, без сомнения, достаточно быстра, чтобы насыщать USB-соединение на полной скорости.

Короче говоря, это скорее фундаментальное системное ограничение или проблема оптимизации программного обеспечения?

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

Позаботьтесь, чтобы точно выяснить, какой тип USB-соединения вы используете, хотя, если вы используете USB 1.1, вы будете ограничены 64 КБ / с, а полная скорость USB 2.0 - 512 КБ / с. Если вам требуется более высокая пропускная способность, вы должны перейти на использование отдельной конечной точки для передачи данных.

Я бы порекомендовал прочитать простой USB-сайт, чтобы получить представление о различных скоростях USB и их возможностях.

И последнее замечание: библиотеки CDC вендоров не всегда являются лучшими, и реализации стандарта CDC могут отличаться. Теоретически вы можете получить больше данных через конечную точку CDC, используя более крупные конечные точки, хотя я видел, что это приводит к тому, что драйверы на стороне хоста стоят на коленях - если вы идете по этому пути, создайте собственный драйвер, используя объемные конечные точки.

Попробуйте протестировать ваше устройство на нескольких системах, вы можете обнаружить, что вы получаете совершенно разные результаты для Windows и Linux. Это поможет указать пальцем на конец хоста.

И наконец, убедитесь, что вы выполняете большие буферизованные чтения на стороне хоста, USB прекратит передачу данных, как только буферы на стороне хоста заполнятся.

Другие вопросы по тегам