Byte-niveau gennemgang af HID-rapportdeskriptoren, Usage Page-layout, boot- vs rapportprotokol samt OEM-tilpasningsregler for læsepenne.

Opslået den: aug. 16, 2024 - 25 Visninger

HID-rapportdeskriptor og Usage Page for læsepen: byte-niveau kortlægning for OID-tryk

Målgruppe: Indlejrede firmwareingeniører, OS-driverintegratorer og OEM-produktchefer, der har brug for at forstå, hvad hver byte i læsepenneens HID-rapportdeskriptor reelt betyder, hvorfor brugssiden er opdelt i en generisk desktop-side plus en vendordefineret side, og hvordan man udvider kortet uden at ødelægge de 230+ distributørkvalitetsdrivere, der allerede er i felten.

HID-rapportdeskriptoren er de mest afgørende 80 til 200 bytes firmware i en læsepen. Den er kontrakten mellem pennens MCU og hvert værtsoperativsystem, den nogensinde vil tale med: Windows 10/11, macOS 12/13/14, ChromeOS, Android 9 til 14, iPadOS 15 til 17 og Linux-kernen 5.15+. Får man deskriptoren forkert, skriver pennen forkerte tegn, ignorerer OID-trykket eller – værre – omdirigerer lyden lydløst til den forkerte sink. På tværs af vores 47.000+ leverede enheder har deskriptor-regressioner kostet flere debugging-timer end ethvert andet firmware-undersystem undtagen OCR-motoren.

Denne artikel gennemgår den kanoniske deskriptor fra TC-057 byte for byte, forklarer hvorfor hvert felt er sat som det er, og viser hvor en ODM-mærke sikkert kan udvide kortet, og hvor de ikke kan.

1. De tre lag i HID-kontrakten

En HID-rapportdeskriptor parses i tre logiske lag:

Lag Granularitet Formål Længde
Element Kort (1 byte) eller Lang (3 byte) Tag + størrelse + data Variabel
Lokal Defineret pr. element Usage, Usage Minimum/Maximum, Designator Variabel
Hoved Ombryder en række input/output/feature Collection, End Collection, Input, Output, Feature Variabel

Parseren er tilstandsbevidst. En Collection åbner et scope, og Input/Output/Feature-elementerne inden for dette scope beskriver en rapport. Deskriptoren behandles fra venstre mod højre, og hver byte skal være velformet. En enkelt misdannet byte får værten til at afvise hele deskriptoren.

Vores Q6/Q8-deskriptor er 92 bytes. F8-deskriptoren er 76 bytes. T2/Y6 (med fuld consumer-control-understøttelse til hovedtelefonafspilning) er 168 bytes. Deskriptorlængden er indkodet i HID-deskriptoren ved enumerationstidspunktet, og værten cacher den. Hvis du ændrer deskriptoren i en fremtidig firmware-revision, kan værten fortsætte med at bruge den cachelagrede version, hvilket er grunden til, at vi altid tvinger en USB-busnulstilling ved firmwareopdatering (se TC-075).

2. Element-tags som læsepennen bruger

HID-specifikationen definerer en tag-tabel; pennen bruger kun 12 af dem:

Tag Mnemoteknik Rolle Brugt i Q6/Q8
0x05 Usage Page Skifter side Ja (3 gange)
0x09 Usage Vælger én usage Ja (4 gange)
0x15 Logical Minimum Afgrænser et input/output Ja (3 gange)
0x25 Logical Maximum Afgrænser et input/output Ja (3 gange)
0x75 Report Size Bits pr. element Ja (3 gange)
0x95 Report Count Antal elementer Ja (3 gange)
0xA1 Collection Åbner scope Ja (2 gange)
0x81 Input Definerer et input-rapportfelt Ja (3 gange)
0x91 Output Definerer et output-rapportfelt Ja (1 gang)
0x19 Usage Minimum Åbn rækkevidde Ja (1 gang)
0x29 Usage Maximum Luk rækkevidde Ja (1 gang)
0xC0 Afslut samling Lukker scope Ja (2 gange)

Vi holder os bevidst inden for dette undersæt af 12 tags. HID-specifikationen tillader mange flere, men hvert ekstra tag øger risikoen for en OS-specifik mærkværdighed. For eksempel, den Padding (0x5A)-tagget Linux-kernens hid-core.c i visse Padding-sekvenser under suspend/resume.

3. De tre Usage Pages

Q6/Q8-deskriptoren bruger tre usage pages:

Usage Page Hex Formål
Generic Desktop 0x01 Tastatur, mus, systemkontroller
Consumer 0x0C Lydstyrke, play/pause, skift af nummer
Vendor Defined 0xFF00 OID-hændelsespayload (brugerdefineret brandudvidelse)

Generic Desktop-siden er den tastatursamling, vi leverer. Den erklærer en 1-byte modifier (8 bit, 1 byte rapportstørrelse, 8 rapportantal) og en 1-byte reserveret konstant (8 bit, 1 rapportstørrelse, 1 antal). Tilsammen udgør de boot-tastaturrapportens hoved.

Consumer-siden er den volumen op / volumen ned / play-pause-kontrol, vi leverer til hovedtelefonafspilning. Den er i alt 3 bit.

Vendor Defined-siden 0xFF00 er OID-hændelsespayloaden: 16 bytes pr. rapport, uden Report ID, i en Output-rapport, så værten også kan sende 16 bytes kontekst til pennen efter behov.

4. Bytekort for Q6/Q8-firmware 3.3.1

Nedenfor er den kanoniske deskriptor for Q6/Q8-platformen, byte-indekseret:

Byte Hex Betydning Hvorfor
0 0x05 Usage Page-tag (Global) Fortæller parseren, at vi skifter side
1 0x01 Side 0x01 (Generic Desktop) Åbner tastatur-scope
2 0x09 Usage-tag (Lokal) Vælger én usage
3 0x06 Tastatur Påkrævet til boot-protokol
4 0xA1 Collection-tag (Main) Åbner Application-collection
5 0x01 Application Application er standardindpakningen
6 0x05 Usage Page-tag
7 0x07 Keyboard-side Modifier-taster hører til her
8 0x19 Usage Minimum
9 0xE0 Venstre Control = 224 Modifier-område 224–231
10 0x29 Usage Maximum
11 0xE7 Højre GUI = 231 Afslutter modifier-området
12 0x15 Logical Minimum
13 0x00 0 Boolesk false
14 0x25 Logical Maximum
15 0x01 1 Boolesk true
16 0x75 Report Size
17 0x01 1 bit pr. element Modifier er et bitfield
18 0x95 Report Count
19 0x08 8 elementer Én bit pr. modifier
20 0x81 Input-tag (Main)
21 0x02 Data, Variabel, Absolut Standard boot-tastatur-modifikator
22 0x95 Rapportantal
23 0x01 1 element Reserveret byte
24 0x75 Rapportstørrelse
25 0x08 8 bit Én byte reserveret
26 0x81 Input-tag
27 0x03 Konstant, Variabel, Absolut Styresystemet forventer denne reserverede byte
28 0x05 Usage Page-tag
29 0x0C Forbrugerside Til medietaster
30 0x09 Anvendelse
31 0xE9 Lydstyrke op
32 0x09 Anvendelse
33 0xEA Lydstyrke ned
34 0x09 Anvendelse
35 0xCD Afspil/Pause
36 0x15 Logisk minimum
37 0x00 0
38 0x25 Logisk maksimum
39 0x01 1
40 0x75 Reportstørrelse
41 0x01 1 bit
42 0x95 Rapportantal
43 0x03 3 elementer 3 mediebits
44 0x81 Input-tag
45 0x02 Data, Variabel, Absolut
46 0xC0 End Collection Lukker tastatur-app
47 0x06 Usage Page-tag (udvidet) 2-byte usage page
48 0xFF, 0x00 Side 0xFF00 Leverandørdefineret
49 0x09 Brug
50 0x01 OID-hændelse Brugerdefineret brug
51 0xA1 Samling
52 0x01 Applikation
53 0x15 Logisk minimum
54 0x00 0
55 0x26 Logisk maksimum (udvidet) 2-byte logisk max
56 0xFF, 0x00 255
57 0x75 Report Size
58 0x08 8 bits
59 0x95 Report Count
60 0x10 16 elementer 16-byte OID-nyttelast
61 0x09 Usage
62 0x02 OID-nyttelast
63 0x91 Output-tag
64 0x02 Data, Variable, Absolute
65 0xC0 End Collection Lukker vendor-samlingen

De resterende bytes (66 til 91) på Q6/Q8 er polstring for bytejustering samt en Feature-rapport for brand-ID. På F8 fjernes bytes fra 47 og frem, og deskriptoren stopper ved byte 46.

5. Boot-protokol vs. Report-protokol

Læsepennen eksponerer en Protocol Mode-karakteristik (UUID 0x2A4E på BLE, bInterfaceProtocol-byte på USB). To protokoller er gyldige:

Protokol Rapportlayout Bruges når
Boot 8-byte fast (modifikator + reserveret + 6 keycodes) BIOS, gendannelse, tidlig boot
Report Deskriptordefineret Normal OS-brug

På Q6/Q8-firmware 3.3.1 er standarden Report Protocol. Værten kan anmode om Boot Protocol ved at skrive 0x00 til Protocol Mode-karakteristikken, hvilket vores firmware honorerer ved at kollapse den 16-byte OID-rapport til 8-byte boot-formatet. Vi mister ingen data; OID-side-ID'et og koden foldes blot ind i keycode-bytes.

For et skoleprogram på 12.000 enheder anbefalede vi, at Boot Protocol aktiveres som standard, fordi skolens bærbare computere kører et låst Windows-image, hvor den standard HID-driverstak indlæses på 1,4 s mod 4,8 s for den fulde Report Protocol-parser. Latensbesparelsen er meningsfuld, når 30 børn koldstarter systemet ved begyndelsen af timen.

6. Vendor-defineret side 0xFF00: Hvorfor vi reserverede den

Vi reserverede 0xFF00 i USB-IF's vendor-liste tilbage i 2022. Reservationen giver os juridisk autoritet til at definere alle usage-ID'er fra 0x01 til 0xFFFF på den side, og enhver tredjepart, der vilinteropere med vores penne, skal forhandle et usage-ID-område med os. ODM-kunden får et delområde på 32 usages allokeret til deres brand-ID. De første 8 af disse 32 er reserveret til vores interne brug, hvilket efterlader 24 usages til brandet.

Sådan kan den samme Q6/Q8-firmware leveres til 230+ distributører uden at deres app ved et uheld taler med en anden distributørs pen.

7. Layoutet for OID-rapporten

Den 16-byte OID-nyttelastrapport er opbygget som følger:

Byte Felt Kodning Område
0–3 Side-ID uint32 LE 0 til 4.294.967.295
4–7 OID-kode uint32 LE 0 til 4.294.967.295
8 Sprog uint8 0–255 (se sprogpakke)
9–10 Sekvens uint16 LE 0–65.535
11–12 Opholdstid (ms) uint16 LE 0–65.535
13 Flag uint8 bitmaske bit 0 = gentag, bit 1 = lyd optaget
14–15 Reserveret uint16 LE 0

Flag-byten er den eneste, et kundemærke må omdefinere. Vi allokerer bit 2–7 til brandspecifikke flag (f.eks. "testtilstand", "diagnostik", "kvalitetskontrol på fabrikken"). Bit 0–1 er reserveret til vores firmware.

8. Feature-rapporten (Brand ID)

En 4-byte Feature-rapport i slutningen af deskriptoren indeholder et Brand ID. Feature-rapporten er skrivebeskyttet fra værten og indstilles under fabrikkens klargøring. Den tjener to formål:

  1. Ledsager-appen læser Brand ID for at bestemme, hvilket indholdskatalog der skal indlæses.
  2. QA-stationen læser Brand ID for at verificere firmware-loadets integritet.
0x09, 0x03,        // Usage (Brand ID)
0x15, 0x00,        // Logical Minimum 0
0x26, 0xFF, 0x00,  // Logical Maximum 255
0x75, 0x08,        // Report Size 8
0x95, 0x04,        // Report Count 4
0xB1, 0x02,        // Feature (Data, Variable, Absolute)

Den første byte er brand-indekset (vi har aktuelt 38 brand-indekser tildelt), den anden er en regionskode (1=EU, 2=US, 3=APAC, 4=MENA, 5=LATAM, 6=SSA), den tredje er en indholdsrevision (0–255), og den fjerde er en CRC over de første tre.

9. Sådan kortlægges deskriptoren til GATT

Når pennen er på BLE, serveres de samme deskriptorbytes af karakteristikken 0x2A4B (Report Descriptor). Selve rapporten sendes på karakteristikken 0x2A4D via notifikationer. Protocol Mode ligger på 0x2A4E. Brand ID Feature-rapporten eksponeres på en vendor-defineret karakteristik 0x9F01 (skrivebeskyttet) på den samme HID-tjeneste.

USB HID-element GATT-karakteristik-UUID Egenskaber
Rapportdeskriptor 0x2A4B Læs
Rapport 0x2A4D Notificer, Skriv, SkrivUdenSvar
Protokoltilstand 0x2A4E Læs, Skriv
Brand ID 0x9F01 (custom) Læs
HID-information 0x2A4A Læs

Dette er GATT-tabellen dokumenteret i TC-060.

10. Valideringspakke vi kører på hvert deskriptorbuild

Før en deskriptor sendes af sted, skal den bestå:

Kontrol Værktøj Godkendelseskriterium
Parse-konformitet USB-IF HID-deskriptorviser 0 fejl, 0 advarsler
Boot-protokol bootbarhed USBlyzer Ændrer boot-rapport med succes
OS-enumeration Windows 10/11 Enhedshåndtering Vises som HID Keyboard + HID Vendor Device
Parring med iPadOS iPad 9. generation, iPadOS 17 Parres og læser descriptor
ChromeOS-registrering Lenovo Chromebook 14 Vises som inputenhed
macOS-registrering MacBook Air M1 System Information viser alle 3 interfaces
Android-registrering Pixel 7a, Android 14 InputDeviceManager rapporterer keyboard + vendor

Hvis bare én af disse fejler, afvises descriptoren, og firmware-buildet tilbageholdes. På tværs af 86 firmware-udgivelser siden 2023 er 6 blevet afvist ved denne gate og rullet tilbage. Den mest almindelige årsag er et Usage Page-tag med forkert extended-length-kodning, som fejler macOS-kontrollen men består i Windows.

11. Almindelige fejl kunder begår

Når en ODM-kunde kommer med sit eget descriptor-udkast, er tre fejl skyld i ~80 % af afvisningerne:

  1. Den reserverede byte efter modifieren springes over. macOS forventer præcis 9 bytes boot keyboard-rapport (8 modifier + 1 reserveret + 6 keycode). Kunder komprimerer det ofte til 8 bytes, hvilket bryder boot-protokollen på Mac.
  2. Brug af Logical Maximum 0x00FF uden det udvidede tag (0x26). Den korte form 0x25 0xFF virker for værdier op til 127. For værdier op til 255 er det udvidede tag obligatorisk. Kunder glemmer det, og descriptoren afkortes lydløst på Linux.
  3. En Input-rapport erklæres inde i en Output-collection. HID-parseren håndhæver ikke en streng Output-only-collection, men det gør nogle OS-drivere. Vi erklærer altid Output i OID-collectionen for at gøre symmetrien eksplicit.

12. Performancebudget

På host-siden parses descriptoren én gang ved registrering. På enhedssiden rører hver rapport-samling descriptor-mappet. Vores interne benchmark på Q6/Q8 firmware 3.3.1:

Operation Cyklusser Tid ved 64 MHz
Slå Usage Page op 8 125 ns
Slå Usage ID op 12 188 ns
Saml 16-byte OID-rapport 240 3,75 µs
Send rapport på USB EP1 IN 320 5,0 µs
Send rapport på BLE 0x2A4D 1.840 28,75 µs
Total pr. tryk (USB) 580 9,1 µs
Total pr. tryk (BLE) 2.100 32,8 µs

9,1 µs USB-tallet er det, der gør den 6,4 ms end-to-end-latens mulig. BLE-tallet er den dominerende komponent i 32 ms BLE-latensen.

Descriptor Build Time (ms)

13. Det større billede

Hvis du evaluerer en pen, der ikke offentliggør sin HID-rapport-descriptor åbent, er det det første, du bør bede om. En leverandør, der nægter at dele descriptoren, skjuler enten manglende overholdelse eller bygger på en ikke-HID-stack, der kræver driverarbejde på din side. Vores descriptor til Q6/Q8 firmware 3.3.1 er 92 bytes, og vi udgiver den under NDA til kvalificerede ODM-kunder på anmodning.

15. Relateret læsning


Anmod om et tilbud — få et hurtigt svar fra fabrikken

Frequently Asked Questions

Kan vi erstatte Usage Page 0xFF00 med vores eget sidenummer?
Ja, men du skal registrere en vendor usage page hos USB-IF mod et engangsgebyr på 2.000 USD og med en leveringstid på 6 uger. Vi leverer med 0xFF00, fordi den allerede er registreret til os. Brands, der bruger 0xFF00, overtager den kontrakt, som vores eksisterende 230+ distributør-apps allerede taler.
Hvorfor er descriptor 92 bytes på Q6\/Q8 og 76 bytes på F8?
Q6\/Q8 tilføjer en 4-byte Feature-rapport for Brand ID og en 12-byte Output-collection for OID-payload, hvilket bringer descriptor op på 92 bytes. F8 er kun BLE og leveres uden Brand ID Feature-rapporten, så dens descriptor er 76 bytes.
Ændrer descriptor sig mellem firmware-revisioner?
Nej, descriptor er frosset i hele platformens levetid. På tværs af 86 firmware-udgivelser siden 2023 er Q6\/Q8-descriptor ikke ændret. Hvis der er behov for et nyt felt, sender vi en ny platform (f.eks. T2/Y6) i stedet.
Hvad sker der, hvis værten cacher en forældet descriptor?
På Windows ligger cachen i registreringsdatabasen under HIDClass og ugyldiggøres ved en USB-busnulstilling. Vi gennemtvinger en busnulstilling ved hver firmwareopdatering via en 2-sekunders USB-suspend\/resume-cyklus, som rydder værtscachen.
Kan vores brand-app udvide OID-payload ud over 16 bytes?
Ikke uden at bryde kontrakten. Det 16-byte layout er låst. Hvis du har brug for mere, leverer vi en anden vendor-collection med Report ID 2, der bærer en 32-byte udvidet payload, men det kræver en SDK-opgradering af appen og er forbeholdt premium-brandniveauer.
Din indkøbskurv
Din oplevelse på dette websted forbedres ved at tillade cookies. Cookiepolitik
Chat on WhatsApp