У меня есть устройство USB FullSpeed, которое отправляет дескриптор отчета, соответствующий дескриптор конечной точки которого объявляет bInterval
из 8, что означает 8 мс.
Следующая выдержка отчета получается из дампера дескриптора USB, когда устройстводрайвер HidUsb:
Interface Descriptor: // +several attributes
------------------------------
0x04 bDescriptorType
0x03 bInterfaceClass (Human Interface Device Class)
0x00 bInterfaceSubClass
0x00 bInterfaceProtocol
0x00 iInterface
HID Descriptor: // +bLength, bCountryCode
------------------------------
0x21 bDescriptorType
0x0110 bcdHID
0x01 bNumDescriptors
0x22 bDescriptorType (Report descriptor)
0x00D6 bDescriptorLength
Endpoint Descriptor: // + bLength, bEndpointAddress, wMaxPacketSize
------------------------------
0x05 bDescriptorType
0x03 bmAttributes (Transfer: Interrupt / Synch: None / Usage: Data)
0x08 bInterval (8 frames)
После переключения драйвера на WinUSB, чтобы иметь возможность его использовать, если я неоднократно запрашиваю передачу прерываний IN, используя libusb, и время реального времени, потраченное между 2 вызовами libusb и во время libusbвызов с использованием этого сценария:
for (int i = 0; i < n; i++) {
start = std::chrono::high_resolution_clock::now();
forTime = (double)((start - end).count()) / 1000000;
<libusb_interrupt_transfer on IN interrupt endpoint>
end = std::chrono::high_resolution_clock::now();
std::cout << "for " << forTime << std::endl;
transferTime = (double)((end - start).count()) / 1000000;
std::cout << "transfer " << transferTime << std::endl;
std::cout << "sum " << transferTime + forTime << std::endl << std::endl;
}
Вот пример полученных значений:
for 2.60266
transfer 5.41087
sum 8.04307 //~8
for 3.04287
transfer 5.41087
sum 8.01353 //~8
for 6.42174
transfer 9.65907
sum 16.0808 //~16
for 2.27422
transfer 5.13271
sum 7.87691 //~8
for 3.29928
transfer 4.68676
sum 7.98604 //~8
Значения суммы постоянно остаются очень близкими к 8 мс, за исключением времени, прошедшего до инициации нового прерывания.Переадресация слишком длинная (пороговое значение, по-видимому, находится между 6 и 6,5 для моего конкретного случая), в этом случае оно равно 16. Я однажды видел меру «для», равную 18 мс, а сумма точно равна 24 мс.Используя трекер URB (в моем случае Microsoft Message Analyzer), разница во времени между сообщениями Complete URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
также кратна 8 мс - обычно 8 мс.Короче говоря, они соответствуют мерам «суммы».
Итак, ясно, что время, прошедшее между двумя возвратами «вызовов передачи прерываний libusb», кратно 8 мсам, что, я полагаю, связано с bIntervalзначение 8 (FullSpeed -> * 1ms -> 8ms).
Но теперь, когда я, я надеюсь, дал понять, о чем я говорю - где это применяется?Несмотря на исследования, я не могу найти четкого объяснения того, как значение bInterval влияет на вещи.
Очевидно, это обеспечивается драйвером.
Следовательно, это:
Водитель запрещает запуск запроса до истечения 8 мс.Звучит как наиболее разумный вариант для меня, но из моего URB Trace события Dispatch message
были вызваны за несколько миллисекунд до того, как запрос вернулся.Это будет означать, что в реальном времени данные, оставленные хостом, скрыты от меня / анализатора сообщений.
Драйвер скрывает ответ от меня и анализатора до тех пор, пока не пройдет 8 мс с момента последнего ответа.
Если это действительно обработано драйвером, то где-то ложь с тем, что показано мне в журнале обмена сообщениями.Ответ должен прийти сразу после запроса, но это не так.Итак, либо запрос отправляется после указанного времени, либо ответ приходит раньше, чем отображается.
Как работает соблюдение принципа уважения bInterval?
Моя конечная цель состоит в том, чтобыне обращайте внимания на значение bInterval и опрашивайте устройство чаще, чем за 8 мс (у меня есть веские основания полагать, что оно может опрашиваться каждые 2 мс, а период 8 мс неприемлем для его использования), но сначала я бы хотел узнать, как его текущееограничение работает, если то, что я ищу, вообще возможно, поэтому я могу понять, что изучать дальше (например, написание собственного драйвера WinUSB)