Timeout en bulk transfer USB: depurando high-speed, full-speed, STALL, NAK y retrasos del firmware

Cómo diagnosticar timeouts en bulk transfers USB, lecturas lentas, escrituras stalled, comportamiento NAK, recuperación de endpoint halted, desajuste de velocidad y retrasos del firmware con evidencia USB.

usb bulk transfer timeout, usb bulk endpoint, usb high speed, usb full speed, endpoint stall, diagnóstico USB

Las bulk transfers USB se usan cuando la corrección importa más que el timing fijo. Dispositivos de almacenamiento, adaptadores serie, sondas de debug, herramientas de actualización de firmware, escáneres, dispositivos vendor-specific y muchos productos de adquisición de datos usan endpoints bulk. Cuando fallan, los usuarios buscan "USB bulk transfer timeout", "bulk endpoint stalled", "USB read timeout", "USB write timeout", "libusb bulk transfer failed" y "USB device stops responding during bulk transfer".

La aplicación suele ver un timeout o un error de E/S. El bus puede contar una historia más rica: el dispositivo estuvo haciendo NAK demasiado tiempo, el endpoint hizo STALL, el host reintentó, el dispositivo se reseteó, el tamaño de la transferencia era incorrecto, el dispositivo iba más lento de lo esperado, o el firmware se quedó bloqueado preparando datos.

Bus Scope ayuda porque los fallos de bulk transfer necesitan evidencia a nivel de endpoint, no solo un stack trace de la aplicación.

Para qué sirven las bulk transfers

Las bulk transfers son fiables a nivel de protocolo USB. Aprovechan el ancho de banda disponible y pueden reintentar. Son ideales para mover datos grandes donde la latencia importa menos que la corrección.

Dispositivos bulk habituales:

  • Almacenamiento masivo USB.
  • Adaptadores CDC serie.
  • Herramientas vendor-specific de firmware.
  • Sondas de debug.
  • Equipos de medida.
  • Impresoras y escáneres.
  • Algunos dispositivos de captura.
  • Pipes de datos de FPGA o microcontrolador.

Como las bulk transfers usan el ancho de banda sobrante del bus, el rendimiento puede variar según el resto del tráfico USB y el scheduling del host.

Timeout no siempre significa pérdida de paquetes

Un timeout en una bulk transfer suele significar que la petición del lado host no terminó dentro del timeout de la aplicación. Eso puede pasar incluso si el bus USB se está comportando de forma legal.

Causas posibles:

  • El dispositivo no tiene datos listos y sigue haciendo NAK.
  • El firmware está ocupado y retrasa la respuesta.
  • El endpoint quedó halted tras un STALL.
  • El host mandó la petición al endpoint equivocado.
  • El tamaño de la transferencia no encaja con la expectativa del protocolo.
  • El dispositivo se reseteó o desconectó.
  • El driver no envió la transferencia correctamente.
  • El camino full-speed es demasiado lento para el throughput esperado.
  • Otro dispositivo consume ancho de banda del bus.
  • El timeout de la aplicación es demasiado agresivo.

La traza debería señalar cuál de estas es plausible.

Comportamiento de NAK

Los dispositivos USB pueden responder con NAK para indicar que no están listos de forma temporal. NAK no es necesariamente un error. Es una señal de control de flujo.

Para un endpoint bulk IN, NAKs repetidos pueden significar que el dispositivo aún no tiene datos. Para un endpoint bulk OUT, los NAKs pueden indicar que el dispositivo no puede aceptar más datos ahora mismo.

El problema está en la duración y el contexto. Unos cuantos NAKs son normales. NAKs continuos hasta el timeout de la aplicación significan que el dispositivo nunca estuvo listo o que el host esperaba datos en el momento equivocado.

STALL y halt del endpoint

Un STALL es distinto de un NAK. Suele significar que el endpoint quedó halted o que la petición no se soporta en ese contexto. La recuperación a menudo requiere:

CLEAR_FEATURE(ENDPOINT_HALT)

Si el host no limpia el halt, las transferencias posteriores seguirán fallando. Si el endpoint vuelve a hacer STALL justo después de limpiarlo, puede que el firmware del dispositivo esté rechazando la secuencia de comandos.

Fíjate en:

  • Primer STALL antes del timeout.
  • CLEAR_FEATURE(ENDPOINT_HALT).
  • Si la transferencia se reanuda tras el clear.
  • Si el mismo comando causa STALL cada vez.
  • Reset tras STALL repetidos.

Expectativas high-speed frente a full-speed

La velocidad USB cambia el throughput realista. Un dispositivo full-speed no puede dar rendimiento high-speed. Un dispositivo capaz de high-speed puede caer a full-speed por culpa del cable, hub, puerto, integridad de señal o negociación del dispositivo.

Si la aplicación asume rendimiento high-speed pero el dispositivo enumeró a full-speed, pueden aparecer timeouts durante transferencias grandes.

Revisa descriptores, velocidad negociada, max packet size del endpoint y el pacing real de la transferencia. No infieras la velocidad por la forma del conector ni por el marketing.

Protocolos de comandos en el firmware

Muchos dispositivos bulk implementan un protocolo comando/respuesta sobre USB. El host escribe un comando en bulk OUT y espera datos en bulk IN.

Los timeouts pasan cuando:

  • El formato del comando es incorrecto.
  • El dispositivo espera una petición de control antes de la bulk transfer.
  • El dispositivo manda el status en otro endpoint.
  • El host lee demasiado pronto.
  • El host lee demasiado.
  • El firmware se bloquea procesando el comando.
  • El dispositivo requiere un boundary de zero-length packet.
  • Un estado de error previo no se limpió.

La evidencia de paquetes puede mostrar si el dispositivo ignoró el comando, lo stalled, lo aceptó pero nunca respondió, o respondió en otro endpoint.

Tamaño de bulk transfer y short packets

Los protocolos bulk USB suelen usar short packets para señalar el fin de la transferencia. Si el host espera una longitud fija pero el dispositivo manda un short packet, la aplicación puede interpretar mal el resultado. Si el host espera más datos después de que el dispositivo ya cerró la transferencia, puede aparecer un timeout a nivel de aplicación.

Fíjate en:

  • Longitud solicitada de la transferencia.
  • Longitud real devuelta.
  • Short packet.
  • Zero-length packet.
  • Framing de protocolo por encima de USB.

Esto es especialmente importante en firmware a medida y herramientas basadas en libusb.

Checklist de depuración

Usa este proceso:

  1. Captura la enumeración y los descriptores de endpoint.
  2. Confirma la velocidad del dispositivo y el max packet size del endpoint.
  3. Identifica los endpoints bulk IN y bulk OUT.
  4. Captura el comando o transferencia que da timeout.
  5. Comprueba si el endpoint devuelve NAK, STALL, datos o se desconecta.
  6. Inspecciona la recuperación con CLEAR_FEATURE(ENDPOINT_HALT) si hay STALL.
  7. Compara la longitud solicitada y la longitud real.
  8. Mira si el dispositivo manda short packet o zero-length packet.
  9. Compara el camino directo al puerto frente a hub y la ruta high-speed frente a full-speed.
  10. Correlaciona con logs de firmware si están disponibles.

Diagnóstico final

Un timeout en bulk transfer USB no es un único bug. Puede significar que el comportamiento normal de NAK excedió el timeout de la aplicación, que un STALL en el endpoint no se recuperó, que el firmware no respondió, que la velocidad era menor de lo esperado, que el framing del protocolo era incorrecto, o que el dispositivo se reseteó.

Bus Scope ayuda exponiendo la secuencia a nivel de endpoint, para que un timeout se convierta en evidencia USB diagnosticable en lugar de un error genérico de E/S.