USB: низкая задержка (‹ 1 мс) с передачей прерываний и необработанным HID

У меня есть проект, который требует регулярного чтения данных внешнего гироскопа IMU и отправки данных на телефон Android.

Я использую плату teensy 2.0 для запроса IMU через I2C и отправки его через USB с использованием необработанного HID. Я использую переменную RawHID, которая объявлена ​​в usb_api.h из usb_rawhid teensyduino.

Я читал, что полноскоростной USB, использующий передачу с прерыванием, может иметь максимальную задержку 1 мс, и хотел бы достичь этой максимальной задержки 1 мс. Я не уверен, что искать для достижения этой максимальной задержки, и хотел бы узнать об указателях. Моя конечная цель — получать данные гироскопа каждые 2 мс (500 Гц).

Несколько вещей, о которых я знаю, которые могут быть проблемой:

1) Я изменил RAWHID_TX_SIZE на 6 байтов (мне нужно только 6 байтов для значения гироскопа), а RAWHID_TX_INTERVAL установлен на 1 мс (самый быстрый). Конечная точка OUT в настоящее время указана в интерфейсе, который мне не нужен, я не уверен, что ее удаление может уменьшить задержку.

2) Android распознает teensy как «hiddev USB HID v1.11 Device». Я не уверен, что это полный необработанный HID или он пытается его проанализировать. Teensy использует необработанный HID, как указано выше.

3) В Android определенный поток пытается поставить очередь() на UsbRequest, за которой следует requestWait(). Обработка при поступлении данных происходит очень быстро (т. е. сохраняется в глобальной переменной), но я нахожусь во власти планировщика потоков.

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


person Jary316    schedule 16.01.2015    source источник


Ответы (1)


Для USB это все опрос. Каждую 1 мс у вас есть «кадр», состоящий из ни одного или нескольких дескрипторов передачи, где каждый дескриптор передачи сообщает контроллеру USB, какое USB-устройство опрашивать.

Как правило, контроллер USB начинает кадр с дескрипторов передачи для прерывания передачи. Это означает, что с одним дескриптором передачи прерывания вы (почти) гарантированно будете опрашиваться один раз за мс. Если ваше устройство имеет прерывание для отправки, оно возвращает его при опросе; так что в худшем случае вы получите задержку в 1 мс.

Можно попросить USB-контроллер реже опрашивать устройство (например, изохронные передачи). Также можно попросить контроллер USB опрашивать устройство несколько раз в одном и том же кадре 1 мс; однако, поскольку он обычно сначала прерывает дескрипторы передачи, вы ожидаете, что опрос будет выполнен дважды почти в одно и то же время с промежутком «почти 1 мс» между ними, так что это не поможет в худшем случае задержки.

В основном, насколько я могу судить, для требования «‹ 2 мс» спецификации / протоколы USB, контроллер USB, драйвер контроллера USB ядра и драйвер USB HID ядра не являются проблемой вообще. Проблема заключается в своевременной передаче данных из драйвера USB HID в процесс/поток пользовательского пространства.

К сожалению, Linux/Andriod не является ОС реального времени. Он не дает никаких гарантий. Вы будете во власти планировщика потоков (и, возможно, также сборщика мусора JVM). Вероятно, вы ничего не можете с этим поделать.

Я бы порекомендовал выяснить, почему вам нужно получать данные гироскопа каждые 2 мс в первую очередь. В качестве простого примера, можете ли вы добавить временную метку к данным гироскопа и позволить принимающему потоку «реконструировать историю» по этим временным меткам, чтобы принимающий поток вообще не нуждался в малой задержке?

person Brendan    schedule 16.01.2015
comment
Большое спасибо, Брендан, это очень хорошее объяснение. Несколько вещей, которые я не уверен, что понимаю ясно, вы говорите с передачей одного прерывания, вы указываете конечную точку или просто интерфейс, пожалуйста? То, о чем вы говорите, если я правильно понимаю, что если описано более одного интерфейса, это отнимет некоторое время у моего кадра (поэтому я должен описать только один интерфейс передачи прерывания, а может быть, только IN endpoint?) - person Jary316; 16.01.2015
comment
К сожалению, мой вариант использования требует ограниченной задержки, поскольку я пытаюсь отслеживать телефон в реальном времени. Я могу применять такие артефакты, как предсказание, чтобы сгладить дрожание или задержку, но получение данных с очень низкой задержкой через равные промежутки времени — моя конечная цель. - person Jary316; 16.01.2015