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
- Rozmiar pakietu poniżej 64/512 B nie przyspieszy transmisji ‒ host i tak wysyła żądania w wielokrotnościach maks. pakietu EP.
- Duży
ulInTransferSize
(kilka kB) wydłuża czas oczekiwania, bo sterownik czeka na zapełnienie bufora lub upływ Latency Timer
.
- 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
- Zmierz latencję w trybie loop-back (TX→RX zwarty) i
QueryPerformanceCounter()/clock_gettime()
.
- Jeżeli CPU przekracza 30 % przy 1 ms, podnieś
Latency Timer
do 2-4 ms lub zwiększ ulInTransferSize
(np. 256 B FS).
- 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:
- Ustawisz
Latency Timer
= 1 ms (lub 2 ms, jeśli 1 nie działa stabilnie).
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.
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.