Stall em USB e depuração de transferências de controle: bmRequestType, bRequest, wValue e wIndex
Como corrigir erros de stall em USB e falhas em transferências de controle. Aprenda a diagnosticar problemas no pacote de setup usando bmRequestType, bRequest, wValue, wIndex e evidência de requisição de descritor na depuração de firmware.
As transferências de controle são a primeira conversa séria entre host e dispositivo. A enumeração depende delas. A configuração de classe depende delas. A inicialização específica do fabricante geralmente também. Quando uma transferência de controle falha, o usuário costuma ver apenas "dispositivo não reconhecido" ou "driver falhou", mas a evidência quase sempre está no pacote de setup.
Para o engenheiro de firmware, aprender a ler bmRequestType, bRequest, wValue, wIndex e wLength é um dos caminhos mais rápidos para trocar achismo por correção precisa.
O pacote de setup é o contrato da requisição
Um pacote de setup em USB diz ao dispositivo:
- direção da transferência
- tipo de requisição: standard, class, vendor ou reserved
- recipient: device, interface, endpoint ou outro
- código da requisição
- campo de valor
- campo de índice
- comprimento esperado de dados
Se o firmware decodifica esses campos errado, ele pode devolver o descritor errado, travar uma requisição válida ou aceitar um comando inválido. Se o host envia uma requisição inesperada, a captura mostra isso também.
GET_DESCRIPTOR é o primeiro lugar para olhar
Durante a enumeração, o host envia requisições standard de descritor. Um padrão comum inclui:
- requisição do descritor de dispositivo
- requisição do descritor de configuração
- requisição do descritor de string
- requisição do descritor de relatório HID para dispositivos HID
- requisição do descritor BOS em hosts mais novos
No pacote de setup, bRequest identifica o GET_DESCRIPTOR, enquanto wValue inclui o tipo de descritor e o índice. wIndex pode identificar o language ID para descritores de string ou a interface para descritores específicos de classe. wLength diz quantos bytes o host espera.
Quando o tamanho da resposta do descritor está errado, ou quando o firmware devolve menos bytes do que o host precisa, a enumeração pode falhar mais adiante de um jeito que parece não ter relação.
Erros de direção custam caro
Transferências de controle têm direção. Requisições device-to-host devolvem dados. Requisições host-to-device carregam dados ou configuram estado. Se o firmware trata uma leitura como escrita, ou devolve dados durante uma escrita, o host não vai adivinhar a intenção.
Fique de olho em:
- direção IN sem data stage
- direção OUT enquanto o firmware espera para enviar dados
- status stage de comprimento zero ausente
- STALL em uma requisição standard válida
- requisição de classe tratada pela interface errada
A captura deve mostrar a requisição, o data stage e o status stage.
Requisições de classe e vendor precisam de contexto de interface
Depois da enumeração, drivers de classe enviam requisições específicas. CDC pode enviar requisições de line coding. HID pode requisitar descritores de relatório ou feature reports. Ferramentas vendor podem enviar comandos de inicialização. O mesmo valor de bRequest pode significar coisas diferentes conforme o tipo de requisição e o recipient.
Inspecione:
- tipo da requisição
- recipient
- número de interface em
wIndex - número do endpoint quando o recipient é endpoint
- bytes do payload
- resposta ou stall
Se um dispositivo composto tem várias interfaces, rotear a requisição para a interface errada é um bug frequente.
Como o Bus Scope ajuda
O Bus Scope foi feito para evidência USB. A depuração de transferências de controle exige os campos decodificados e os bytes brutos lado a lado. A melhor visualização deixa o engenheiro ler os campos semânticos e ainda validar os bytes exatos do pacote.
Uma sessão útil do Bus Scope para depurar transferências de controle deve responder:
- qual pacote de setup falhou?
- era standard, class ou vendor?
- qual descritor ou interface foi solicitado?
- o dispositivo devolveu o tamanho esperado?
- o firmware gerou stall de propósito ou por engano?
- o próximo passo da enumeração dependia dessa resposta?
O problema pode aparecer como "transferência de controle USB falhou", mas a correção quase sempre mora em um pacote de setup de cinco campos.