Depuración USB CDC ACM DTR y RTS: SetControlLineState, apertura de puerto serie, reset de bootloader y datos faltantes
Cómo depurar el estado de líneas DTR y RTS en USB CDC ACM, peticiones SetControlLineState, comportamiento al abrir el puerto serie, triggers de reset al bootloader y datos serie que no llegan.
Los dispositivos USB CDC ACM parecen puertos serie, pero muchos bugs de "puerto serie" son en realidad bugs de control de clase USB. Los usuarios buscan "CDC ACM DTR RTS", "SetControlLineState USB", "USB serial no data until DTR", "Arduino resets when serial port opens", "USB CDC bootloader reset" y "COM port opens but device does not respond" cuando el puerto existe pero el comportamiento es incorrecto.
Bus Scope ayuda porque DTR y RTS no son flags mágicas de aplicación. El host envía peticiones de control class-specific y el firmware reacciona a esas peticiones.
Qué hace SetControlLineState
CDC ACM usa una class request conocida como SetControlLineState. Comunica el estado de líneas de control como:
- DTR: Data Terminal Ready.
- RTS: Request To Send.
Muchos dispositivos usan estos bits para más cosas que el comportamiento clásico de módem. El firmware puede empezar a transmitir solo tras DTR asserted, entrar en bootloader cuando DTR conmuta, o usar RTS como semántica de control de flujo.
Síntomas habituales
Los problemas de líneas de control aparecen como:
- El puerto COM se abre pero no llega ningún dato.
- El dispositivo empieza a enviar solo cuando se conecta el programa terminal.
- El firmware se resetea cuando se abre el monitor serie.
- Aparece el bootloader tras abrir/cerrar el puerto.
- Los datos se cortan cuando cae DTR.
- Cambiar la opción RTS/CTS cambia el comportamiento.
- La herramienta de Linux funciona pero la de Windows no.
- Un script en Python se comporta distinto al emulador de terminal.
Estas frases encajan con los síntomas que describen los ingenieros cuando intentan reproducir el fallo.
Comportamiento al abrir el puerto serie
Cada aplicación del host configura DTR y RTS a su manera al abrir el puerto.
Ejemplos:
- El emulador de terminal pone DTR inmediatamente.
- Un script abre el puerto pero deja DTR en false.
- La herramienta de actualización de firmware conmuta DTR como señal de reset.
- El driver pone RTS según los ajustes de control de flujo.
- La aplicación cierra el puerto y DTR cae de forma inesperada.
La traza de paquetes puede enseñar la secuencia real de peticiones de control, en lugar de depender de lo que asume la aplicación.
Patrones de reset al bootloader
Muchas placas de desarrollo usan transiciones de DTR o RTS para resetear y entrar al bootloader. Es cómodo para subir firmware, pero sorprende en herramientas de producción.
Patrones de fallo:
- El dispositivo se resetea cada vez que se abre un visor de logs.
- La subida de firmware va, pero la conexión serie normal falla.
- El dispositivo aparece como una identidad USB, se resetea y reenumera como bootloader.
- El número de serie o el string de producto cambia tras el reset.
- La aplicación pierde el handle del puerto.
Bus Scope debería conservar la petición de control y la secuencia de re-enumeración.
No hay datos hasta DTR
Algunos firmware esperan a DTR a propósito antes de enviar datos. Eso puede hacer que una herramienta parezca rota mientras otra va bien.
Evidencia:
- El host abre endpoints bulk o interrupt.
- No se mandan datos IN.
- El host envía SetControlLineState con DTR true.
- El dispositivo empieza a transmitir.
Esto no es un problema de cable ni necesariamente un bug de driver. Es política del firmware.
Confusión con RTS y el control de flujo
RTS se puede usar para control de flujo hardware, pero muchos dispositivos CDC USB no tienen líneas de módem reales. El firmware puede exponer igualmente el estado de RTS a la lógica de la aplicación.
Preguntas:
- ¿El host pone RTS?
- ¿El dispositivo requiere RTS antes de transmitir?
- ¿Activar el control de flujo hardware en el terminal cambia los bits de la petición?
- ¿El firmware ignora RTS aunque la documentación diga lo contrario?
- ¿Se usa RTS como bootloader o como señal de selección de modo?
La evidencia de paquetes evita tener que adivinar.
Checklist de depuración
Usa este proceso:
- Captura la enumeración.
- Abre el puerto serie con la app que falla.
- Apunta las class-specific requests CDC.
- Encuentra SetControlLineState.
- Decodifica los bits DTR y RTS.
- Compara con un programa terminal que sí funcione.
- Mira si los datos empiezan tras DTR.
- Mira si hay reset o re-enumeración tras una conmutación.
- Compara herramientas Windows y Linux.
- Conserva juntas las peticiones de control y los primeros paquetes de datos.
Diagnóstico final
Los problemas de DTR y RTS en USB CDC ACM son problemas de secuenciación de control de clase. El puerto puede existir y los drivers pueden enlazar correctamente mientras el firmware espera un estado de línea de control que la aplicación nunca envía.
Bus Scope ayuda a enseñar SetControlLineState, DTR, RTS, el comportamiento al abrir el puerto, los resets al bootloader y las causas de datos faltantes a nivel de protocolo USB.