Ftd2xx USB – optymalne ustawienia pakietu i Latency Timer dla minimalnej latencji FT232R, FT232H

Pytanie

Ftd2xx usb jaki pakiet ustawic dla najmniejszej latency

Odpowiedź Sztucznej Inteligencji


Bezpośrednia odpowiedź na pytanie

  • Ustaw w funkcji FT_SetUSBParameters() wartość ulInTransferSize równą JEDNEMU pakietowi USB: • 64 B dla urządzeń USB Full-Speed (np. FT232R, FT230X)
    • 512 B dla urządzeń USB High-Speed (np. FT232H, FT2232H)
  • Jednocześnie zredukuj Latency Timer ( FT_SetLatencyTimer() ) do 1 ms (lub 2 ms, jeżeli sterownik/układ nie akceptuje „1”).
    To zestawienie zapewnia najmniejsze praktycznie osiągalne opóźnienie przy zachowaniu stabilności połączenia.

Kluczowe punkty

  1. Rozmiar pakietu poniżej 64/512 B nie przyspieszy transmisji ‒ host i tak wysyła żądania w wielokrotnościach maks. pakietu EP.
  2. Duży ulInTransferSize (kilka kB) wydłuża czas oczekiwania, bo sterownik czeka na zapełnienie bufora lub upływ Latency Timer.
  3. Zmiana rozmiaru pakietu bez skrócenia Latency Timer nie daje zauważalnej korzyści.

Szczegółowa analiza problemu

1. Mechanizm tworzenia pakietu w D2XX

Sterownik D2XX zbiera dane z układu FTDI do własnego bufora. Dane są przekazywane aplikacji, gdy:
a) bufor osiągnie ustawione w FT_SetUSBParameters() ulInTransferSize, lub
b) od ostatniego transferu upłynie czas określony przez Latency Timer.

Dla ruchu o małym wolumenie (kilka–kilkadziesiąt bajtów) duży ulInTransferSize zmusza sterownik do czekania prawie wyłącznie na timer, co dodaje do 16 ms (wartość domyślna) opóźnienia.

2. Maksymalny pakiet USB

Protokół USB wysyła dane w „max-packet-size” przypisanym do punktu końcowego (endpointu):
• Full-Speed — 64 B, ramka 1 ms
• High-Speed — 512 B, mikro-ramka 125 µs
Wysłanie mniejszego żądania niż max-packet-size nie jest możliwe, więc ustawianie ulInTransferSize < 64/512 B niczego nie skraca, a jedynie wprowadza narzut sterownika.

3. Interakcja z Latency Timer

  • Typowe układy R/C/BM pozwalają na 1-255 ms (online AN232B-04).
  • Niektóre sterowniki linuksowe akceptują 0 ms, lecz FTDI oficjalnie ostrzega o wysokim zużyciu CPU.
  • 1 ms pokrywa się z jedną ramką USB FS; poniżej nie zyskujemy rzeczywistego czasu fizycznej transmisji, ale skracamy logikę sterownika.

4. Praktyczny kompromis

Szybka telemetria, MIDI, sterowanie serwomechanizmami itp. korzystają na ustawieniu:

FT_SetLatencyTimer(ftHandle, 1);          // 1 ms
FT_SetUSBParameters(ftHandle, 64, 0);     // Full-Speed
// lub
FT_SetUSBParameters(ftHandle, 512, 0);    // High-Speed

Testy loop-back pokazują typowe opóźnienia 1,1-1,5 ms (FS) i ~0,2 ms (HS) – zależnie od OS i wydajności CPU.

5. Gdzie pojawiają się ograniczenia

  • Bardzo małe Latency Timer + mały bufor = częste przerwania USB -> ~3-6-krotny wzrost obciążenia CPU.
  • W trybach synchronicznych FIFO (FT245 Sync, MPSSE) latencja jest dodatkowo ograniczona przez częstotliwość zegara I/O; pakiet 512 B @60 MHz wychodzi w ~70 µs.
  • Po stronie OUT (PC→układ) Latency Timer nie działa; decyduje scheduler host-a i wypełnienie FIFO TX.

Aktualne informacje i trendy

  • App-Note FTDI AN232B-04 z marca 2024 nadal rekomenduje „najpierw zmniejsz Latency Timer, potem dostosuj ulInTransferSize”.
  • Nowe sterowniki FTDI (2.14.x Windows, libftd2xx 1.4.x Linux/macOS) obsługują timer 0 ms, ale FTDI zastrzega, że „to tryb eksperymentalny”.
  • W systemach RT (Linux PREEMPT_RT, Windows RT) obserwuje się dalszą redukcję jitteru po przypisaniu wątku I/O do dedykowanego rdzenia.

Wspierające wyjaśnienia i detale

  • FT_SetUSBParameters(ftHandle, inSize, outSize) można wywołać dopiero PO FT_Open*, ale przed pierwszym FT_Read/Write.
  • W VCP (Virtual COM Port) zamiast D2XX podobną rolę pełni „USB Transfer Sizes” w rejestrach sterownika (Windows) lub /sys/bus/usb-serial/.../rx_queue_len (Linux).
  • FT_SetFlowControl() i FT_SetChars() pozostaw w stanie domyślnym, jeśli nie używasz XON/XOFF – nie wpływają na latencję.

Aspekty etyczne i prawne

Brak bezpośrednich implikacji etycznych; prawnie należy jedynie:

  • używać oryginalnych sterowników FTDI (licencja D2XX)
  • nie rozpowszechniać firmware ani wycinków sterownika z naruszeniem licencji.

Praktyczne wskazówki

  1. Zmierz latencję w trybie loop-back (TX→RX zwarty) i QueryPerformanceCounter()/clock_gettime().
  2. Jeżeli CPU przekracza 30 % przy 1 ms, podnieś Latency Timer do 2-4 ms lub zwiększ ulInTransferSize (np. 256 B FS).
  3. Na Linuxie dodaj udev-rule zmieniające latency_timer przy każdym podłączeniu, aby nie polegać na uprawnieniach root.

Ewentualne zastrzeżenia lub uwagi dodatkowe

  • Pełna eliminacja jitteru <1 ms w USB FS nie jest możliwa z powodu ramki 1 ms.
  • W High-Speed 512 B pakiet / 125 µs mikro-ramka stanowi fizyczne minimum.
  • Niektóre komputery (zwłaszcza z hubami USB 3.0) wprowadzają dodatkowe „coalescing” pakietów – testuj na bezpośrednio podłączonym porcie.

Sugestie dalszych badań

  • Sprawdź nowe układy FTDI serii FT60x (USB 3.0 SuperSpeed); latencja <50 µs dla 1024 B pakietu.
  • Rozważ interfejsy alternatywne (Cypress FX3, STM32 HS FSDevice), gdy potrzebne są opóźnienia sub-milisekundowe przy dużym throughput.
  • Zbadaj wpływ włączonego U1/U2 (USB 3 Link-Power-Management) na jitter w laptopach.

Krótkie podsumowanie

Najmniejszą osiągalną latencję w aplikacjach korzystających z biblioteki FTD2XX uzyskasz, gdy:

  1. Ustawisz Latency Timer = 1 ms (lub 2 ms, jeśli 1 nie działa stabilnie).
  2. ulInTransferSize ustawisz dokładnie na rozmiar jednego pakietu USB: 64 B (Full-Speed) albo 512 B (High-Speed).
    Ta kombinacja minimalizuje czas oczekiwania sterownika na zapełnienie bufora, jednocześnie nie zmuszając hosta do nadmiarowych, mniejszych transakcji USB.

Oceń odpowiedź:
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.