Programmeren van eenvoudige USB-apparaten in Delphi. Boek: USB-interface (praktijk van gebruik en programmeren) HID-apparaten programmeren op “topniveau”

Programmering via USB-poort

Het programmeren van het SF-50-afstemapparaat voor satellietantennes via de USB-poort verschilt alleen van programmeren via de RS-232-poort in de manier waarop gegevens worden overgedragen van het apparaat naar de computer en van de computer naar het apparaat. Bij het programmeren via USB wordt een draagbare USB-drive (flashdrive) gebruikt. Dit is handig wanneer bijvoorbeeld uw computer of, vaker nog, een laptop (netbook) geen seriële RS-232-poort op het chassis heeft.
Om het apparaat te programmeren met behulp van een USB-stick heeft u het volgende nodig:
- USB-drive (flashdrive) geformatteerd in het FAT-32-bestandssysteem;
- AliEditor-editorprogramma, gelegen in de map Database_editor_new van het softwaregedeelte van het OPENBOX SF-50-apparaat.

Voordat u gaat programmeren, moet u de database van het apparaat naar uw computer overbrengen. Om dit te doen, schakelt u het apparaat in en sluit u een USB-stick aan op de USB-poort. Uitvoeren MENU – Systeem – Opslaan op USB,

Verlaat het menu door op de MENU-knop te drukken totdat het huidige kanaal verschijnt, of totdat het hoofdmenubeeld verschijnt als er nog geen kanalen zijn en verwijder de flashdrive. Plaats de flashdrive in de computer.
Voer het Editor.exe-programma uit vanuit de map Database_editor_new en open de afbeelding op de flashdrive daarin.

Wanneer u wordt gevraagd een database te selecteren, selecteert u Gebruikersdatabase.

Klik op OK. Selecteer Alle services. Er wordt een lijst geopend met alle gescande en opgeslagen tv-, radio- en servicekanalen die beschikbaar zijn in de database.

Bewerk kanalen naar wens, laat bijvoorbeeld alleen open kanalen achter.
Houd op het toetsenbord van uw computer de Shift-knop ingedrukt, druk op de pijl-omlaag en markeer de kanalen die u wilt verwijderen. Klik op Verwijderen om de geselecteerde te verwijderen.

Om de satellietinstellingen te bewerken, selecteert u Alle diensten – Satellietinformatie – EUTELSAT W4, W7 en drukt u op de ENTER-knop.

Bewerk indien nodig de waarden in Antenne 1.
Om een ​​transponder te verwijderen, gaat u op de onnodige transponder staan ​​en drukt u op de knop Verwijderen op het toetsenbord van de computer. Bevestig de geselecteerde actie.

Om een ​​transponder toe te voegen, klikt u op de naam van de satelliet, klikt u met de rechtermuisknop en selecteert u Informatie toevoegen (of markeer de satelliet en druk op de knop Invoegen op het toetsenbord).

Voer de gegevens voor de nieuwe transponder in, bijvoorbeeld van de website lyngsat.com.

Klik op OK en zorg ervoor dat de transponder is geregistreerd.

Om een ​​satelliet toe te voegen, gaat u naar de regel Satellietinformatie, drukt u op de Insert-toets op het toetsenbord en voert u de parameters van de nieuwe satelliet in.

sluit het editorprogramma en verwijder de schijf.
Plaats de schijf in het OPENBOX SF-50-apparaat, volg de volgorde MENU – Systeem – Update vanaf USB, selecteer de modus “SAT&TP List”.

Selecteer Beginnen. Bevestig uw bedoelingen.

Het apparaat zal de database bijwerken en zichzelf opnieuw opstarten. Na het opnieuw opstarten moet u de menutaal op een nieuwe manier instellen op Russisch. Reset het apparaat naar de fabrieksinstellingen.
Verlaat het instellingenmenu door tweemaal op de MENU-knop te drukken. Druk op de OK-knop op de huidige zender en zorg ervoor dat de zenderlijst is bewerkt.

U kunt er ook voor zorgen dat de lijst met transponders en satellieten wordt bewerkt.
Het programmeren is voltooid.


Afb. 1 Illustratie van de werking van een Android-apparaat in de USB Host- en Accessory-modi (afbeelding van de site http://developer.android.com)

Houd er rekening mee dat het gebruik van USB niet de enige manier is om met hetzelfde zelfgemaakte apparaat te communiceren. Met Android kunt u ook NFC, Wi-Fi P2P, SIP en een standaard netwerkverbinding gebruiken. De ontwikkelaar heeft dus voldoende mogelijkheden in zijn arsenaal om zijn wildste ideeën te verwezenlijken.

Een andere veel voorkomende optie voor communicatie met verschillende apparaten is nog steeds het gebruik van een USB-COM-adapter. Er is materiaal op internet over het gebruik van een USB-COM-adapter in Android - zie bijvoorbeeld. De populariteit van deze verbinding is te danken aan de aanwezigheid van een groot aantal apparaten die al zijn ontwikkeld met behulp van verschillende microcontrollers, waarvan de communicatie wordt uitgevoerd via een COM-poort (seriële poort), wat 10 jaar geleden een vrijwel standaard manier was om gegevens over te dragen van een computer tot een zelfgemaakt stuk hardware.

Vergeleken met een COM-poort kan het gebruik van USB de gegevensoverdrachtsnelheid aanzienlijk verhogen en dit proces gebruiksvriendelijker maken. Overdrachtssnelheid, die zelfs bij apparaten met lage snelheid (toetsenborden, muizen, joysticks) 10-1500 Kbps bedraagt, eenvoud en lage kosten van het bekabelingssysteem en verbindingen, zelfidentificatie van apparaten met automatische configuratie, verbergen van details van de elektrische aansluiting van de eindgebruiker (plus de mogelijkheid om de kabel los te koppelen zonder de apparaten uit te schakelen), foutcontrole en hun herstel op protocolniveau - dit zijn de onmiskenbare voordelen van deze technologie (zie p. 12).

Als we het over het gebruik van USB voor gegevensoverdracht hebben, zou het in het algemeen nuttig zijn om het boek van P. Agurov “USB Interface” te noemen. Hoewel het op internet vaak wordt bekritiseerd en voor het laatst in 2006 werd uitgebracht, heeft het meer dan eens geholpen bij het vinden van de juiste oplossing bij het zoeken naar informatie over verschillende aspecten van de toepassing van deze technologie. Het boek behandelt kwesties van het kiezen van een microcircuit en circuitontwerp voor de controller tot het schrijven van een microcontrollerprogramma en voorbeelden van het programmeren van gegevensoverdracht via het USB-protocol vanaf de computer. Het is onmogelijk om niet de "primaire bron" van gegevens over dit onderwerp aan te geven - de website van de non-profitorganisatie USB IF (USB Implementers Forum), die specificaties voor deze interface ontwikkelt -, hoewel dit materiaal in het Engels is. Daar vindt u echter uitgebreide informatie over het USB-interfaceapparaat. Er is een goede vertaling van delen van de specificatie - . Degenen die geïnteresseerd zijn in softwareoplossingen van de kant van de microcontroller kunnen de link ook zien.

Dit artikel is in de eerste plaats bedoeld voor degenen die een elektronisch apparaat hebben (onafhankelijk of door iemand anders ontwikkeld), waarvan het gegevensuitwisselingsprotocol bekend is (er is bijvoorbeeld al een programma dat met dit apparaat werkt in Windows/Linux) en Ik zou graag een programma willen hebben dat ermee werkt in Android.

Iets over USB-apparaatklassen

Opgemerkt moet worden dat de ontwikkeling van software voor communicatie met een specifiek apparaat sterk afhankelijk is van de implementatie ervan op microcontrollerniveau. Om voor de hand liggende redenen is het onmogelijk om voorbeelden van communicatieprogramma's voor alle soorten USB-apparaten in één artikel te geven (de eerste informatie over het programmeren van verschillende soorten apparaten is te vinden in). We zullen ons echter beperken tot het presenteren van code die het zoeken naar apparaten en toegang tot de controlepunten voor informatie-uitwisseling implementeert. We zullen ook het verzenden van gegevens analyseren met behulp van het voorbeeld van een van de typen USB-apparaten, namelijk de HID-apparatenklasse (human interface device). Deze klasse omvat "langzame" apparaten zoals een toetsenbord, muis, joystick, en er zijn tal van voorbeelden van de implementatie ervan met behulp van verschillende microcontrollers op het netwerk (die zijn er bijvoorbeeld in).

Waarom is de HID-klasse zo populair bij fabrikanten van verschillende zelfgemaakte apparaten? Om Wikipedia te citeren: “Naast gedetailleerde specificaties van klassieke invoerapparaten (zoals toetsenborden en muizen), definieert de HID-standaard een speciale klasse apparaten zonder gedetailleerde specificaties. Deze klasse wordt USB HID Consumer Control genoemd en is in wezen een ongereguleerd communicatiekanaal met een apparaat. In dit geval gebruikt het apparaat dezelfde standaardstuurprogramma's voor het besturingssysteem als een muis en toetsenbord. Het is dus mogelijk om een ​​USB-apparaat te maken waarvoor geen speciale stuurprogramma's nodig zijn in de meeste gangbare computerbesturingssystemen." Rest alleen nog toe te voegen dat deze specificatie ook werkt in het Android-besturingssysteem (exclusief CyanogenMod-firmware).

Een van de opties voor het uitwisselen van gegevens met een HID-apparaat is interrupt-overdracht, die wordt gebruikt wanneer het nodig is om kleine datapakketten over te dragen (de maximale pakketgrootte is afhankelijk van de overdrachtssnelheid en varieert van 64 tot 1024 bytes) na een bepaald tijdsinterval . Het pakket voor verzending wordt een rapport genoemd (Engels - rapport, zie pp. 71, 95). Deze lengte van een rapport is meestal voldoende om informatie uit te wisselen met een zelfgemaakt apparaat; 64 bytes aan informatie in één pakket is bijvoorbeeld behoorlijk veel voor een controller, omdat 1 bit aan informatie voldoende is om de toestanden van een LED over te brengen. of een eenvoudige sensor.

Vereiste hulpmiddelen

We hebben dus een tablet of telefoon nodig met Android-versie niet lager dan 3.1. Hierbij dient te worden opgemerkt dat bovenstaande USB Host API niet volledig op alle mobiele apparaten is geïmplementeerd (dit staat ook vermeld op de website developer.android.com, zie link). Bij sommige tablets/telefoons wordt de USB-connector alleen gebruikt voor het opladen en communiceren met een pc. Opnieuw verwijs ik de lezer naar de lijst met mobiele apparaten die wel of niet geschikt zijn voor onze experimenten (zie).

Je hebt ook een soort USB-apparaat nodig (voor de eerste experimenten is een gewone USB-stick voldoende), een OTG-adapter (On-The-Go - zie figuur 2) en/of een USB-kabel voor communicatie met de apparaat. Wikipedia zegt over OTG: “Bij aansluiting via USB OTG wordt de rang van het apparaat (master of slave) bepaald door de aan- of afwezigheid van een jumper tussen pin 4 en 5 in de aansluitkabelstekker. Bij een USB OTG-kabel wordt een dergelijke jumper alleen in een van de twee connectoren geïnstalleerd (zie). Daarom hebben we zo'n jumper aan de zijkant van het mobiele apparaat nodig.


Fig.2 Verschillen in het circuit van een gewone USB-kabel en een OTG-kabel (foto van http://tech.firstpost.com)

Zo’n OTG-kabel voor je toestel kun je zelf solderen. Om dit te doen, moet je een geschikte connector kopen in een radiowinkel, en de auteur heeft bijvoorbeeld een oude kabel van een draagbare harde schijf gebruikt:

Het USB Device Info-programma dat is geïnstalleerd vanuit de Google Play Market-opslag zal ook een goede hulp zijn bij uw werk. Het programma kan apparaten detecteren die zijn aangesloten op de USB-connector van een tablet/telefoon met behulp van zowel de Java API als de Linux-kernel. Dat wil zeggen, als uw apparaat niet wordt gedetecteerd met behulp van de Java USB Host API in USB Device Info, dan zal het hoogstwaarschijnlijk tevergeefs zijn om (inclusief uw eigen) Android-programma te gebruiken dat met Java is geschreven voor dit mobiele apparaat en USB Host API.

Soms is de informatie die wordt geproduceerd door de opdracht lsusb van het Linux-besturingssysteem ook erg nuttig. Met de schakelaars -v en -d geeft lsusb alles, of bijna alles, weer over een USB-apparaat dat een softwareontwikkelaar nodig heeft voor apparaten van deze klasse (zie figuur 3).


Fig.3 Voorbeelduitvoer van lsusb- en lsusb -v -d-opdrachten

Vervolgens heb je een computer nodig waarop de Android SDK is geïnstalleerd en de Eclipse geïntegreerde ontwikkelomgeving (IDE) met de ADT-plug-in (hoewel je ook met alleen de SDK kunt rondkomen). U kunt zien hoe u een applicatie voor Android kunt maken en installeren, bijvoorbeeld in of op internet.

En je hebt natuurlijk op zijn minst de wens nodig om resultaten te bereiken, zonder dat kun je niet! Ik merk op dat het de auteur weken van nauwgezet zoeken naar informatie kostte om enkele technische problemen met betrekking tot het gebruik van USB in Android op te helderen.

Java-klassen voor het werken met USB in Android API

Dus, zoals ze zeggen op de website van de ontwikkelaars van de USB Host API voor Android (zie) - "voordat je begint, is het belangrijk om te begrijpen welke klassen je in je werk gaat gebruiken." Tabel 1 geeft een beschrijving van de belangrijkste klassen voor het werken met de USB Host API (een poging om informatie van http://developer.android.com te vertalen).

Tabel 1. Beschrijving van klassen voor het werken met USB in Android

Naam van de klas Beschrijving
USB-manager Hiermee kunt u aangesloten USB-apparaten opsommen en ermee communiceren.
Hiermee kunt u een aangesloten USB-apparaat detecteren en er gegevens mee uitwisselen.
USB-apparaat Vertegenwoordigt een aangesloten USB-apparaat en bevat methoden om toegang te krijgen tot de identificerende informatie, interfaces en eindpunten.
Vertegenwoordigt een aangesloten USB-apparaat en bevat methoden voor toegang tot de identiteit, interfaces en eindpunten ervan.
USB-interface Vertegenwoordigt een interface van een USB-apparaat, die een reeks functionaliteiten voor het apparaat definieert. Een apparaat kan een of meer interfaces hebben waarop kan worden gecommuniceerd.
Vertegenwoordigt de "interface" van een USB-apparaat, die de reeks functies voor dat apparaat definieert. Eén apparaat kan een of meer interfaces hebben voor informatie-uitwisseling.
USB-eindpunt Vertegenwoordigt een interface-eindpunt, dat een communicatiekanaal voor deze interface is. Een interface kan een of meer eindpunten hebben en heeft doorgaans invoer- en uitvoereindpunten voor tweerichtingscommunicatie met het apparaat.
Vertegenwoordigt het "eindpunt" van een interface, het communicatiekanaal voor die interface. Een interface kan een of meer eindpunten hebben, en heeft doorgaans eindpunten voor het ontvangen en verzenden van informatie.
USB-apparaatverbinding Vertegenwoordigt een verbinding met het apparaat, die gegevens over eindpunten overdraagt. Met deze klasse kunt u gegevens synchroon of asynchroon heen en weer sturen.
Vertegenwoordigt een "verbinding" met een bepaald apparaat. Vereist om gegevens naar het eindpunt over te dragen. Met deze klasse kunt u gegevens synchroon of asynchroon ontvangen of verzenden.
USBVerzoek Vertegenwoordigt een asynchrone aanvraag om te communiceren met een apparaat via een USBDeviceConnection.
Vertegenwoordigt een asynchrone aanvraag om te communiceren met een apparaat via een USBDeviceConnection.
USB-constanten Definieert USB-constanten die overeenkomen met definities in linux/usb/ch9.h van de Linux-kernel.
Definieert constanten die overeenkomen met de definities in linux/usb/ch9.h van de Linux-kernel.

In bijna alle gevallen waarin de USB Host API wordt gebruikt, gebruikt de programmeur deze klassen in zijn werk. Het algoritme voor hun gebruik ziet er ongeveer zo uit: we definiëren apparaten (het doel is programmatische toegang tot de USBDevice-klasse) die zijn verbonden met de host (mobiel apparaat) met behulp van UsbManager. Wanneer softwaretoegang tot een apparaat wordt verkregen, is het noodzakelijk om de juiste UsbInterface en UsbEndpoint te bepalen om ermee te communiceren. Zodra u het eindpunt in uw bezit heeft, opent u UsbDeviceConnection om met het USB-apparaat te communiceren. Als het eindpunt in de asynchrone overdrachtsmodus werkt, gebruiken we de klasse UsbRequest.

Laten we proberen dit allemaal uit te zoeken door een eenvoudige applicatie te maken die, met behulp van deze API, een apparaat detecteert dat is verbonden met de host met Android OS en wat informatie daarover weergeeft op het scherm van een telefoon of tablet.

Maak een project

In Eclipse wordt een project gemaakt met behulp van de menu-items Bestand->Nieuw->Android-applicatieproject. Merk ook op dat de onderstaande code is ontleend aan voorbeeldapplicaties die bij de Android SDK zijn geleverd (map android sdk samples/android-N(API Level)/USB). We hebben het over het Missile Launcher USB-speelgoedbesturingsprogramma (zie figuur 4). applicaties worden gedownload via Android SDK Manager (vink het vakje aan - Voorbeelden voor SDK). In de onderstaande lijsten worden de codevoorbeelden voorzien van commentaar waarin wordt uitgelegd wat er gebeurt.


Afb.4 Leuk speelgoed "Raketwerper"

Wanneer u een project aanmaakt, vergeet dan niet het vereiste API-niveau aan te vinken in de Minimum Requared SDK-optie (API-niveau 12, overeenkomend met Android-versie 3.1 /Honeycomb/, of hoger). Het project zal een zeer eenvoudige gebruikersinterface hebben: het hoofdvenster (Activiteit) en TextView voor het weergeven van informatie. Een soortgelijk project wordt uitgebreid besproken in.

In de automatisch aangemaakte klasse voor de activiteit van ons project is het noodzakelijk om de volgende instanties van klassen te definiëren voor het werken met USB:

privé TextView lgView;
privé USBManager mUsbManager;
privé USB-apparaat mApparaat;
privé USBDeviceConnection mConnection;
privé UsbEndpoint mEndpointIntr;

LgView = (TextView) findViewById(R.id .logTextView ) ;

en krijg toegang tot de klasse UsbManager

MUsbManager = (UsbManager) getSystemService(Context .USB_SERVICE );

Laten we ook een gebeurtenishandler onResume() maken. Laten we het doel bereiken: zodat informatie over verbonden apparaten wordt bijgewerkt wanneer ons toepassingsvenster wordt geactiveerd (zie Lijst 1).

Lijst 1. OnResume() gebeurtenishandler

publieke leegte opResume() (
super.onResume();

//vul de container met een lijst met apparaten
HashMap< String , UsbDevice>deviceList = mUsbManager.getDeviceList();
Iterator< UsbDevice>deviceIterator = deviceList.values().iterator();

lgView.setText("Aantal apparaten:" + deviceList.size());

while (deviceIterator.hasNext()) (
UsbDevice-apparaat = (UsbDevice) deviceIterator.next () ;

//voorbeeld van het bepalen van de ProductID van een apparaat
\N"+ "Apparaatproduct-ID: " + device.getProductId());
}
// definieer de intentie beschreven in het filter
// bedoeling AndroidManifest.xml
Intentie intentie = getIntent() ;
lgView.setText (lgView.getText() + " \N"+ "intentie: " + intentie);
Tekenreeksactie = intent.getAction();

//Als het apparaat is aangesloten, geeft u de link door aan
//naar de setDevice() functie
UsbDevice-apparaat = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) ;
if (UsbManager.ACTION_USB_DEVICE_ATTACHED .is gelijk aan (actie) ) (
setApparaat(apparaat) ;
lgView.setText (lgView.getText() + " \N" + "UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(actie) is WAAR") ;
) else if (UsbManager.ACTION_USB_DEVICE_DETACHED .is gelijk aan (actie) ) (
if (mDevice != null && mDevice.equals (apparaat) ) (
setDevice(null) ;
lgView.setText (lgView.getText() + " \N" + "UsbManager.ACTION_USB_DEVICE_DETACHED.equals(actie) is WAAR") ;
}
}

Vervolgens maken we de functie setDevice() voor de activiteit, die nodig is om met ons apparaat te werken (zie Lijst 2). In de onResume()-handler en in de setDevice()-functie hebben we exact het algoritme gevolgd voor het gebruik van de USB Host API zoals beschreven in de vorige sectie.

Lijst 2. setDevice()-functie

private void setDevice(UsbDevice-apparaat) (
lgView.setText (lgView.getText() + " \N"+ "setApparaat" + apparaat);

// bepaal beschikbare apparaatinterfaces
als (device.getInterfaceCount() != 1 ) (

LgView.setText(lgView.getText()+" \N"+ "kon interface niet vinden" );
opbrengst ;
}
UsbInterface intf = apparaat.getInterface(0);

// definieer apparaateindpunten
als (intf.getEndpointCount() == 0 ) (

LgView.setText(lgView.getText()+" \N"+ "kon eindpunt niet vinden" );
opbrengst ;
) anders (
lgView.setText (lgView.getText() + " \N"+ "Aantal eindpunten: " + intf.getEndpointCount () );
}

UsbEndpoint epIN = null;
UsbEndpoint epOUT = null;

//zoek naar eindpunten om via interrupts te verzenden
voor (int ik = 0; ik< intf.getEndpointCount () ; i++ ) {
if (intf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_INT) (
if (intf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) (
epIN = intf.getEndpoint(i) ;
lgView.setText (lgView.getText() + " \N"+ "IN-eindpunt: " + intf.getEndpoint (i) );
}
anders(
epOUT = intf.getEndpoint(i) ;
lgView.setText (lgView.getText() + " \N"+ "OUT-eindpunt: " + intf.getEndpoint (i) );
}
) anders ( lgView.setText ( lgView.getText() + " \N" + "geen eindpunten voor INTERRUPT_TRANSFER") ; }
}

MApparaat = apparaat;
mEndpointIntr = epOUT;

//open het apparaat voor gegevensoverdracht
if (apparaat != nul ) (
UsbDeviceConnection-verbinding = mUsbManager.openDevice (apparaat) ;
if (verbinding != nul && verbinding.claimInterface (intf, true ) ) (

LgView.setText(lgView.getText()+" \N"+ "open apparaat SUCCES!" );
mVerbinding = verbinding;

) anders (

LgView.setText(lgView.getText()+" \N"+ "open apparaat FOUT!" );
mVerbinding = nul;
}
}
}
}

Naast de bovenstaande code, die, zoals de oplettende lezer waarschijnlijk al geraden heeft, het apparaat opent voor het ontvangen en verzenden van gegevens, hoeft u alleen nog maar het gegevensuitwisselingsprotocol te gebruiken, dat, ik herhaal, goed bekend zou moeten zijn bij de ontwikkelaar. We zullen alleen, zoals beloofd, de code presenteren die een bepaald berichtdatapakket naar het HID-apparaat verzendt met behulp van interrupttransmissie, de UsbRequest-klasse en het bijbehorende eindpunt - zie Listing 3.

Lijst 3. Voorbeeldcode voor het verzenden van gegevens naar een apparaat

//de grootte bepalen van de te verzenden buffer
//gebaseerd op de maximale pakketgrootte
int bufferDataLength = mEndpointIntr.getMaxPacketSize () ;

lgView.setText (lgView.getText() + " \N"+ mEndpointIntr.getMaxPacketSize());

ByteBuffer-buffer = ByteBuffer.allocate (bufferDataLength + 1);

UsbRequest-verzoek = nieuw UsbRequest() ;

buffer.put(bericht);

request.initialize(mConnection, mEndpointIntr) ;

request.queue(buffer, bufferDataLength) ;

if (request.equals(mConnection.requestWait()) )

//verzenden is gelukt
//lgView.setText(lgView.getText() + "\n" + "CLEAR verzenden!!!");

vangst (uitzondering ex)

//Er is iets mis...
//lgView.setText(lgView.getText() + "\n" + "verzenden niet duidelijk...");

Apparaatfiltering in AndroidManifest.xml

Hoewel onze applicatie niet hoeft te zoeken naar een specifiek apparaat met een bekende VID (Vendor-ID) en PID (Product-ID), geven de technici van Google geen voorbeelden van applicaties zonder een intent-filtergedeelte in het manifestbestand. De auteur kon het programma niet laten werken zonder apparaten in AndroidManifest.xml te filteren.

Ik wil u eraan herinneren dat Vendor-ID en Product-ID unieke identificatiegegevens van USB-apparaten zijn. Dat wil zeggen dat u met behulp van filtering een applicatie kunt maken die alleen communiceert met een bepaald apparaat of een bepaalde klasse apparaten. Houd er rekening mee dat apparaatfabrikanten deze cijfers moeten overeenkomen met de USB IF-organisatie.

Een applicatie waarvan het manifestbestand wordt weergegeven in Lijst 4 en waarvan het filterconditiebestand zich in Lijst 5 bevindt, herkent bijvoorbeeld met succes USB-flashstations die zijn aangesloten op een mobiel apparaat, maar herkent het toetsenbord en de muis niet die de auteur heeft. Deze applicatie kan samen met de broncode worden gedownload via de link.

Lijst 4. AndroidManifest.xml-bestand


" > http://schemas.android.com/apk/res/android"
> package="ru.learn2prog.usbhostvoorbeeld"
android:versieCode = "1"
android:versionName="1.0" >


android:minSdkVersion = "12"
android:targetSdkVersion = "14" />


android:allowBackup = "waar"
android:icon="@drawable/ic_launcher"
android:label="@string/app_naam"
android:theme="@style/AppTheme" >

androïde:naam= "ru.learn2prog.usbhovoorbeeld.Hoofdactiviteit"
android:label="@string/app_name" >
>

"android.intent.categorie.DEFAULT" />

"android.intent.category.LAUNCHER" />

>

>

>
"android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
>
>

>

Lijst 5. Filterbestand device_filter.xml (map/res/xml)

>

>

De handelingen voor het samenstellen en installeren van onze applicatie verschillen niet van de gewone (zie voorbeelden in,). Ik zou graag uw aandacht willen vestigen op de acties van het intentiefilter: wanneer een apparaat is verbonden met de host, vraagt ​​het besturingssysteem de gebruiker om onze applicatie te starten.

Literatuur/Referenties: 11.
12.
13. http://developer.android.com/guide/topics/connectivity/usb/host.html - overzicht van de klassen die nodig zijn om met USB in Android te werken
14. link naar applicatiebronnen

Maar het is niet voldoende om het apparaat alleen fysiek op de computer aan te sluiten; u moet ook gegevensuitwisseling tussen de apparaten tot stand brengen. Hoe kies je een poort en organiseer je een verbinding? Een paar jaar geleden was de standaardoplossing het gebruik van een COM-poort. Overigens installeren verschillende specialisten nog steeds 8, 16 of zelfs 32 COM-poorten op industriële computers (er is een hele categorie verschillende PCI-uitbreidingskaarten voor seriële poorten, controllers, enz.). Als u dus meerdere externe apparaten met een RS-232-interface moet aansluiten, heeft u mogelijk dure adapters en exotische uitbreidingskaarten nodig, die volgens de oude traditie wekenlang per schip naar Rusland reizen. Overigens kan de naam van een reguliere adapter “DB9m/DB25f adapter” alleen maar irritatie veroorzaken bij een computerwinkelmanager.

Wat is een HID-apparaat

Tegenwoordig zijn bijna alle apparaten via een USB-interface op een computer aangesloten. Daarom hebben veel nieuwe pc's helemaal geen COM-poort.

De USB-interface is een standaardoplossing voor het koppelen van een nieuw extern apparaat aan een computer; preciezer gezegd is het een HID-interface gebaseerd op het USB 1.1-protocol.

Hoewel veel mensen denken dat de HID-interface (Human Interface Device) uitsluitend bedoeld is voor het toetsenbord, de muis en de joystick, is deze geschikt voor veel oplossingen die verband houden met het koppelen van externe apparaten aan een computer.

Als de gebruiker gegevensuitwisseling op lage snelheid (tot 64 kbit/s) moet uitvoeren en tegelijkertijd de tijd voor het moeizaam ontwikkelen van zijn eigen stuurprogramma's wil verkorten, dan is HID zeer geschikt voor hem. Het eindresultaat zal een eenvoudige en volledig moderne oplossing zijn, gebaseerd op een standaard USB-software-interface met gegarandeerde ondersteuning op alle gangbare softwareplatforms.

HID-apparaateigenschappen

Vanuit het oogpunt van het organiseren van softwareondersteuning voor een HID-apparaat ziet alles er behoorlijk aantrekkelijk uit: om onder Windows te werken, kun je snel begrijpelijke, compacte code maken op basis van kant-en-klare, bewezen algoritmen. Tegelijkertijd zal de ontwikkelaar veel tijd hebben om zijn eigen data-uitwisselingsprotocol op het hoogste niveau te implementeren, aangezien het noodzakelijke abstractieniveau al is georganiseerd via het HID-protocol (zie tabel). Bovendien is het voor een programmeur gemakkelijk om een ​​geschreven uitwisselingsprotocol te debuggen (uiteraard als er een werkend HID-apparaat is) - vanwege de relatieve rigiditeit van het protocol zelf is het voldoende om simpelweg een computerondersteuningsprogramma te ontwikkelen voor de apparaat. Natuurlijk! De maker van het HID-apparaat heeft al veel werk op zich genomen.

Organisatie van de gegevensuitwisseling tussen het HID-apparaat en de computer

Om de interactie van een HID-apparaat met een computer te beschrijven, gebruiken we de term ‘host’. In dit geval wordt het opgevat als een besturingsapparaat in de algemene fysieke architectuur van interactie via het USB-protocol. Alle poorten op een computer zijn dus hosts. U kunt verschillende USB-apparaten (flashdrives, muizen, webcams, camera's, enz.) aansluiten die geen host hebben. De host biedt apparaatdetectie, verbinding, ontkoppeling, configuratie, evenals het verzamelen van statistieken en energiebeheer.

Het HID-apparaat kan zijn eigen pollingfrequentie instellen om te bepalen of het nieuwe gegevens bevat. Dit betekent dat zelfs op zo'n laag niveau de programmeur het systeem kan vertrouwen, omdat de pollingfrequentie en andere communicatieparameters vooraf moeten worden ingesteld in het HID-apparaatcontrollerprogramma. Dit onderscheidt het HID-protocol van de algemene beschrijving van USB 1.1 of USB 2.0, die geen strenge eisen stelt aan de organisatie van het protocol. Voor specifieke taken die een hoger beveiligingsniveau vereisen, kan het echter behoorlijk moeilijk zijn om van cyclische polling af te komen, wanneer vrijwel dezelfde gegevensblokken voortdurend worden verzonden.

Programmeerfuncties voor HID-apparaten

HID-apparaten hebben speciale omschrijvingen. Wanneer de host bepaalt dat het apparaat tot de HID-klasse behoort, geeft hij de controle erover door aan het juiste stuurprogramma. Aangenomen wordt dat onder zijn leiding verdere gegevensuitwisseling plaatsvindt.

In Windows is de HidServ-systeemservice verantwoordelijk voor toegang tot HID-apparaten. Meer details over de functies van zoekopdrachten naar HID-apparaten en andere functies van het werken met het HID-stuurprogramma worden beschreven in het werk van P. V. Agurov “USB Interface. Praktijk van gebruik en programmeren" (St. Petersburg: BHV-Petersburg, 2005).

HID-apparaten programmeren op het “topniveau”

Het zware leven van “applicatie”-programmeurs die in Pascal werken, wordt gemakkelijker gemaakt door de beproefde HID-module. PAS, shell-software voor verborgen. dll (Gebruikersbibliotheek verborgen - zoals gespecificeerd in de bestandseigenschappen). Uit de opmerkingen bij het bestand blijkt dat het gebaseerd is op de modules hidsdi.h en hidpi.h van Microsoft. En het HID-bestand zelf. PAS maakt deel uit van het JEDI()-pakket.

Om met een HID-apparaat in de Delphi voor win32-omgeving te werken, wordt de component TJvHidDeviceController gebruikt, een handige globale manager voor toegang tot HID-apparaten. En al op basis daarvan kunt u een objectinstantie krijgen voor het werken met een specifiek apparaat.

Basiseigenschappen en gebeurtenissen van de component TJvHidDeviceController

Laten we de component TJvHidDeviceController in meer detail bekijken. De OnArrival-gebeurtenis wordt geactiveerd wanneer een HID-apparaat het systeem binnenkomt (er verbinding mee maakt); toegang tot het apparaat wordt verleend in de handler van deze gebeurtenis via een exemplaar van de TJvHidDevice-klasse. De eenvoudige OnDeviceChange-gebeurtenis reageert op veranderingen in de status van het apparaat; het signaleert alleen veranderingen in het systeem. De gebeurtenis OnDeviceData wordt geactiveerd wanneer gegevens binnenkomen vanaf een van de HID-apparaten en het volgende doorgeeft aan de handler: HidDev: TJvHidDevice; - het apparaat waarvan de gegevens zijn ontvangen;

De gebeurtenis OnDeviceDataError waarschuwt voor een fout bij de gegevensoverdracht door de HidDev-parameters door te geven aan de verwerkingsprocedure: TJvHidDevice; - HID-apparaat en fout: DWORD; - foutcode. De gebeurtenis OnDeviceUnplug meldt dat een apparaat is verwijderd uit de lijst met geïnstalleerde apparaten op het systeem. De typen gebeurtenishandlers op Plug en Unplug zijn hetzelfde (in de brontekst: TJvHidUnplugEvent = TJvHidPlugEvent). Een object van de klasse TJvHidDevice dat overeenkomt met het HID-apparaat wordt doorgegeven aan de handler.

Om de HID-apparaten die in het systeem beschikbaar zijn opeenvolgend op te sommen door de Enumerate-methode aan te roepen, is de OnEnumerate-gebeurtenis bedoeld, dat wil zeggen dat in de gebeurtenishandler de gevonden apparaten opeenvolgend worden overgedragen als objecten. Deze gebeurtenis wordt geforceerd door de Enumerate-methode, die wordt gebruikt om bestaande HID-apparaten via een handler door te geven, bijvoorbeeld bij het herzien van de status van HID-apparaten op initiatief van de host (computer).

De gebeurtenis OnRemoval wordt geactiveerd wanneer een apparaat fysiek uit het systeem wordt verwijderd en hetzelfde handlertype TJvHidUnplugEvent heeft als voor OnDeviceUnplug. De functie CountByProductName retourneert het aantal apparaten dat overeenkomt met de productnaam die in het argument is opgegeven, en CountByVendorName retourneert de naam van de fabrikant die in het argument is opgegeven.

Belangrijkste eigenschappen en gebeurtenissen van de klasse TJvHidDevice

De klasse TJvHidDevice is een virtuele representatie van een enkel HID-apparaat. Een nieuw object van deze klasse kan, zoals reeds vermeld, worden verkregen uit de gebeurtenis OnArrival of OnEnumerate. De functionaliteit van de klassen TJvHidDeviceController en TJvHidDevice is gedeeltelijk gedupliceerd, omdat de eerste algemene tools integreert voor het werken met een reeks HID-apparaten die beschikbaar zijn in het systeem en een mechanisme voor toegang tot een van deze. Een apparaat kan op unieke wijze worden geïdentificeerd aan de hand van de eigenschappen Serienummer, Productnaam en Leveranciersnaam. Om via een dergelijk object informatie te verkrijgen over de aankomst van gegevens, kunt u gebruik maken van de gebeurtenis OnData. Gegevens worden verzonden via de WriteFile-methode (in strikte zin - via een functie). WriteFile is een wrapper rond de WriteFile (kernel32) systeemfunctie.

Om te bepalen of het apparaat is verwijderd, moet u uw eigen handler toewijzen aan de OnUnplug-gebeurtenis. Voordat u gegevens gaat uitwisselen met een HID-apparaat, moet u ervoor zorgen dat een dergelijke uitwisseling mogelijk is met HasReadWriteAccess. Deze klasse heeft zelfs een aparte OnDataError-gebeurtenis wanneer er een gegevensuitwisselingsfout optreedt.

Laten we nu eens kijken naar codefragmenten van een ‘live’ project dat een testclienttoepassing implementeert voor het organiseren van gegevensuitwisseling met een niet-standaard apparaat: op HID gebaseerde plastic chipkaarten. In de strijd om realisme nam de auteur het op zich om geen “extra” technologische codeverbindingen uit de lijsten te verwijderen.

De ScanDevices-methode (Lijst 1) is bedoeld om het proces van het zoeken in het systeem naar het vereiste HID-apparaat te starten. Het grootste deel van de code, met uitzondering van de aanroep van de Enumerate-methode, is optioneel en biedt flexibiliteit aan de applicatie, zodat bijvoorbeeld de mogelijkheid om op een niet-HID-interface te werken aan hetzelfde testprogramma kan worden toegevoegd. De AddError-methode geeft foutopsporingsinformatie in het venster weer terwijl het programma actief is.

Lijst 2 toont een gebeurtenishandler OnEnumerate om het vereiste externe apparaat te vinden. Voor de eenvoud gaan we ervan uit dat het programma slechts met één apparaat kan werken van het type dat het nodig heeft.

Voordat we de verdere implementatie van het project overwegen, moeten we eerst even praten over het aangenomen data-uitwisselingsformaat op het hoogste niveau, dat wil zeggen over de structuur die is ontworpen als tussenpersoon tussen de methoden voor het ontvangen en verzenden van gegevens en het specifieke toepassingsprobleem dat wordt opgelost. Feit is dat hier de ontwikkelaar de kans krijgt om zijn creatieve vaardigheden te realiseren. Of beter gezegd: ontwikkelaars, omdat het proces van het maken van een nieuw protocol vaak tweerichtingsverkeer is en de eerste viool wordt gespeeld door degene die het moeilijker vindt om het uitwisselingsalgoritme te implementeren. Over het algemeen is het, ongeacht het uitwisselingsprotocol, altijd prettig om elke software-entiteit zo visueel en zelfvoorzienend mogelijk te maken, zelfs ten koste van enkele algemeen aanvaarde tradities. Want de beste oplossing is degene die in korte tijd kan worden geïmplementeerd met minimale aansluiting op de softwareomgeving en met grote mogelijkheden voor verdere ontwikkeling. Op basis van deze principes werd een uitwisselingsprotocol op het hoogste niveau gecreëerd, waarbij het hoofdconcept “opdracht” is. Lijst 3 laat zien hoeveel de auteur van stringgegevens houdt, wat hem meer dan eens heeft bespaard bij het debuggen van programmamodules. Hoe geweldig is het dat we zelfs een String-type hebben! Alle protocolopdrachten zijn onderverdeeld in categorieën (klassen), waarbinnen zich een opdrachtcode bevindt die het doel ervan op unieke wijze kenmerkt. De parameter edParam wordt gebruikt om gegevens naar het apparaat te verzenden, en de parameter edAnswerData bevat gegevens die van het apparaat zijn ontvangen. Dankzij het stringtype van de beschreven recordleden kunt u vrij en duidelijk gegevens in HEX-stringformaat manipuleren. En het beste is dat het formaat van het beschreven document ideologisch gezien ergens in het midden ligt tussen het directe doel ervan en de verschillende vormen van presentatie ervan (INI, HEX, XML, enz.)

Het uitvoeren van de opdracht, dat wil zeggen het verzenden van gegevens naar het apparaat, wordt geïmplementeerd met behulp van het verzenden van gegevenspakketten van 8 bytes lang (Lijst 4). Deze lengte is niet de enige oplossing; deze keuze wordt bepaald door de vereisten van het protocol op het hoogste niveau en kan in elk specifiek geval verschillen. Dit is, zoals ze zeggen, een kwestie van smaak. De vreemde IsUSBMode-vlag in de ExecuteCommand-methode (Listing 5 in PC World) wordt achtergelaten als herinnering dat we mogelijk een COM-poort of een andere interface moeten gebruiken in plaats van met USB te werken. Aan het begin van de verzonden groep gegevens wordt een synchronisatiereeks van een willekeurig geselecteerd formaat (bijvoorbeeld 3E3E3E2B) naar het apparaat verzonden, waardoor het apparaat wordt geïnformeerd dat het volledig legale gegevens aan de ingang heeft. Ik wil u eraan herinneren dat we het in dit geval niet zozeer over HID hebben, maar over een specifiek protocol op het hoogste niveau, ideologisch gescheiden van de hardware en bedoeld om speciale toepassingsproblemen op te lossen.

De GetDataExecutor-handler voor gegevens ontvangen van het apparaat (een pakket van 8 bytes) gebruikt een speciaal gemaakte OnNewInputData-gebeurtenis om de aanvankelijk verwerkte gegevens over te dragen voor verdere verwerking, waarbij hun oude en nieuwe waarden worden aangegeven (Lijst 6 op de “World of PC Disk ”). Op deze manier worden aankomstgebeurtenissen van ruwe gegevens en indicaties voor verdere verwerking ontkoppeld, waardoor al vroeg een specifiek algoritme kan worden toegevoegd om te waarschuwen voor foutieve, dubbele of onnodige invoerinformatie.

De hier gepresenteerde voorbeelden van het werken met een HID-apparaat illustreren het algemene idee van het artikel: het relatieve gemak van het programmeren van niet-standaard HID-apparaten met Delphi.

De USB-bus (Universal Serial Bus) verscheen op 15 januari 1996, met de goedkeuring van de eerste versie van de standaard door Intel, DEC, IBM, NEC, Northen Telecom en Compaq.

Het belangrijkste doel van de standaardset voor de ontwikkelaars is om gebruikers de mogelijkheid te bieden om in Plug&Play-modus met randapparatuur te werken. Dit betekent dat het mogelijk moet zijn om het apparaat aan te sluiten op een draaiende computer, het direct na aansluiting automatisch te herkennen en vervolgens de juiste stuurprogramma's te installeren. Daarnaast is het raadzaam om apparaten met een laag vermogen vanaf de bus zelf van stroom te voorzien. De bussnelheid zou voor de overgrote meerderheid van de randapparatuur voldoende moeten zijn. De USB-controller zou slechts één interrupt moeten bezetten, ongeacht het aantal apparaten dat op de bus is aangesloten, dat wil zeggen het probleem van het gebrek aan bronnen op de interne bussen van een IBM PC-compatibele computer oplossen.

Bijna alle toegewezen taken werden opgelost in de USB-standaard en in het voorjaar van 1997 begonnen computers te verschijnen die waren uitgerust met connectoren voor het aansluiten van USB-apparaten. Nu is USB zo actief geïmplementeerd door fabrikanten van computerrandapparatuur dat bijvoorbeeld de iMAC-computer van Apple Computers alleen USB als externe bus heeft.

USB 1.0-functies zijn als volgt:

1. hoge gegevensoverdrachtsnelheid (volle snelheid) – 12 MB Het/Met;

2. maximale kabellengte voor snelle uitwisseling – 5 meter;

3. lage gegevensuitwisselingssnelheid (low-speed) – 1,5 MB Het/Met;

4. maximale kabellengte voor lage gegevensoverdrachtsnelheid is 3 meter;

5. maximaal aantal aangesloten apparaten – 127;

6. mogelijke gelijktijdige verbinding van apparaten met verschillende wisselkoersen;

8. Het maximale stroomverbruik per apparaat bedraagt ​​500 mA.

Daarom is het raadzaam om vrijwel alle randapparaten op USB 1.0 aan te sluiten, behalve digitale videocamera's en snelle harde schijven. Deze interface is vooral handig voor het aansluiten van vaak aangesloten/losgekoppelde apparaten, zoals digitale camera's.
De mogelijkheid om slechts twee datasnelheden te gebruiken beperkt de bruikbaarheid van de bus, maar vermindert aanzienlijk het aantal interfacelijnen en vereenvoudigt de hardware-implementatie.
Rechtstreekse voeding vanaf USB is alleen mogelijk voor apparaten met een laag vermogen, zoals toetsenborden, muizen, joysticks, enz.

USB-signalen worden verzonden via een 4-aderige kabel, schematisch weergegeven in de onderstaande afbeelding:

Afbeelding 2.6.1 – USB-signaaldraden

Hier is GND het gemeenschappelijke draadcircuit voor het voeden van randapparatuur, Vbus is +5 V, ook voor stroomcircuits. De D+-bus is voor het verzenden van gegevens op de bus en de D-bus is voor het ontvangen van gegevens.
De full-speed buskabel is een twisted-pair-kabel, beschermd door een afscherming, en kan ook worden gebruikt voor werking op lage snelheid. Een kabel die alleen op minimale snelheid werkt (bijvoorbeeld om een ​​muis aan te sluiten) kan elk en niet-afgeschermd zijn.
De connectoren die worden gebruikt om randapparatuur aan te sluiten, zijn onderverdeeld in series: connectoren uit de serie “A” (stekker en stopcontact) zijn alleen bedoeld voor aansluiting op een bron, zoals een computer, connectoren uit de serie “B” (stekker en stopcontact) zijn alleen bedoeld voor aansluiting naar een randapparaat.

USB-connectoren hebben de volgende pinnummers, weergegeven in Tabel 2.6.1.

Tabel 2.6.1 – Doel en markering van USB-contacten

In 1999 begon hetzelfde consortium van computerbedrijven dat de ontwikkeling van de eerste versie van de USB-busstandaard startte, actief met de ontwikkeling van versie 2.0 van USB, die zich onderscheidde door de introductie van een extra hogesnelheidsmodus (Hi-speed). De busbandbreedte is 40 keer vergroot, tot 480 Mbit/s, waardoor het mogelijk is videogegevens via USB over te dragen.
De compatibiliteit van alle eerder uitgebrachte randapparatuur en hogesnelheidskabels blijft volledig behouden. De 2.0-standaardcontroller is al geïntegreerd in de systeemlogica van programmeerbare apparaten (bijvoorbeeld het moederbord van een pc).

In 2008 creëerden Intel, Microsoft, Hewlett-Packard, Texas Instruments, NEC en NXP Semiconductors de USB 3.0-standaardspecificatie. In de USB 3.0-specificatie zijn de connectoren en kabels van de bijgewerkte standaard fysiek en functioneel compatibel met USB 2.0, maar naast de vier communicatielijnen zijn er nog vier toegevoegd. De nieuwe pinnen in de USB 3.0-connectoren bevinden zich echter apart van de oude op een andere pinnenrij. De USB 3.0-specificatie verhoogt de maximale overdrachtssnelheid tot 5 Gbps - wat een orde van grootte hoger is dan de 480 Mbps die USB 2.0 kan bieden. Bovendien is de maximale stroom verhoogd van 500 mA naar 900 mA per apparaat, waardoor u sommige apparaten kunt voeden die voorheen een aparte voeding nodig hadden.

Stel dat u een USB-apparaat heeft ontwikkeld waarmee u op een computer moet werken. Dit kan op ten minste twee manieren worden bereikt:

1. ontwikkeling van een volledig uitgerust stuurprogramma voor het besturingssysteem;

2. gebruik van een USB-interface van een speciale klasse - apparaten die HID-apparaten (Human Interface Device) worden genoemd.

De eerste methode is universeel: als je voldoende kennis hebt op het gebied van het schrijven van stuurprogramma's, kun je deze programmeren om met elk apparaat te werken op elke snelheid die door USB wordt ondersteund. Maar dit is een behoorlijk moeilijke taak.

De tweede manier is als volgt. Er is een interface die wordt ondersteund door moderne besturingssystemen voor computer-menselijke interface-apparaten of HID-apparaten, zoals:

1. toetsenborden, muizen, joysticks;

2. diverse sensoren en lezers;

3. gamingbesturing en pedalen;

4. knoppen, schakelaars, regelaars.

Een dergelijk apparaat wordt, als het voldoet aan de vereisten voor HID-apparaten, automatisch door het systeem herkend en vereist geen speciale stuurprogramma's. Bovendien is het programmeren ervan meestal veel eenvoudiger dan het schrijven van een aangepast apparaatstuurprogramma. Helaas heeft deze methode een belangrijk nadeel: de snelheid van de informatie-uitwisseling met het HID-apparaat is zeer beperkt en bedraagt ​​maximaal 64 kB/s.

In principe is het op basis van HID-technologie mogelijk om interactie met elk apparaat te organiseren, zelfs als het niet in de strikte zin van het woord een mens-computer-interfaceapparaat is. Dit elimineert de tijdrovende ontwikkeling van een uniek apparaatstuurprogramma en bespaart tijd bij het ontwikkelen van een nieuw USB-apparaat. Aan de hostzijde wordt de communicatie met het apparaat geregeld door het standaard HID-stuurprogramma dat bij het besturingssysteem wordt geleverd. U hoeft alleen maar aan de minimale vereisten van het USB-HID-protocol aan de apparaatzijde te voldoen.

Het is vermeldenswaard dat veel USB-apparaten, die op het eerste gezicht niet onder de definitie van apparaten voor menselijke interactie vallen, nog steeds logischer zijn om als HID-apparaten te implementeren. Dit fenomeen komt veel voor op het gebied van productieapparatuur, waar onlangs een enorme adoptie van USB-technologie heeft plaatsgevonden. Denk bijvoorbeeld aan een laboratoriumvoeding met de mogelijkheid om de parameters van de uitgangssignalen vanaf een computer in te stellen met behulp van een USB-interface. De krachtbron zelf is ongetwijfeld geen middel tot interactie met een persoon. In dit geval dupliceren de functies die via een USB-verbinding worden geïmplementeerd echter het toetsenbord, de bedieningselementen en de indicatoren die op het apparaat zelf zijn geïnstalleerd. En deze controles vallen binnen de definitie van HID. Daarom is het het meest logisch om een ​​voeding met deze USB-functies als HID-apparaat te organiseren.

In het beschouwde voorbeeld zal een lage gegevensoverdrachtsnelheid voldoende zijn voor normaal gebruik; in andere gevallen kunnen apparaten zeer veeleisend zijn voor de wisselkoers. Lage overdrachtssnelheid is de belangrijkste beperking van de HID-apparaatontwerpoptie, die, in vergelijking met de 12 Mbit/s volledige snelheid van de USB 1.0-bus, een groot nadeel van HID-technologie lijkt bij het kiezen van een specifieke USB-implementatie. Voor veel communicatietaken is de opgegeven snelheid echter voldoende en neemt de HID-architectuur als gespecialiseerd hulpmiddel zijn rechtmatige plaats in onder de methoden voor het organiseren van gegevensuitwisseling.

Er zijn twee soorten HID-apparaten: apparaten die deelnemen (opstarten) en apparaten die niet deelnemen aan de eerste keer opstarten van de computer. Het meest opvallende voorbeeld van een opstartbaar USB-HID-apparaat is een toetsenbord, dat begint te werken zodra de computer opstart.

Bij het ontwerpen van een HID-apparaat moet aan de volgende specificatie-eisen worden voldaan:

1. HID-apparaat op volle snelheid kan 64.000 bytes per seconde of 64 bytes per 1 ms overbrengen; Een HID-apparaat met lage snelheid kan maximaal 800 bytes per seconde overdragen, of 8 bytes per 10 ms.

2. Het HID-apparaat kan zijn pollingfrequentie plannen om te bepalen of er nieuwe gegevens moeten worden verzonden.

3. Gegevensuitwisseling met het HID-apparaat vindt plaats via een speciale structuur, een rapport genaamd. Elk gedefinieerd rapport kan maximaal 65535 bytes aan gegevens bevatten. De rapportstructuur heeft een zeer flexibele organisatie waarmee u elk formaat voor gegevensoverdracht kunt beschrijven. Om een ​​specifiek rapportformaat bekend te maken bij de host, moet de microcontroller een speciale beschrijving bevatten: een rapportdescriptor.

USB-interactie wordt op verschillende manieren rechtstreeks op de microcontroller geïmplementeerd:

1. gebruik van een controller met hardware-ondersteuning, bijvoorbeeld AT90USB*, van atmega;

2. het gebruik van software-emulatie van de USB-interface op elke microcontroller.

Voor de software-implementatie bestaan ​​er momenteel een aantal kant-en-klare oplossingen voor diverse families microcontrollers. Voor AVR-microcontrollers, bijvoorbeeld Atmega8, is het mogelijk om de volgende gratis bibliotheken in de C-taal te gebruiken:

Beide zijn vrij eenvoudig te gebruiken, bieden volledige emulatie van USB 1.1-apparaten met lage snelheid, met uitzondering van de afhandeling van communicatiefouten en elektrische kenmerken, en draaien op vrijwel alle AVR-controllers met minimaal 2 kilobyte flashgeheugen, 128 bytes RAM en een frequentie van 12 tot 20 MHz.

Om applicaties te schrijven die Windows USB HID-apparaten ondersteunen, hebt u de hid*-headerbestanden nodig die zijn opgenomen in de WDK (Windows Driver Kit), of u kunt de gratis beschikbare hidlibrary-bibliotheek of een andere vergelijkbare bibliotheek gebruiken.

Over het algemeen is USB-programmering dus een nogal complexe taak, waarvoor een speciale microcontroller met hardware-ondersteuning en het schrijven van een besturingssysteemstuurprogramma vereist is. In de praktijk kunt u bij het ontwikkelen van apparaten echter een veel eenvoudiger HID-apparaatinterface gebruiken, waarvan de ondersteuning wordt geïmplementeerd op het niveau van een standaard systeemstuurprogramma, en het programmeren wordt vereenvoudigd door gebruik te maken van bestaande functiebibliotheken.

Beveiligingsvragen

  1. Wat is het verschil tussen de D- en GND-draden in USB? Waarom kun je niet één gemeenschappelijke draad gebruiken voor stroom en signaal?
  2. Hoeveel USB-snelheidsmodi zijn er tegenwoordig (inclusief versie 3.0)?
  3. Wat is een HID-apparaat? Waarom vereisen ze geen schrijfstuurprogramma's om in moderne besturingssystemen te werken?
  4. Is het mogelijk om USB-apparaten te implementeren met behulp van een microprocessor die geen ingebouwde interface-ondersteuning heeft?
  5. Wat zijn de belangrijkste verschillen tussen USB 3.0 en eerdere versies?

Goed boek, legt veel uit. Het zal nuttig zijn voor degenen die willen begrijpen hoe gegevens via de USB-bus worden overgedragen.

Inleiding 1
Voor wie is dit boek bedoeld: 2
Wat vind je in boek 2
Softwarevereisten 3
Hardwarevereisten 4
Over programmacode 4
Korte beschrijving van hoofdstukken 4
Notatie 6
Bedankt 7
DEEL I. INLEIDING TOT USB 9
Hoofdstuk 1. Wat is USB 11
1.1. Geschiedenis van USB 11
1.2. Vergelijking van USB met andere interfaces 14
1.3. USB 16-concepten
1.3.1. Algemene busarchitectuur 16
1.3.2. Fysieke en logische architectuur van bus 16
1.3.3. Componenten van USB 18
1.3.4. Eigenschappen USB-apparaat 18
1.3.5. Hubeigenschappen 19
1.3.6. Hosteigenschappen 20
1.4. 20 Voorbeelden van USB-apparaten
1.4.1. Muis en toetsenbord., 21
1.4.2. Monitoren 21
1.4.3. USB-naar-COM- en USB-naar-LPT-adapters 22
1.4.4. Scanners 23
1.4.5. Modems 23
1.4.6. Sprekers 24
1.4.7. Flashdrives 25
1.4.8. Naven 28
1.4.9. Meettechniek 28
1.4.10. Exotische apparaten 29
1.5. Netwerkverbinding via USB 30
1.5.1. USB-Ethernet-converter 31
1.5.2. Directe verbinding via USB-poort 31
1.6. Gegevensoverdracht 31
1.6.1. Beginselen van gegevensoverdracht 32
1.6.2. Onderbrekingsmechanisme 32
1.6.3. Hostadapterinterfaces 32
1.6.4. DMA-mogelijkheid 34
1.6.5. Gegevensoverdrachtmodi 34
1.7. USB-apparaten installeren en configureren 35
1.7.1. BIOS-instellingen voor USB 38
1.7.2. Probleemoplossing 41
1.8. USB 45-beperkingen
1.9. Als u een computer koopt 46
1.9.1. HS en USB 2.0 zijn niet hetzelfde! 46
1.9.2. Systeembord 47
1.9.3. Gebouw 48
1.9.4. USB voor “oude” computermodellen 48
1.10. Online bronnen voor dit hoofdstuk 49
Hoofdstuk 2. USB-hardware 51
2.1. Kabels en connectoren 51
2.1.1. Kabeltypen 52
2.1.2. Kabellengte 53
2.1.3. Connectoren 53
2.2. Fysieke interface 55
2.2.1. Gegevenscodering 57
2.2.2. Apparaatidentificatie 58
2.3. Voeding 59
2.3.1. USB-voedingstypen 59
2.3.2. Energiebeheer 60
2.3.3. Energiezuinige modus inschakelen 61
2.4. Online bronnen voor dit hoofdstuk 61
DEEL II. INTERNE ORGANISATIE USB 63
Hoofdstuk 3. Interne organisatie van de bus 65
3.1. Logische communicatieniveaus 65
3.1.1. Clientsoftwareniveau 66
3.1.2. USB-systeemstuurprogramma niveau 67
3.1.3. Interfacehostcontrollerlaag 68
3.1.4. Randbus niveau 68
3.1.5. USB logisch apparaatniveau 69
3.1.6. Functioneel niveau van USB-apparaat 69
3.2. Gegevensoverdracht over 69 niveaus
3.3. Soorten gegevensoverdrachten 71
3.4. Synchronisatie met isochrone transmissie 73
3.5. Personeel 77
3.6. Eindpunten 78
3.7. Kanalen 79
3.8. Pakketten 81
3.8.1. Formaat van IN-, OUT-, SETUP- en PING-markeringspakketten 83
3.8.2. SOF 83 pakketformaat
3.8.3. Datapakketformaat 84
3.8.4. Bevestigingspakketformaat< 84
3.8.5. Pakketformaat SPLIT * 84
3.9. Controlesom 85
3.9.1. Algoritme voor het berekenen van CRC 86
3.9.2. Softwareberekening van CRC 87
3.10. Transacties 90
3.10.1. Transactiesoorten 91
3.10.2. Transactiebevestiging en stroomcontrole 92
3.10.3. Transactieprotocollen 93
Hoofdstuk 4. Interne organisatie van het apparaat 96
4.1. Verzoeken aan USB-apparaten 96
4.1.1. Configuratiepakket 96
4.1.2. Standaardverzoeken aan apparaten 99
4.1.3. Apparaatbeschrijvingen 105
Hoofdstuk 5. Interne organisatie van de host en hubs 123
5.1. Naven 123
5.1.1. Interactie van de hostcontroller met de hub 126
5.1.2. Naafbeschrijving 127
5.1.3. Hubverzoeken 129
5.1.4. Verzoek CLEAR_HUB_FEATURE 130
5.1.5. Vraag CLEAR PORT_FEATURE 130 aan
5.1.6. Vraag GET_BUS_STA TE 131 aan
5.1.7. Verzoek GET_HUB_DESCRfPTOR 131
5.1.8. Vraag GET_HUB_STATUS 131 aan
5.1.9. Vraag GET_PORT_STA TUS 132 aan
5.1.10. Verzoek SET_HUB_DESCRIPTOR 134
5.1.11. Verzoek SET_HUB_FEATURE 134
5.1.12. SET PORT FEATURE-verzoek. 134
5.2. Samenwerken tussen apparaten op verschillende snelheden 135
Hoofdstuk 6. USB zonder pc 137
6.1. OTG 138-connectoren
6.2. Soorten OTG-apparaten 138
6.3. OTG-apparaatdescriptor 139
6.4. Online bronnen voor dit hoofdstuk 140
DEEL III. PROGRAMMERINGSPRAKTIJK 141
Hoofdstuk 7. USB-ondersteuning in Windows 143
7.1. ModelWDM144
7.2. Interactie met USB-stuurprogramma 146
Hoofdstuk 8. HID-apparaten * 149
8.1. HID-apparaateigenschappen 149
8.2. Hoe te communiceren met een HID-apparaat 151
8.3. Een HID-apparaat installeren 152
8.4. HID-apparaatidentificatie 152
8.4.1. Identificatie van opstartapparaat 153
8.4.2. HID-apparaatconfiguratiedescriptor 153
8.4.3. HID-descriptor 154
8.4.4. Rapportbeschrijving 156
8.5. Rapportdescriptorstructuur 156
8.5.1. Structuur van rapportelementen 156
8.5.2. Soorten rapportelementen 157
8.5.3. Voorbeelden van descriptoren 165
8.6. HID-apparaatquery's 168
8.6.1. GET_REPORT verzoek. 169
8.6.2. Verzoek SET_REPORT 169
8.6.3. GETJDLE-verzoek. 170
8.6.4. Zoek SETJDLE 170
8.6.5. Vraag GET_PROTOCOL 171 aan
8.6.6. Verzoek SET_PROTOCOL 171
8.7. Gereedschap 171
8.8. Interactie met HID-stuurprogramma 172
Hoofdstuk 9. Inleiding tot WDM 181
9.1. Driverlagen 183
9.2. Symbolische apparaatnamen 184
9.3. Basisprocedures WDM-stuurprogramma 189
9.3.1. Procedure Bestuurdersinvoer 190
9.3.2. Procedure Apparaat toevoegen 192
9.3.3. Procedure lossen 194
9.3.4. Bedieningsprocedures voor chauffeurs 196
9.3.5. IOCTL 203-verzoeken verwerken
9.4. Het stuurprogramma laden en toegang krijgen tot stuurprogrammaprocedures 209
9.4.1. Procedure voor het werken met de chauffeur 209
9.4.2. Chauffeursregistratie 210
9.4.3. Verwijzend naar operationele procedures 217
9.4.4. Het stuurprogramma opslaan in het uitvoerbare bestand 218
9.5. Hulpmiddelen voor het maken van stuurprogramma's 220
9.5.1. NuMega-stuurprogramma Studio 220
9.5.2. Jungo WinDriver 220
9.5.3. Jungo Kernel-stuurprogramma 220
Hoofdstuk 10. USB PnP-specificatie 221
10.1. Inleiding tot Plug-and-Play 221
10.1.1. Plug-and-play-taken en -functies 221
10.1.2. PnP-procedure uitvoeren 222
10.1.3. PnP 224-softwarecomponenten
10.2. Plug-and-play voor USB 225
10.2.1. USB 226-apparaten configureren
10.2.2. USB-apparaatnummer 226
10.2.3. PnP USB-apparaat-ID's 228
10.3. Een lijst met USB-apparaten ophalen 229
10.4. INF-bestand 234
10.4.1. INF-bestandsstructuur 234
10.4.2. Sectieversie 235
10.4.3. Sectie Fabrikant 237
10.4.4. Sectie Bestemmingsmap 239
10.4.5. Modelbeschrijving Sectie 241
10.4.6. Sectie xxx.AddReg en xxx.DelReg. 242
10.4.7. Sectie xxx.LogConfig 244
10.4.8. Sectie xxx.CopyFiles 244
10.4.9. Sectiereeksen 245
10.4.10. Sectieverbindingen 246
10.4.11. INF-bestanden maken en testen 247
10.4.12. Apparaten installeren met behulp van een INF-bestand 248
10.5. Registervertakkingen voor USB 249
Hoofdstuk 11. BIOS-functies 251
11.1. Service-BIOS 1AN 251
11.1.1. Functie B101H - bepalen van de aanwezigheid van PCI BIOS 252
11.1.2. Functie В102Н - zoeken naar PCI-apparaat op basis van identificatie
apparaat en fabrikant 253
11.1.3. Functie В103Н - zoeken naar PCI-apparaat op klassecode 254
11.1.4. Functie B108N - configuratieregister lezen (byte) 255
11.1.5. Functie VYu9N - lezen van het configuratieregister (Word) 256
11.1.6. Functie B10AN - configuratieregister lezen (DWord) 256
11.1.7. Functie В10ВН - schrijf configuratieregister (Byte) 257
11.1.8. Functie B10CH - schrijven van een configuratieregister (Word) 257
11.1.9. Functie B10DH - Configuratieregister schrijven (DWord) 258
11.2. Gebruiksvoorbeeld 259
DEEL IV. USB-APPARATEN MAKEN 283
Hoofdstuk 12. USB-randapparatuur 285
12.1. Atmel 286-chips
12.1.1. Microcontrollers met MSC-51 286-architectuur
12.1.2. Hubcontrollers 289
12.1.3. Hub-microprocessors met AVR 289-kern
12.1.4. Andere Atmel 290-chips
12.2. Cygnal 291-chips
12.2.1. Microprocessoren C8051F320 en C8051F321 291
12.2.2. Andere Cygnal 293-chips
12.3. FTDI 296-chips
12.3.1. Chips FT232AM en FT232BM 297
12.3.2. Chips FT245AM en FT245BM 298
12.3.3. Chip FT2232BM 299
12.3.4. ChipFT8U100AX 300
12.3.5. Debug-kits en modules 301
12.3.6. Chauffeurs 302
12.3.7. Extra nutsvoorzieningen 303
12.3.8. Overige 304 modules
12.4. Intel 304-chips
12.5. Microchip 308-chips
12.6. Motorola 308-chips
12.7. Philips 309-chips
12.7.1. USB 310-chips
12.7.2. Naven 311
12.7.3. Andere Philips 313-chips
12.8. Texas Instruments 314-chips
12.9. Trans Dimension 317-chips
12.10. 318 stroombeveiligingschips
12.11. Online bronnen voor dit hoofdstuk 319
Hoofdstuk 13. HID-apparaat gebaseerd op Atmel AT89C5131 322
13.1. Blokschema AT89S5131 322
13.2. USB registreert AT89С5131 324
13.2.1. USBCON-register 324
13.2.2. USBADDR-register 326
13.2.3. USBINT-register 327
13.2.4. USBIEN 328-register
13.2.5. UEPNUM-register. 329
13.2.6. Registreer UEPCONX 330
13.2.7. UEPSTAX-register. 331
13.2.8. Registreer UEPRST. 334
13.2.9. UEPINT-register. 335
13.2.10. Registreer UEPIEN 336
13.2.11. Registreer UEPDATX 337
13.2.12. Registreer UBYCTLX 337
13.2.13. UFNUML-register 338
13.2.14. UFNUMH-register. 338
13.3. Schakelingen AT89S5131 338
13.4. Programmeerhulpmiddelen 339
13.4.1. Samensteller 341
13.4.2. Programmeur 342
13.5. Programma voor microprocessor 349
13.5.1. Eerste versie van het programma voor AT89S5131 349
13.5.2. Tekenreeksdescriptors toevoegen 369
13.5.3. Eindpunten toevoegen 374
13.5.4. Een HID-apparaat maken 377
13.5.5. Communicatie met HID-apparaat 381
13.6. Rapporten lezen in Windows 388
13.7. Extra functies van Windows XP 396
13.8. Toestel met meerdere rapporten 397
Hoofdstuk 14. Een USB-apparaat maken op basis van ATMEL AT89C5131 402
14.1. Niet-HID-apparaat 402
14.2. Een stuurprogramma maken met Driver Studio 405
14.2.1. Een paar woorden over de Driver Studio 407-bibliotheek
14.2.2. Andere Driver Studio 411-klassen
14.2.3. Een driversjabloon maken met Driver Studio 412
14.2.4. Verbetering van stuurprogrammasjabloon 422
14.2.5. Basismethoden van de apparaatklasse 423
14.2.6. Implementatie van leesgegevens 426
14.2.7. Het installeren van het 428-stuurprogramma
14.2.8. Gegevenslezer 429
14.2.9. Gegevens lezen van andere typen eindpunten 438
14.2.10. “Schoon” USB-stuurprogramma 439
Hoofdstuk 15: FTDI 457-chips gebruiken
15.1. Functioneel diagram FT232BM 457
15.2. Schakelontwerp FT232BM 460
15.3. Functies van D2XX 460
15.4. Overgang van COM naar USB 465
15.4.1. Beschrijving van het 465-omzettercircuit
15.4.2. Instellen van de baudrate 467
DEEL V. HANDBOEK 469
Hoofdstuk 16: Basisfuncties van Windows 471
16.1. CreateFile- en CloseHandle-functies: een object openen en sluiten.471
16.1.1. Aanvullende informatie 472
16.1.2. Retourwaarde 472
16.1.3. Voorbeeld bel 472
16.2. Bestandsfunctie lezen: gegevens lezen 473
16.2.1. Aanvullende informatie 474
16.2.2. Retourwaarde 474
16.2.3. Voorbeeld bel 474
16.3. WriteFile-functie: gegevensoverdracht 475
16.3.1. Aanvullende informatie 476
16.3.2. Retourwaarde 476
16.3.3. Voorbeeld bel 476
16.4. ReadFileEx-functie. APC-gegevens lezen 477
16.4.1. Retourwaarde 479
16.4.2. Aanvullende informatie 479
16.4.3. Voorbeeld bel 479
16.5. WriteFileEx-functie: APC-gegevensoverdracht 480
16.5.1. Retourwaarde 481
16.5.2. Voorbeeld bel 481
16.6. Functie WaitForSingleObject wacht op signaal
objectstatus 482
16.6.1. Retourwaarde 482
16.7. WaitForMultipleObjects-functie: wachten op signaal
objectstatus 483
16.7.1. Retourwaarde 484
16.8. GetOverlappedResult-functieresultaat van asynchrone bewerking 484
16.8.1. Retourwaarde 485
16.9. DeviceIoControl-functie: Directe driverbediening 485
16.9.1. Retourwaarde 487
16.10. QueryDosDevice-functie: de apparaatnaam ophalen
onder zijn DOS-naam 487
16.10.1. Retourwaarde 488
16.10.2. Voorbeeld bel 488
16.11: Dos Device-functie definiëren: bewerkingen met DOS-apparaatnaam 489
16.11.1. Retourwaarde 490
16.11.2. Voorbeeld bel 490
Hoofdstuk 17. HID API-functies. 492
17.1. HidD_Hello-functie: bibliotheek 492 controleren
17.2. Functie HidD_GetHidGuid: GUID 492 ophalen
17.3. HidD_GetPreparsedData-functie: een apparaatdescriptor maken 493
17.4. HidD_FreePreparsedData-functie: apparaathandgreep 493 vrijmaken
17.5. Functie HidD_GetFeature: FEATURE-rapport 494 ontvangen
17.6. HidD_SetFeature-functie: FEATURE-rapport 494 verzenden
17.7. HidD_GetNumInputBuffers-functie: het aantal buffers 495 ophalen
17.8. Functie HidD_SetNumInputBuffers: het aantal buffers instellen op 495
17.9. Functie HidD_GetAttribntes: apparaatkenmerken ophalen 495
17.10. Functie HidD_GetMamifactnrerStnng. fabrikantstring 496 verkrijgen
17.11. Functie HidD_GetProductString. productlijn 497 verkrijgen
17.12. Functie HidD_ Serienummerreeks ophalen. touwtje krijgen
serienummer 497
17.13. Functie HidD_GetIndexedString. een rij krijgen op index 498
17.14. Functie HidDjGetlnputReporr. ontvangst van INPUT-rapport 498
17.15. Functie HidD_SetOutputReport. OUTPUT-rapport 499 verzenden
17.16. HidP_GetCaps-functie: apparaateigenschappen ophalen 499
17.17. Functie HidP_MaxDataListLength: rapportgrootte 500 ophalen
Hoofdstuk 18. UCH 502 hostcontroller
18.1. H502
18.1.1. USB-opdrachtregister (USBCMD) ..504
18.1.2. USB-statusregister (USBSTS) 506
18.1.3. Interrupt-controleregister (USBINTR) 506
18.1.4. Framenummerregister (FRNUM) 507
18.1.5. Framebasisadresregister (FLBASEADD) 508
18.1.6. Begin van Frame Modifier Register (SOFMOD) 508
18.1.7. Havenstatus en controleregister (PORTSC) 509
18.2. UCH 510 hostcontroller-datastructuren
18.2.1. Lijst met frames 510
18.2.2. Overdrachtsdescriptor i 511
18.2.3. Wachtrijkop 514
18.3. Een lijst met UCH 516-descriptoren verwerken
Hoofdstuk 19. Gereedschappen 518
19.1. Microsoft Visual Studio Tools 518
19.1.1. Hangt ervan af 518
19.1.2. Fout opzoeken 518
19.1.3. GuidGen 518
19.2. Microsoft DDK 520-hulpmiddelen
19.2.1. Apparaatboom 520
19.2.2. DevCon.-521
19.2.3. Chklnf en Genlnf. 526
19.3. CompuWare Corporation-hulpprogramma's 527
19.3.1. Monitor 527
19.3.2. SymLink 527
19.3.3. EzDriverlnstaller 527
19.3.4. WdmSniff 527
19.4. Betekent systeem 528
19.4.1. Winobj 528
19.5. USB-hulpmiddelen Forum 531
19.5.1. HID-descriptortool 531
19.6. HDD-software 533
19.7. Sourceforge-hulpmiddelen 533
TOEPASSINGEN 535
Bijlage 1. Extra functies 537
Bijlage 2. Tabel met taalidentificaties (LangID) 539
Bijlage 3. Tabel met fabrikantcodes (leveranciers-ID, apparaat-ID) 543
Bijlage 4. Beschrijving van de CD 546
Literatuur 548
Onderwerpindex 549