Interfață de programare a funcționării portului USB. Programare USB în Android. Folosim interfața USB pentru comunicare. Principalele proprietăți și evenimente ale clasei TJvHidDevice

Autobuzul USB (Universal Serial Bus) a apărut pe 15 ianuarie 1996, odată cu aprobarea primei versiuni a standardului de către Intel, DEC, IBM, NEC, Northen Telecom și Compaq.

Scopul principal al setului standard pentru dezvoltatorii săi este de a crea posibilitatea utilizatorilor de a lucra în modul Plug&Play cu dispozitive periferice. Aceasta înseamnă că trebuie să fie posibil să se conecteze dispozitivul la un computer care rulează, să-l recunoască automat imediat după conectare și apoi să se instaleze driverele corespunzătoare. În plus, este recomandabil să furnizați energie dispozitivelor de putere redusă din magistrala în sine. Viteza autobuzului ar trebui să fie suficientă pentru marea majoritate dispozitive periferice. Controler USB ar trebui să ia o singură întrerupere, indiferent de numărul de dispozitive conectate la magistrală, adică să rezolve problema lipsei de resurse pe plan intern. Autobuze IBM computer compatibil PC.

Aproape toate sarcinile au fost rezolvate în standardul USB și în primăvara anului 1997 calculatoare echipate cu conectori pt. conexiuni USB dispozitive. Acum, USB a devenit atât de activ implementat de producătorii de periferice pentru computer, încât, de exemplu, computerul iMAC de la Apple Computers are doar USB ca magistrală externă.

Capabilități USB 1.0 sunt după cum urmează:

1. viteză mare de transfer de date (viteză maximă) – 12 MB ea/Cu;

2. lungime maxima cablu pt de mare viteză schimb – 5 metri;

3. viteză scăzută de schimb de date (viteză mică) – 1,5 MB ea/Cu;

4. lungimea maximă a cablului pentru viteza scăzută de transfer de date este de 3 metri;

5. număr maxim de dispozitive conectate – 127;

6. posibilă conectare simultană a aparatelor cu cursuri de schimb diferite;

8. curent maxim consum pe dispozitiv – 500 mA.

Prin urmare, este recomandabil să conectați aproape orice dispozitiv periferic la USB 1.0, cu excepția camerelor video digitale și a camerelor de mare viteză. hard disk-uri. Această interfață este deosebit de convenabilă pentru conectarea dispozitivelor frecvent conectate/deconectate, cum ar fi camerele digitale.
Capacitatea de a utiliza doar două rate de date limitează capacitatea de utilizare a magistralei, dar reduce semnificativ numărul de linii de interfață și simplifică implementarea hardware.
Alimentarea directă de la USB este posibilă numai pentru dispozitivele cu consum redus, cum ar fi tastaturi, mouse-uri, joystick-uri etc.

Semnale USB sunt transmise printr-un cablu cu 4 fire, prezentat schematic în figura de mai jos:

Figura 2.6.1 – Semnal fire USB

Aici GND este circuitul firului comun pentru alimentarea dispozitivelor periferice, Vbus este +5 V și pentru circuitele de alimentare. Magistrala D+ este pentru transmiterea datelor pe magistrală, iar magistrala D este pentru primirea datelor.
Cablu suport viteza maxima anvelopele (viteză maximă) se execută ca pereche răsucită, este protejat de un ecran și poate fi folosit și pentru a funcționa în modul de viteză redusă. Un cablu pentru funcționare numai la viteză minimă (de exemplu, pentru a conecta un mouse) poate fi orice și neecranat.
Conectorii utilizați pentru conectarea dispozitivelor periferice sunt împărțiți în serii: Conectorii din seria „A” (ștecher și priză) sunt destinate numai pentru conectarea la o sursă, cum ar fi un computer, conectorii din seria „B” (mușcă și priză) sunt doar pentru conectare la un dispozitiv periferic.

Conectorii USB au următoarea numerotare a pinii, prezentată în Tabelul 2.6.1.

Tabelul 2.6.1 – Scopul și marcarea contactelor USB

În 1999, același consorțiu firme de calculatoare, care a inițiat dezvoltarea primei versiuni a standardului de magistrală USB, a început să dezvolte în mod activ versiunea 2.0 a USB, care se distinge prin introducerea unui mod suplimentar de mare viteză (Hi-speed). Lățimea de bandă a magistralei a fost mărită de 40 de ori, până la 480 Mbit/s, ceea ce a făcut posibilă transferul de date video prin USB.
Compatibil cu toate perifericele lansate anterior și cabluri de mare viteză este complet conservată. Controlerul standard 2.0 este deja integrat în setul logic al sistemului de dispozitive programabile (de exemplu, placa de baza computer personal).

În 2008 Companii Intel, Microsoft, Hewlett-Packard, Texas Instruments, NEC și NXP Semiconductors au creat specificația standard USB 3.0. În specificația USB 3.0, conectorii și cablurile standardului actualizat sunt compatibile fizic și funcțional cu USB 2.0, dar pe lângă cele patru linii de comunicație au mai fost adăugate patru. Cu toate acestea, noi contacte în conectori USB 3.0 sunt situate separat de cele vechi pe un rând de contact diferit. Specificația USB 3.0 mărește viteza maximă de transfer de informații la 5 Gbps - care este cu un ordin de mărime mai mare decât cei 480 Mbps pe care îi poate oferi USB 2.0. În plus, curentul maxim a fost crescut de la 500 mA la 900 mA per dispozitiv, permițându-vă să alimentați unele dispozitive care anterior necesitau o sursă de alimentare separată.

Să presupunem că ați dezvoltat un dispozitiv USB cu care trebuie să lucrați folosind un computer. Acest lucru se poate realiza în cel puțin două moduri:

1. dezvoltarea unui driver complet sistem de operare;

2. utilizarea interfeței clasa speciala Dispozitivele USB sunt numite dispozitive HID (Human Interface Device).

Prima metodă este universală: având suficiente cunoștințe în domeniul scrierii driverelor, îl puteți programa să funcționeze cu orice dispozitiv la orice viteză suportată de USB. Dar aceasta este o sarcină destul de dificilă.

A doua cale este următoarea. Există o interfață susținută de sistemele de operare moderne pentru dispozitive de interfață computer-om sau dispozitive HID, cum ar fi:

1. tastaturi, mouse-uri, joystick-uri;

2. diverși senzoriși cititori;

3. direcție și pedale pentru jocuri;

4. butoane, întrerupătoare, regulatoare.

Orice astfel de dispozitiv, dacă îndeplinește cerințele pentru dispozitivele HID, va fi recunoscut automat de sistem și nu va necesita scrierea de drivere speciale. În plus, programarea acestora este de obicei mult mai simplă decât scrierea unui driver de dispozitiv personalizat. Din păcate, această metodă are un dezavantaj semnificativ: viteza de schimb de informații cu dispozitivul HID este foarte limitată și se ridică la maximum 64 kB/s.

În principiu, pe baza tehnologiei HID, este posibilă organizarea interacțiunii cu orice dispozitiv, chiar dacă nu este în sens strict un dispozitiv de interfață om-calculator. Acest lucru elimină dezvoltarea consumatoare de timp a unui driver de dispozitiv unic și economisește timp la dezvoltarea unui nou dispozitiv USB. Pe partea gazdă, comunicarea cu dispozitivul va fi controlată de driverul HID standard inclus cu sistemul de operare. Trebuie doar să o faci din partea dispozitivului cerințe minime Protocol USB-HID.

Este de remarcat faptul că multe dispozitive USB, care la prima vedere nu se încadrează în definiția dispozitivelor de interacțiune umană, sunt încă mai logice pentru a fi implementate ca dispozitive HID. Acest fenomen este comun în domeniul echipamentelor de producție, care a cunoscut recent o adoptare masivă a tehnologiei USB. De exemplu, luați în considerare o sursă de alimentare de laborator cu capacitatea de a seta parametrii semnalelor sale de ieșire de la un computer folosind o interfață USB. Sursa de energie în sine nu este, fără îndoială, un mijloc de interacțiune cu o persoană. Cu toate acestea, în acest caz, funcțiile implementate printr-o conexiune USB dublează tastatura, comenzile și indicatorii instalați pe dispozitivul însuși. Și aceste controale se încadrează în definiția HID. În consecință, este cel mai logic să organizați o sursă de alimentare cu aceste funcții USB ca dispozitiv HID.

În exemplul considerat pentru funcționare normală O rată scăzută de transfer de date va fi suficientă în alte cazuri, dispozitivele pot fi foarte solicitante la cursul de schimb. Viteza redusă de transfer este principala limitare a opțiunii de proiectare a dispozitivului HID, care, în comparație cu viteza maximă de 12 Mbit/s a magistralei USB 1.0, arată ca un mare dezavantaj al tehnologiei HID în ceea ce privește alegerea unei implementări USB specifice. Cu toate acestea, pentru multe sarcini de comunicare, viteza specificată este destul de suficientă, iar arhitectura HID ca instrument specializat își ocupă locul cuvenit printre metodele de organizare a schimbului de date.

Există două tipuri de dispozitive HID: cele care participă (boot) și cele care nu participă la pornirea inițială a computerului. Cel mai izbitor exemplu de dispozitiv USB-HID bootabil este o tastatură, care începe să funcționeze când computerul pornește.

La proiectarea unui dispozitiv HID, trebuie îndeplinite următoarele cerințe de specificație:

1. Dispozitivul HID cu viteză maximă poate transfera 64000 de octeți la fiecare secundă sau 64 de octeți la fiecare 1 ms; Un dispozitiv HID de viteză redusă poate transfera până la 800 de octeți pe secundă sau 8 octeți la fiecare 10 ms.

2. Dispozitivul HID își poate programa frecvența de sondare pentru a determina dacă are date noi de transmis.

3. Schimbul de date cu dispozitivul HID se realizează printr-o structură specială numită raport. Fiecare raport definit poate conține până la 65535 de octeți de date. Structura raportului are o organizare foarte flexibilă care vă permite să descrieți orice format de transmitere a datelor. Pentru ca un anumit format de raport să devină cunoscut gazdei, microcontrolerul trebuie să conțină o descriere specială - un descriptor de raport.

Interacțiunea USB este implementată direct pe microcontroler în mai multe moduri:

1. folosind un controler cu suport hardware, de exemplu AT90USB*, de la atmega;

2. folosind emularea software a interfeței USB pe orice microcontroler.

Pentru implementarea software-ului există în prezent un număr de soluții gata făcute sub diverse familii microcontrolere. Pentru Microcontrolere AVR, de exemplu, Atmega8 este posibil să utilizați următoarele biblioteci gratuite în limbajul C:

Ambele sunt destul de ușor de utilizat, oferă o emulare completă a dispozitivelor USB 1.1 cu viteză redusă, cu excepția gestionării erorilor de comunicare și a caracteristicilor electrice și rulează pe aproape toate controlerele AVR cu cel puțin 2 kiloocteți de memorie flash, 128 de octeți de RAM și o frecvență de 12 până la 20 MHz.

Pentru a scrie aplicații care acceptă Windows USB Dispozitivele HID necesită fișierele de antet hid* incluse în WDK (Windows Driver Kit) sau puteți utiliza biblioteca hidlibrary disponibilă gratuit sau alta similară.

Astfel, în general, programarea USB este o sarcină destul de complexă, care necesită un microcontroler special cu suport hardware și scrierea unui driver de sistem de operare. Cu toate acestea, în practică, atunci când dezvoltați dispozitive, puteți utiliza o interfață de dispozitiv HID mult mai simplă, suport pentru care este implementat la nivelul unui driver de sistem standard, iar programarea este simplificată prin utilizarea bibliotecilor de funcții existente.

Întrebări de securitate

  1. Care este diferența dintre firele D- și GND din USB? De ce nu poți folosi un fir comun pentru alimentare și semnal?
  2. Câte moduri de viteză Funcționare USB există astăzi (inclusiv versiunea 3.0)?
  3. Ce este un dispozitiv HID? De ce nu necesită drivere de scriere pentru a funcționa în sistemele de operare moderne?
  4. Este posibil să implementați dispozitive USB folosind un microprocesor care nu are suport de interfață încorporat?
  5. Care sunt principalele diferențe dintre USB 3.0 și versiunile anterioare?

Dar nu este suficient doar să conectați fizic dispozitivul la computer, trebuie să stabiliți și un schimb de date între ei. Cum să alegi un port și să organizezi o conexiune? Acum câțiva ani soluție standard folosea un port COM. Apropo, diverși specialiști încă instalează 8, 16 sau chiar 32 de porturi COM pe computere industriale (există o întreagă categorie de diferite plăci de expansiune PCI pentru porturi seriale, controlere etc.). Astfel, dacă aveți nevoie să conectați mai multe dispozitive externe cu o interfață RS-232, este posibil să aveți nevoie de adaptoare scumpe și plăci de expansiune exotice, care, conform vechii tradiții, călătoresc în Rusia cu vaporul săptămâni întregi. Apropo, numele unui adaptor obișnuit „Adaptor DB9m/DB25f” poate provoca doar iritare pentru un manager de magazin de calculatoare.

Ce este un dispozitiv HID

În zilele noastre, aproape toate dispozitivele sunt conectate la un computer printr-o interfață USB. Prin urmare, multe PC-uri noi nu au deloc un port COM.

Interfață USB - o soluție tipică pentru conectarea unui nou dispozitiv extern cu un computer, mai exact, este o interfață HID bazată pe protocolul USB 1.1.

Deși mulți oameni cred că interfața HID (Human Interface Device) este destinată exclusiv tastaturii, mouse-ului și joystick-ului, este potrivită pentru multe soluții legate de asocierea dispozitivelor externe cu un computer.

Dacă utilizatorul trebuie să efectueze schimburi de date la viteză redusă (până la 64 kbit/s) și, în același timp, dorește să reducă timpul petrecut pentru dezvoltarea obositoare a propriilor drivere, atunci HID este destul de potrivit pentru el. Rezultatul final va fi o soluție simplă și complet modernă bazată pe o interfață software standard USB cu suport garantat pe toate platformele software comune.

Proprietăți dispozitiv HID

Din punct de vedere organizatoric suport software Dispozitive HID, totul pare destul de atractiv: pentru a lucra sub Control Windows puteți crea rapid cod ușor de înțeles, compact, bazat pe algoritmi gata făcuti și dovediți. În același timp, dezvoltatorul va avea la dispoziție mult timp pentru a-și implementa propriul protocol de schimb de date de nivel superior, deoarece nivelul de abstracție necesar este deja organizat prin protocolul HID (vezi tabel). În plus, este ușor pentru un programator să depaneze un protocol de schimb scris (desigur, dacă există un dispozitiv HID care funcționează) - datorită rigidității relative a protocolului în sine, este suficient să dezvolte pur și simplu un program de suport pentru computer pentru dispozitiv. Desigur! Creatorul dispozitivului HID a luat deja multă muncă.

Organizarea schimbului de date între dispozitivul HID și computer

Pentru a descrie interacțiunea unui dispozitiv HID cu un computer, vom folosi termenul „gazdă”. În acest caz, înseamnă dispozitiv de controlîn arhitectura fizică generală a interacțiunii prin protocolul USB. Deci, toate porturile de pe un computer sunt gazde. Puteți conecta diverse dispozitive USB (unități flash, șoareci, camere web, camere etc.) care nu au o gazdă pentru ele. Gazda oferă descoperirea dispozitivului, conexiunea, deconectarea, configurarea, precum și colectarea de statistici și gestionarea energiei.

Dispozitivul HID își poate seta propria frecvență de interogare pentru a determina dacă conține date noi. Aceasta înseamnă că, chiar și la un nivel atât de scăzut, programatorul poate avea încredere în sistem, deoarece frecvența de interogare și alți parametri de comunicare trebuie să fie prestabiliți în programul controlerului dispozitivului HID. Acesta este modul în care protocolul HID diferă descriere generală USB 1.1 sau USB 2.0, care nu are cerințe stricte de protocol. Cu toate acestea, pentru sarcini specifice care necesită un nivel crescut de securitate, poate fi destul de dificil să scapi de sondajele ciclice, când aproape aceleași blocuri de date sunt transmise în mod constant.

Caracteristici de programare a dispozitivului HID

Dispozitivele HID au descriptori speciali. Când gazda stabilește că dispozitivul aparține clasei HID, acesta transferă controlul acestuia către driverul corespunzător. Se presupune că un schimb suplimentar de date se realizează sub conducerea sa.

În Windows, este responsabil pentru accesarea dispozitivelor HID serviciul de sistem HidServ. Mai multe detalii despre funcțiile solicitărilor către dispozitivele HID și alte caracteristici ale lucrului cu driverul HID sunt descrise în lucrarea lui P. V. Agurov „Interfața USB. Practică de utilizare și programare” (Sankt. Petersburg: BHV-Petersburg, 2005).

Programarea dispozitivelor HID la „nivelul superior”

Viața grea a programatorilor de „aplicații” care lucrează în Pascal este simplificată de modulul HID dovedit. PAS, software shell pentru hid. dll (Hid User Library - așa cum este specificat în proprietățile fișierului). Comentariile la fișier indică faptul că acesta se bazează pe modulele hidsdi.h și hidpi.h de la Microsoft. Și fișierul HID în sine. PAS face parte din pachetul JEDI().

Pentru a lucra cu un dispozitiv HID în mediul Delphi pentru win32, este utilizată componenta TJvHidDeviceController, care este un manager global convenabil pentru accesarea dispozitivelor HID. Și deja pe baza sa puteți obține o instanță de obiect pentru a lucra cu un anumit dispozitiv.

Proprietățile și evenimentele de bază ale componentei TJvHidDeviceController

Să ne uităm la componenta TJvHidDeviceController mai detaliat. Evenimentul OnArrival este declanșat atunci când un dispozitiv HID sosește (se conectează) la sistem, accesul la dispozitiv este oferit în handlerul acestui eveniment printr-o instanță a clasei TJvHidDevice. Evenimentul simplu OnDeviceChange reacționează la schimbările în starea dispozitivului, semnalează doar schimbări în sistem. Evenimentul OnDeviceData este declanșat atunci când datele sosesc de la unul dintre dispozitivele HID și transmit următoarele operatorului: HidDev: TJvHidDevice; - dispozitivul de la care au fost primite datele;

Evenimentul OnDeviceDataError notifică o eroare de transfer de date prin transmiterea parametrilor HidDev la procedura de procesare: TJvHidDevice; - Dispozitiv HID și Eroare: DWORD; - cod de eroare. Evenimentul OnDeviceUnplug notifică faptul că un dispozitiv este eliminat din lista celor instalate pe sistem. Tipurile de gestionare a evenimentelor de pe Plug and Unplug sunt aceleași (în textul sursă: TJvHidUnplugEvent = TJvHidPlugEvent). Un obiect din clasa TJvHidDevice care corespunde dispozitivului HID este transmis handler-ului.

Pentru a enumera secvențial dispozitivele HID disponibile în sistem prin apelarea metodei Enumerate, este intenționat evenimentul OnEnumerate, adică în handlerul de evenimente, dispozitivele găsite sunt transferate secvenţial ca obiecte. Acest eveniment este forțat de metoda Enumerate, care este folosită pentru a „trece” dispozitivele HID existente printr-un handler, de exemplu, la revizuirea stării dispozitivelor HID la inițiativa gazdei (calculatorului).

Evenimentul OnRemoval este declanșat atunci când un dispozitiv este eliminat fizic din sistem și are același tip de handler TJvHidUnplugEvent ca și pentru OnDeviceUnplug. Funcția CountByProductName returnează numărul de dispozitive care se potrivesc cu numele produsului specificat în argument, iar CountByVendorName returnează numele producătorului specificat în argument.

Principalele proprietăți și evenimente ale clasei TJvHidDevice

Clasa TJvHidDevice este o reprezentare virtuală a unui singur dispozitiv HID. Un nou obiect al acestei clase poate fi obținut, după cum sa menționat deja, din evenimentul OnArrival sau OnEnumerate. Funcționalitatea claselor TJvHidDeviceController și TJvHidDevice este parțial duplicată, deoarece prima dintre ele integrează instrumente comune pentru lucrul cu un set de dispozitive HID disponibile în sistem și un mecanism de accesare a unuia dintre ele. Un dispozitiv poate fi identificat în mod unic prin proprietățile sale SerialNumber, ProductName și VendorName. Pentru a obține informații despre sosirea datelor folosind un astfel de obiect, puteți utiliza evenimentul OnData. Datele sunt trimise prin metoda WriteFile (în sens strict - printr-o funcție). WriteFile este un înveliș în jurul funcției de sistem WriteFile (kernel32).

Pentru a controla dacă dispozitivul a fost eliminat, ar trebui să atribuiți propriul dvs. handler evenimentului OnUnplug. Înainte de a începe să faceți schimb de date cu un dispozitiv HID, trebuie să vă asigurați că acest schimb este posibil utilizând HasReadWriteAccess. Această clasă are chiar și un eveniment OnDataError separat atunci când apare o eroare de schimb de date.

Acum să ne uităm la fragmentele de cod dintr-un proiect „în direct” care implementează o aplicație client de testare pentru organizarea schimbului de date cu un dispozitiv nestandard - carduri cu cip din plastic bazate pe HID. În lupta pentru realism, autorul și-a luat libertatea de a nu arunca conexiunile de cod tehnologic „extra” din listări.

Metoda ScanDevices (Listarea 1) are scopul de a iniția procesul de căutare în sistem a dispozitivului HID necesar. Majoritatea codului, cu excepția apelului la metoda Enumerate, este opțional și oferă flexibilitate aplicației, de exemplu, astfel încât capacitatea de a lucra pe o interfață non-HID ar putea fi adăugată aceluiași program de testare. Metoda AddError afișează informații de depanare în fereastră în timp ce programul rulează.

Lista 2 arată un handler de evenimente OnEnumerate pentru a găsi dispozitivul extern necesar. Pentru simplitate, vom presupune că programul poate funcționa doar cu un singur dispozitiv de tipul de care are nevoie.

Înainte de a lua în considerare implementarea ulterioară a proiectului, ar trebui să vorbim puțin despre formatul de schimb de date de nivel superior adoptat, adică despre structura menită să fie un intermediar între metodele de primire și transmitere a datelor și problema specifică a aplicației care se rezolvă. Faptul este că aici dezvoltatorului i se oferă posibilitatea de a-și realiza abilitățile creative. Sau, mai degrabă, dezvoltatorii, pentru că procesul de creare a unui nou protocol este de multe ori bidirecțional, iar prima lăutară este jucată de cel căruia îi este mai greu să implementeze algoritmul de schimb. În general, indiferent de protocolul de schimb, este întotdeauna plăcut să facem fiecare entitate software cât mai vizuală și autosuficientă posibil, chiar și în detrimentul unor tradiții general acceptate. Pentru cea mai buna solutie- ceva ce va fi implementat în scurt timp cu conexiune minimă la mediul software și cu mari oportunități de dezvoltare ulterioară. Pe baza acestor principii, a fost creat un protocol de schimb de nivel superior, unde conceptul principal este „comandă”. Lista 3 arată cât de mult iubesc autorul datele șir, ceea ce l-a salvat de mai multe ori atunci când depanează modulele programului. Ce minunat este că avem chiar și un tip String! Toate comenzile de protocol sunt împărțite în categorii (clase), în cadrul cărora există un cod de comandă care îi caracterizează în mod unic scopul. Parametrul edParam este utilizat pentru a trimite date către dispozitiv, iar parametrul edAnswerData conține date primite de la dispozitiv. Tipul de șir al membrilor de înregistrare descriși vă permite să manipulați liber și clar datele în format șir HEX. Și ceea ce este cel mai bun este că formatul înregistrării descrise se situează ideologic undeva la mijloc între scopul său direct și diferitele forme de prezentare (INI, HEX, XML etc.)

Executarea comenzii, adică trimiterea datelor către dispozitiv, este implementată utilizând trimiterea de pachete de date cu lungimea de 8 octeți (Listing 4). Această lungime nu este singura soluție; această alegere este dictată de cerințele protocolului de nivel superior și poate fi diferită în fiecare caz specific. Aceasta este, după cum se spune, o chestiune de gust. Steagul ciudat IsUSBMode din metoda ExecuteCommand (Listing 5 în PC World) este lăsat ca un memento că este posibil să fie nevoie să folosim un port COM sau o altă interfață în loc să lucrăm cu USB. La începutul grupului de date trimis, o serie de sincronizare a unui format selectat aleatoriu (de exemplu, 3E3E3E2B) este transmisă dispozitivului, informând dispozitivul că are date complet legale la intrare. Permiteți-mi să vă reamintesc că în acest caz vorbim nu atât de HID, ci de un protocol specific de nivel superior, separat ideologic de hardware și menit să rezolve probleme speciale de aplicație.

Managerul GetDataExecutor pentru datele primite de la dispozitiv (un pachet de 8 octeți) utilizează un eveniment OnNewInputData special creat pentru a transfera datele procesate inițial pentru procesare ulterioară, indicând valorile lor vechi și noi (Lista 6 pe „World of PC Disk ”). În acest fel, evenimentele de sosire a datelor brute și indicațiile pentru procesarea ulterioară sunt decuplate, permițând adăugarea din timp a unui algoritm specific pentru a avertiza împotriva informațiilor de intrare eronate, duplicate sau inutile.

Exemplele de lucru cu un dispozitiv HID prezentate aici ilustrează ideea generală a articolului - ușurința relativă de a programa dispozitive HID non-standard folosind Delphi.

Dar nu este suficient doar să conectați fizic dispozitivul la computer, trebuie să stabiliți și un schimb de date între ei. Cum să alegi un port și să organizezi o conexiune? În urmă cu câțiva ani, soluția standard era utilizarea unui port COM. Apropo, diverși specialiști încă instalează 8, 16 sau chiar 32 de porturi COM pe computere industriale (există o întreagă categorie de diferite plăci de expansiune PCI pentru porturi seriale, controlere etc.). Astfel, dacă aveți nevoie să conectați mai multe dispozitive externe cu o interfață RS-232, este posibil să aveți nevoie de adaptoare scumpe și plăci de expansiune exotice, care, conform vechii tradiții, călătoresc în Rusia cu vaporul săptămâni întregi. Apropo, numele unui adaptor obișnuit „Adaptor DB9m/DB25f” poate provoca doar iritare pentru un manager de magazin de calculatoare.

Ce este un dispozitiv HID

În zilele noastre, aproape toate dispozitivele sunt conectate la un computer printr-o interfață USB. Prin urmare, multe PC-uri noi nu au deloc un port COM.

Interfața USB este o soluție standard pentru asocierea unui nou dispozitiv extern cu un computer, mai precis, este o interfață HID bazată pe protocolul USB 1.1.

Deși mulți oameni cred că interfața HID (Human Interface Device) este destinată exclusiv tastaturii, mouse-ului și joystick-ului, este potrivită pentru multe soluții legate de asocierea dispozitivelor externe cu un computer.

Dacă utilizatorul trebuie să efectueze schimburi de date la viteză redusă (până la 64 kbit/s) și, în același timp, dorește să reducă timpul petrecut pentru dezvoltarea obositoare a propriilor drivere, atunci HID este destul de potrivit pentru el. Rezultatul final va fi o soluție simplă și complet modernă bazată pe o interfață software standard USB cu suport garantat pe toate platformele software comune.

Proprietăți dispozitiv HID

Din punctul de vedere al organizării suportului software pentru un dispozitiv HID, totul pare destul de atractiv: pentru a lucra sub Windows, puteți crea rapid cod ușor de înțeles, compact, bazat pe algoritmi dovediți. În același timp, dezvoltatorul va avea la dispoziție mult timp pentru a-și implementa propriul protocol de schimb de date de nivel superior, deoarece nivelul de abstracție necesar este deja organizat prin protocolul HID (vezi tabel). În plus, este ușor pentru un programator să depaneze un protocol de schimb scris (desigur, dacă există un dispozitiv HID care funcționează) - datorită rigidității relative a protocolului în sine, este suficient să dezvolte pur și simplu un program de suport pentru computer pentru dispozitiv. Desigur! Creatorul dispozitivului HID a luat deja multă muncă.

Organizarea schimbului de date între dispozitivul HID și computer

Pentru a descrie interacțiunea unui dispozitiv HID cu un computer, vom folosi termenul „gazdă”. În acest caz, este înțeles ca un dispozitiv de control în arhitectura fizică generală a interacțiunii prin protocolul USB. Deci, toate porturile de pe un computer sunt gazde. Puteți conecta diverse dispozitive USB (unități flash, șoareci, camere web, camere etc.) care nu au o gazdă pentru ele. Gazda oferă descoperirea dispozitivului, conexiunea, deconectarea, configurarea, precum și colectarea de statistici și gestionarea energiei.

Dispozitivul HID își poate seta propria frecvență de interogare pentru a determina dacă conține date noi. Aceasta înseamnă că, chiar și la un nivel atât de scăzut, programatorul poate avea încredere în sistem, deoarece frecvența de interogare și alți parametri de comunicare trebuie să fie prestabiliți în programul controlerului dispozitivului HID. Acesta este modul în care protocolul HID diferă de general Descrieri USB 1.1 sau USB 2.0, care nu are cerințe stricte pentru organizarea protocolului. Cu toate acestea, pentru sarcini specifice care necesită un nivel crescut de securitate, poate fi destul de dificil să scapi de sondajele ciclice, când aproape aceleași blocuri de date sunt transmise în mod constant.

Caracteristici de programare a dispozitivului HID

Dispozitivele HID au descriptori speciali. Când gazda stabilește că dispozitivul aparține clasei HID, acesta transferă controlul acestuia către driverul corespunzător. Se presupune că un schimb suplimentar de date se realizează sub conducerea sa.

În Windows, serviciul de sistem HidServ este responsabil pentru accesarea dispozitivelor HID. Mai multe detalii despre funcțiile solicitărilor către dispozitivele HID și alte caracteristici ale lucrului cu driverul HID sunt descrise în lucrarea lui P. V. Agurov „Interfața USB. Practică de utilizare și programare” (Sankt. Petersburg: BHV-Petersburg, 2005).

Programarea dispozitivelor HID la „nivelul superior”

Viața grea a programatorilor de „aplicații” care lucrează în Pascal este simplificată de modulul HID dovedit. PAS, software shell pentru hid. dll (Hid User Library - așa cum este specificat în proprietățile fișierului). Comentariile la fișier indică faptul că acesta se bazează pe modulele hidsdi.h și hidpi.h de la Microsoft. Și fișierul HID în sine. PAS face parte din pachetul JEDI().

Pentru a lucra cu un dispozitiv HID în mediul Delphi pentru win32, este utilizată componenta TJvHidDeviceController, care este un manager global convenabil pentru accesarea dispozitivelor HID. Și deja pe baza sa puteți obține o instanță de obiect pentru a lucra cu un anumit dispozitiv.

Proprietățile și evenimentele de bază ale componentei TJvHidDeviceController

Să ne uităm la componenta TJvHidDeviceController mai detaliat. Evenimentul OnArrival este declanșat atunci când un dispozitiv HID sosește (se conectează) la sistem, accesul la dispozitiv este oferit în handlerul acestui eveniment printr-o instanță a clasei TJvHidDevice. Evenimentul simplu OnDeviceChange reacționează la schimbările în starea dispozitivului, semnalează doar schimbări în sistem. Evenimentul OnDeviceData este declanșat atunci când datele sosesc de la unul dintre dispozitivele HID și transmit următoarele operatorului: HidDev: TJvHidDevice; - dispozitivul de la care au fost primite datele;

Evenimentul OnDeviceDataError notifică o eroare de transfer de date prin transmiterea parametrilor HidDev la procedura de procesare: TJvHidDevice; - Dispozitiv HID și Eroare: DWORD; - cod de eroare. Evenimentul OnDeviceUnplug notifică faptul că un dispozitiv este eliminat din lista celor instalate pe sistem. Tipurile de gestionare a evenimentelor de pe Plug and Unplug sunt aceleași (în textul sursă: TJvHidUnplugEvent = TJvHidPlugEvent). Un obiect din clasa TJvHidDevice care corespunde dispozitivului HID este transmis handler-ului.

Pentru a enumera secvențial dispozitivele HID disponibile în sistem prin apelarea metodei Enumerate, este intenționat evenimentul OnEnumerate, adică în handlerul de evenimente, dispozitivele găsite sunt transferate secvenţial ca obiecte. Acest eveniment este forțat de metoda Enumerate, care este folosită pentru a „trece” dispozitivele HID existente printr-un handler, de exemplu, la revizuirea stării dispozitivelor HID la inițiativa gazdei (calculatorului).

Evenimentul OnRemoval este declanșat atunci când un dispozitiv este eliminat fizic din sistem și are același tip de handler TJvHidUnplugEvent ca și pentru OnDeviceUnplug. Funcția CountByProductName returnează numărul de dispozitive care se potrivesc cu numele produsului specificat în argument, iar CountByVendorName returnează numele producătorului specificat în argument.

Principalele proprietăți și evenimente ale clasei TJvHidDevice

Clasa TJvHidDevice este o reprezentare virtuală a unui singur dispozitiv HID. Un nou obiect al acestei clase poate fi obținut, după cum sa menționat deja, din evenimentul OnArrival sau OnEnumerate. Funcționalitatea claselor TJvHidDeviceController și TJvHidDevice este parțial duplicată, deoarece prima dintre ele integrează instrumente comune pentru lucrul cu un set de dispozitive HID disponibile în sistem și un mecanism de accesare a unuia dintre ele. Un dispozitiv poate fi identificat în mod unic prin proprietățile sale SerialNumber, ProductName și VendorName. Pentru a obține informații despre sosirea datelor folosind un astfel de obiect, puteți utiliza evenimentul OnData. Datele sunt trimise prin metoda WriteFile (în sens strict - printr-o funcție). WriteFile este un înveliș în jurul funcției de sistem WriteFile (kernel32).

Pentru a controla dacă dispozitivul a fost eliminat, ar trebui să atribuiți propriul dvs. handler evenimentului OnUnplug. Înainte de a începe să faceți schimb de date cu un dispozitiv HID, trebuie să vă asigurați că acest schimb este posibil utilizând HasReadWriteAccess. Această clasă are chiar și un eveniment OnDataError separat atunci când apare o eroare de schimb de date.

Acum să ne uităm la fragmentele de cod dintr-un proiect „în direct” care implementează o aplicație client de testare pentru organizarea schimbului de date cu un dispozitiv nestandard - carduri cu cip din plastic bazate pe HID. În lupta pentru realism, autorul și-a luat libertatea de a nu arunca conexiunile de cod tehnologic „extra” din listări.

Metoda ScanDevices (Listarea 1) are scopul de a iniția procesul de căutare în sistem a dispozitivului HID necesar. Majoritatea codului, cu excepția apelului la metoda Enumerate, este opțional și oferă flexibilitate aplicației, de exemplu, astfel încât capacitatea de a lucra pe o interfață non-HID ar putea fi adăugată aceluiași program de testare. Metoda AddError afișează informații de depanare în fereastră în timp ce programul rulează.

Lista 2 arată un handler de evenimente OnEnumerate pentru a găsi dispozitivul extern necesar. Pentru simplitate, vom presupune că programul poate funcționa doar cu un singur dispozitiv de tipul de care are nevoie.

Înainte de a lua în considerare implementarea ulterioară a proiectului, ar trebui să vorbim puțin despre formatul de schimb de date de nivel superior adoptat, adică despre structura menită să fie un intermediar între metodele de primire și transmitere a datelor și problema specifică a aplicației care se rezolvă. Faptul este că aici dezvoltatorului i se oferă posibilitatea de a-și realiza abilitățile creative. Sau, mai degrabă, dezvoltatorii, pentru că procesul de creare a unui nou protocol este de multe ori bidirecțional, iar prima lăutară este jucată de cel căruia îi este mai greu să implementeze algoritmul de schimb. În general, indiferent de protocolul de schimb, este întotdeauna plăcut să facem fiecare entitate software cât mai vizuală și autosuficientă posibil, chiar și în detrimentul unor tradiții general acceptate. Pentru că cea mai bună soluție este cea care va fi implementată într-un timp scurt cu conexiune minimă la mediul software și cu mari oportunități de dezvoltare ulterioară. Pe baza acestor principii, a fost creat un protocol de schimb de nivel superior, unde conceptul principal este „comandă”. Lista 3 arată cât de mult iubesc autorul datele șir, ceea ce l-a salvat de mai multe ori atunci când depanează modulele programului. Ce minunat este că avem chiar și un tip String! Toate comenzile de protocol sunt împărțite în categorii (clase), în cadrul cărora există un cod de comandă care îi caracterizează în mod unic scopul. Parametrul edParam este utilizat pentru a trimite date către dispozitiv, iar parametrul edAnswerData conține date primite de la dispozitiv. Tipul de șir al membrilor de înregistrare descriși vă permite să manipulați liber și clar datele în format șir HEX. Și ceea ce este cel mai bun este că formatul înregistrării descrise se situează ideologic undeva la mijloc între scopul său direct și diferitele forme de prezentare (INI, HEX, XML etc.)

Executarea comenzii, adică trimiterea datelor către dispozitiv, este implementată utilizând trimiterea de pachete de date cu lungimea de 8 octeți (Listing 4). Această lungime nu este singura soluție; această alegere este dictată de cerințele protocolului de nivel superior și poate fi diferită în fiecare caz specific. Aceasta este, după cum se spune, o chestiune de gust. Steagul ciudat IsUSBMode din metoda ExecuteCommand (Listing 5 în PC World) este lăsat ca un memento că este posibil să fie nevoie să folosim un port COM sau o altă interfață în loc să lucrăm cu USB. La începutul grupului de date trimis, o serie de sincronizare a unui format selectat aleatoriu (de exemplu, 3E3E3E2B) este transmisă dispozitivului, informând dispozitivul că are date complet legale la intrare. Permiteți-mi să vă reamintesc că în acest caz vorbim nu atât de HID, ci de un protocol specific de nivel superior, separat ideologic de hardware și menit să rezolve probleme speciale de aplicație.

Managerul GetDataExecutor pentru datele primite de la dispozitiv (un pachet de 8 octeți) utilizează un eveniment OnNewInputData special creat pentru a transfera datele procesate inițial pentru procesare ulterioară, indicând valorile lor vechi și noi (Lista 6 pe „World of PC Disk ”). În acest fel, evenimentele de sosire a datelor brute și indicațiile pentru procesarea ulterioară sunt decuplate, permițând adăugarea din timp a unui algoritm specific pentru a avertiza împotriva informațiilor de intrare eronate, duplicate sau inutile.

Exemplele de lucru cu un dispozitiv HID prezentate aici ilustrează ideea generală a articolului - ușurința relativă de a programa dispozitive HID non-standard folosind Delphi.


Fig.1 Ilustrație a modului în care funcționează un dispozitiv Android moduri USB Gazdă și accesoriu (imagine de la http://developer.android.com)

Rețineți că utilizarea USB nu este singura modalitate de a comunica cu același dispozitiv de casă. De asemenea, Android vă permite să utilizați NFC, Wi-Fi P2P, SIP, precum și standard conexiune la rețea. Deci, dezvoltatorul are suficiente oportunități în arsenalul său pentru a-și realiza cele mai nebunești idei.

O altă opțiune comună de comunicare este diverse dispozitive este încă în uz Adaptor USB-COM. Există materiale pe Internet despre utilizarea unui adaptor USB-COM în Android - vezi, de exemplu,. Popularitatea acestei conexiuni se datorează prezenței cantitate mare dispozitive deja dezvoltate folosind diferite microcontrolere, comunicarea cu care se realizează folosind un port COM (port serial), care acum 10 ani era aproape într-un mod standard transferați date de la un computer la o piesă hardware de casă.

În comparație cu un port COM, utilizarea USB poate crește semnificativ vitezele de transfer de date și poate face acest proces mai ușor de utilizat. Viteza de transmisie, care chiar și în cazul dispozitivelor cu viteză redusă (tastaturi, mouse, joystick-uri), este de 10-1500 Kbps, simplitatea și costul redus al sistemului de cablu și conexiuni, autoidentificare a dispozitivelor cu configurație automată, ascunderea detaliilor conexiune electrică de la utilizatorul final (plus capacitatea de a deconecta cablul fără a opri dispozitivele), controlul erorilor și recuperarea erorilor la nivel de protocol - acestea sunt avantajele incontestabile ale acestei tehnologii (vezi, p. 12).

În general, vorbind despre utilizarea USB pentru transferul de date, ar fi util să menționăm cartea lui P. Agurov „Interfața USB”. Deși este adesea criticat pe Internet și a fost lansat ultima dată în 2006, a ajutat de mai multe ori la găsirea soluției potrivite atunci când se caută informații despre diverse aspecte ale aplicării acestei tehnologii. Cartea acoperă probleme de la alegerea unui microcircuit și design de circuit pentru controler până la scrierea unui program de microcontroler și exemple de programare a transferului de date prin protocolul USB de la computer. Este imposibil să nu indicați „sursa primară” de date cu privire la această problemă - site-ul web al organizației non-profit USB IF (USB Implementers Forum), care dezvoltă specificații pentru această interfață -, Adevărul acest material pe engleză. Cu toate acestea, acolo veți găsi informații complete despre dispozitivul de interfață USB. Există o traducere bună a unor părți ale specificației - . Cei interesați de soluții software din partea microcontrolerului pot vedea și linkul.

Acest articol se adresează în primul rând celor care au orice dispozitiv electronic (dezvoltat independent sau de altcineva), protocolul de schimb de date cu care este bine cunoscut (de exemplu, există deja un program care funcționează cu acest dispozitiv în Windows/Linux) și aș dori să am un program care să funcționeze cu el în Android.

Câteva despre clasele de dispozitive USB

Trebuie remarcat faptul că dezvoltarea software pentru a comunica cu un dispozitiv specific depinde foarte mult de implementarea acestuia la nivel de microcontroler. Din motive evidente, este imposibil să furnizați exemple de programe de comunicare pentru toate tipurile de dispozitive USB într-un articol (informații inițiale despre programare diverse tipuri dispozitivele pot fi găsite în). Cu toate acestea, ne vom limita la prezentarea codului care implementează căutarea dispozitivelor și accesul la punctele sale de control pentru schimbul de informații. De asemenea, vom analiza trimiterea datelor folosind exemplul unuia dintre tipurile de dispozitive USB, și anume, clasa de dispozitive HID (human interface device). Această clasă include dispozitive „lente”, cum ar fi o tastatură, un mouse, un joystick și există o mulțime de exemple de implementare a acesteia folosind diferite microcontrolere în rețea (există, de exemplu, în).

De ce este clasa HID atât de populară printre producătorii de diverse dispozitive de casă? Pentru a cita Wikipedia: „Pe lângă specificațiile detaliate ale dispozitivelor de intrare clasice (cum ar fi tastaturile și mouse-urile), standardul HID definește o clasă specială de dispozitive fără specificații detaliate. Această clasă se numește USB HID Consumer Control și este în esență un canal de comunicare nereglementat cu un dispozitiv. În acest caz, dispozitivul utilizează aceleași drivere standard pentru sistemul de operare ca și mouse-ul și tastatura. Deci poți crea dispozitiv USB care nu necesită crearea și instalarea de drivere speciale în cele mai comune sisteme de operare pentru computere.” Rămâne doar să adăugăm că această specificație funcționează și în sistemul de operare Android (nu exclude firmware-ul CyanogenMod).

Una dintre opțiunile pentru schimbul de date cu un dispozitiv HID este transferul de întrerupere, care este utilizat atunci când este necesar să transferați pachete de date mici (dimensiunea maximă a pachetului depinde de rata de transfer și variază de la 64 la 1024 de octeți) după un interval de timp specificat . Pachetul pentru transmitere se numește raport (în engleză - report, vezi pp. 71, 95). Această lungime a unui raport este de obicei suficientă pentru a face schimb de informații cu un dispozitiv de casă 64 de octeți de informații într-un pachet, de exemplu, este destul de mult pentru un controler, deoarece 1 bit de informații este suficient pentru a transmite stările unui LED; sau un simplu senzor.

Instrumente necesare

Deci, vom avea nevoie de o tabletă sau un telefon cu versiunea Android nu mai mică de 3.1. Trebuie remarcat aici că API-ul USB Host de mai sus nu este implementat pe deplin pe toate dispozitivele mobile (acest lucru este menționat și pe site-ul web developer.android.com, vezi linkul). Pe unele tablete/telefoane, conectorul USB este folosit doar pentru încărcare și comunicare cu computer personal. Încă o dată voi trimite cititorul la lista de dispozitive mobile potrivite sau nepotrivite experimentelor noastre (vezi).

Veți avea nevoie și de un fel de dispozitiv USB (pentru primele experimente, o unitate flash USB obișnuită va fi suficientă), Adaptor OTG(On-The-Go - vezi Fig. 2) și/sau un cablu USB pentru conectarea la dispozitiv. Wikipedia spune despre OTG: „La conectarea prin USB OTG, rangul dispozitivului (master sau slave) este determinat de prezența sau absența unui jumper între pinii 4 și 5 din mufa cablului de conectare. Într-un cablu USB OTG, un astfel de jumper este instalat doar într-unul dintre cei doi conectori (vezi). În consecință, avem nevoie de un astfel de jumper pe partea laterală a dispozitivului mobil.


Fig.2 Diferențele în circuitul unui cablu USB obișnuit și al unui cablu OTG (imagine de la http://tech.firstpost.com)

Puteți lipi singur un astfel de cablu OTG pentru dispozitivul dvs. Pentru a face acest lucru, trebuie să cumpărați un conector adecvat la un magazin de radio, plus autorul, de exemplu, a folosit un cablu vechi de pe un hard disk portabil:

De asemenea, va fi de un bun ajutor în munca ta program USB Informații despre dispozitiv instalate de la Stocare Google Play Market. Programul poate detecta dispozitivele conectate la conectorul USB al unei tablete/telefon folosind atât API-ul Java, cât și Kernel-urile Linux. Adică, dacă dispozitivul dvs. nu este detectat utilizând Java USB Host API în USB Device Info, atunci, cel mai probabil, va fi în zadar să utilizați orice program Android (inclusiv propriul dvs.) scris folosind Java pentru acest dispozitiv mobil și USB Host. API.

Uneori, informațiile transmise de comanda de operare lsusb sunt, de asemenea, foarte utile. sisteme Linux. Cu comutatoarele -v și -d, lsusb afișează totul, sau aproape totul, despre un dispozitiv USB de care un dezvoltator de software are nevoie pentru dispozitivele din această clasă (vezi Fig. 3).


Fig.3 Exemplu de ieșire a comenzilor lsusb și lsusb -v -d

Apoi, aveți nevoie de un computer cu instalat Android SDK și mediul de dezvoltare integrat (IDE) Eclipse cu pluginul ADT (deși vă puteți descurca doar cu SDK-ul). Puteți vedea cum să creați și să instalați o aplicație pentru Android, de exemplu, în sau pe Internet.

Și, desigur, ai nevoie de cel puțin dorința de a obține rezultate, fără ea nu poți! Remarc că pentru a clarifica unii probleme tehnice Utilizarea de către autor a USB-ului în Android a necesitat săptămâni de căutare minuțioasă a informațiilor.

Clasele Java pentru lucrul cu USB în API-ul Android

Deci, așa cum se spune pe site-ul web al dezvoltatorilor USB Host API pentru Android (vezi) - „înainte de a începe, este important să înțelegeți ce clase veți folosi în munca dvs.”. Tabelul 1 oferă o descriere a celor mai importante clase pentru lucrul cu USB Host API (o încercare de a traduce informații de la http://developer.android.com).

Tabelul 1. Descrierea claselor pentru lucrul cu USB în Android

Numele clasei Descriere
USBManager Vă permite să enumerați și să comunicați cu dispozitivele USB conectate.
Vă permite să detectați un dispozitiv USB conectat și să faceți schimb de date cu acesta.
Dispozitiv USB Reprezintă un dispozitiv USB conectat și conține metode de acces la informațiile de identificare, interfețele și punctele finale ale acestuia.
Reprezintă un dispozitiv USB conectat și conține metode de acces la identitatea, interfețele și punctele finale ale acestuia.
Interfață USB Reprezintă o interfață a unui dispozitiv USB, care definește un set de funcționalități pentru dispozitiv. Un dispozitiv poate avea una sau mai multe interfețe pe care să comunice.
Reprezintă „interfața” unui dispozitiv USB, care definește setul de funcții pentru acel dispozitiv. Un dispozitiv poate avea una sau mai multe interfețe pentru schimbul de informații.
USBEndpoint Reprezintă un punct final de interfață, care este un canal de comunicare pentru această interfață. O interfață poate avea unul sau mai multe puncte finale și, de obicei, are puncte finale de intrare și ieșire pentru comunicarea bidirecțională cu dispozitivul.
Reprezintă „punctul final” al unei interfețe, care este canalul de comunicare pentru acea interfață. O interfață poate avea unul sau mai multe puncte finale și, de obicei, are puncte finale pentru primirea informațiilor și pentru transmiterea acesteia.
USBDeviceConnection Reprezintă o conexiune la dispozitiv, care transferă date la punctele finale. Această clasă vă permite să trimiteți date înainte și înapoi sincron sau asincron.
Reprezintă „conexiune” la acest dispozitiv. Necesar pentru a transfera date la punctul final. Această clasă vă permite să primiți sau să transmiteți date sincron sau asincron.
Solicitare USB Reprezintă o solicitare asincronă de a comunica cu un dispozitiv printr-o conexiune UsbDevice.
Reprezintă o solicitare asincronă de a comunica cu un dispozitiv printr-o conexiune UsbDevice.
USBConstants Definește constantele USB care corespund definițiilor din linux/usb/ch9.h ale nucleului Linux..
Definește constante care corespund definițiilor din linux/usb/ch9.h ale nucleului Linux.

În aproape toate cazurile de utilizare a USB Host API, programatorul folosește aceste clase în munca sa. Algoritmul pentru utilizarea lor arată cam așa: definim dispozitivele (scopul este acces programatic la clasa UsbDevice) conectat la gazdă ( dispozitiv mobil), folosind USBManager. Când se obține accesul software la un dispozitiv, este necesar să se determine interfața și punctul de terminare Usb corespunzătoare pentru a comunica cu acesta. După ce aveți punctul final în posesia dvs., deschideți UsbDeviceConnection pentru a comunica cu dispozitivul USB. Dacă punctul final funcționează în modul de transfer asincron, folosim clasa UsbRequest.

Să încercăm să înțelegem totul creând o aplicație simplă care, folosind acest API, va determina ce este conectat la gazdă cu sistemul de operare dispozitiv Androidși va afișa câteva informații despre acesta pe ecranul telefonului sau al tabletei.

Creați un proiect

În Eclipse, un proiect este creat folosind elementele de meniu File->New->Android Application Project. De asemenea, rețineți că codul de mai jos este împrumutat din exemple de aplicații furnizate cu Android SDK (dosar Android sdk samples/android-N(API Level)/USB) vorbim despre programul de control al jucăriilor USB Missile Launcher (vezi Fig. 4) Exemplu aplicațiile sunt descărcate prin Android SDK Manager (bifați caseta - Samples for SDK). În listele de mai jos, exemplele de cod sunt furnizate cu comentarii care explică ce se întâmplă.


Fig.4 Jucărie distractivă „Lansatorul de rachete”

Când creați un proiect, nu uitați să verificați nivelul API necesar în opțiunea Minimum Requared SDK (nivelul API 12, corespunzător versiuni Android 3.1 /Fagure/, sau mai mare). Proiectul va avea o interfață de utilizator foarte simplă - fereastra principală (Activitate) și TextView pentru afișarea informațiilor. Un proiect similar este discutat în detaliu în.

În clasa creată automat pentru Activitatea proiectului nostru, este necesar să definim următoarele instanțe de clase pentru lucrul cu USB:

privat TextView lgView;
UsbManager privat mUsbManager;
Dispozitiv USB privat mDevice;
private UsbDeviceConnection mConnection;
privat UsbEndpoint mEndpointIntr;

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

și obțineți acces la clasa UsbManager

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

Să creăm, de asemenea, un handler de evenimente onResume(). Să atingem obiectivul - astfel încât informațiile despre dispozitivele conectate să fie actualizate atunci când fereastra aplicației noastre este activată (vezi Lista 1).

Listare 1. Manager de evenimente OnResume().

public void onResume() (
super.onResume();

// umple containerul cu o listă de dispozitive
HashMap< String , UsbDevice>deviceList = mUsbManager.getDeviceList();
Iterator< UsbDevice>deviceIterator = deviceList.values().iterator();

lgView.setText("Numărul de dispozitive:" + deviceList.size());

while (deviceIterator.hasNext()) (
UsbDevice device = (UsbDevice) deviceIterator.next () ;

//exemplu de determinare a ProductID-ului unui dispozitiv
\n"+ "Device ProductID: " + device.getProductId());
}
//definiți intenția descrisă în filtru
// intent AndroidManifest.xml
Intent intent = getIntent() ;
lgView.setText(lgView.getText()+" \n"+ "intenție: " + intenție);
String action = intent.getAction();

//dacă dispozitivul este conectat, transmiteți linkul către
//la funcția setDevice().
Dispozitiv UsbDevice = (Dispozitiv Usb) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) ;
dacă (UsbManager.ACTION_USB_DEVICE_ATTACHED .egal (acțiune) ) (
setDevice(dispozitiv) ;
lgView.setText(lgView.getText()+" \n" + „UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action) is TRUE”) ;
) altfel dacă (UsbManager.ACTION_USB_DEVICE_DETACHED .equals (acțiune) ) (
dacă (mDevice != null && mDevice.equals (dispozitiv) ) (
setDevice(null) ;
lgView.setText(lgView.getText()+" \n" + „UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action) is TRUE”) ;
}
}

În continuare, vom crea funcția setDevice() pentru activitate, care este necesară pentru a funcționa cu dispozitivul nostru (vezi Lista 2). În handlerul onResume() și în funcția setDevice(), am urmat exact algoritmul de utilizare a API-ului USB Host descris în secțiunea anterioară.

Lista 2. funcția setDevice().

private void setDevice (dispozitiv USB) (
lgView.setText(lgView.getText()+" \n"+ "setDevice" + dispozitiv);

//determină interfețele dispozitivelor disponibile
dacă (device.getInterfaceCount() != 1) (

LgView.setText (lgView.getText() + " \n"+ "nu am putut găsi interfața" );
întoarcere;
}
UsbInterface intf = device.getInterface(0);

//definiți punctele finale ale dispozitivului
if (intf.getEndpointCount() == 0) (

LgView.setText (lgView.getText() + " \n"+ "nu s-a putut găsi punctul final" );
întoarcere;
) altfel (
lgView.setText(lgView.getText()+" \n"+ "Număr de puncte finale: " + intf.getEndpointCount () );
}

UsbEndpoint epIN = null;
UsbEndpoint epOUT = null ;

//căutați puncte finale de transmis prin întreruperi
pentru (int i = 0; i< 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 punctul final: " + intf.getEndpoint (i) );
}
altceva(
epOUT = intf.getEndpoint(i) ;
lgView.setText(lgView.getText()+" \n"+ " OUT endpoint: " + intf.getEndpoint (i) ) ;
}
) else ( lgView.setText ( lgView.getText() + " \n" + „niciun punct final pentru INTERRUPT_TRANSFER”) ; }
}

MDevice = dispozitiv;
mEndpointIntr = epOUT;

//deschideți dispozitivul pentru transferul de date
dacă (dispozitiv != nul ) (
Conexiune UsbDeviceConnection = mUsbManager.openDevice (dispozitiv) ;
if (conexiune != null && connection.claimInterface (intf, true ) ) (

LgView.setText (lgView.getText() + " \n"+ "deschide dispozitivul SUCCES!" );
mConnection = conexiune;

) altfel (

LgView.setText (lgView.getText() + " \n"+ "deschideți dispozitivul FAIL!" );
mConection = null ;
}
}
}
}

Pe lângă codul dat, care, după cum probabil a ghicit cititorul atent, deschide dispozitivul pentru primirea și transmiterea datelor, nu mai rămâne decât să folosești protocolul de schimb de date, care, repet, ar trebui să fie bine cunoscut dezvoltatorului. Vom prezenta doar, așa cum am promis, codul care va trimite un anumit pachet de date de mesaj către dispozitivul HID utilizând transmisia de întrerupere, clasa UsbRequest și punctul final corespunzător - vezi Lista 3.

Listare 3. Exemplu de cod pentru trimiterea datelor către un dispozitiv

//determinând dimensiunea buffer-ului de trimis
//pe baza dimensiunii maxime a pachetului
int bufferDataLength = mEndpointIntr.getMaxPacketSize () ;

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

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

UsbRequest cerere = nou UsbRequest() ;

buffer.put(mesaj);

request.initialize(mConnection, mEndpointIntr) ;

request.queue(buffer, bufferDataLength) ;

dacă (request.equals(mConnection.requestWait()) )

//Trimiterea a avut succes
//lgView.setText(lgView.getText() + „\n” + „trimitere CLEAR!!!”);

prinde (excepție ex)

//ceva nu este in regula...
//lgView.setText(lgView.getText() + "\n" + "trimiterea nu este clar...");

Filtrarea dispozitivului în AndroidManifest.xml

Deși nu este nevoie să căutați în aplicația noastră dispozitiv specific cu VID (Vendor-ID) și PID (Product-ID) cunoscute, inginerii Google nu oferă exemple de aplicații fără secțiunea de filtrare a intenției din fișierul manifest, iar autorul nu a reușit să facă programul să funcționeze fără filtrarea dispozitivului. AndroidManifest.xml.

Permiteți-mi să vă reamintesc că Vendor-ID și Product-ID sunt identificatori unici ai dispozitivelor USB. Adică, folosind filtrarea, poți crea o aplicație care interacționează numai cu dispozitiv specific sau o anumită clasă de dispozitive. Vă rugăm să rețineți că producătorii de dispozitive trebuie să convină asupra acestor numere cu organizația USB IF.

O aplicație al cărei fișier manifest este afișat în Lista 4 și al cărui fișier de condiție a filtrului se află în Lista 5, de exemplu, recunoaște cu succes unitățile flash USB conectate la un dispozitiv mobil, dar nu recunoaște tastatura și mouse-ul pe care le are autorul. Această aplicație împreună cu cod sursă poate fi descărcat de pe link.

Lista 4. Fișier AndroidManifest.xml


" > http://schemas.android.com/apk/res/android"
> pachet="ru.learn2prog.usbhostexample"
android:versionCode="1"
android:versionName="1.0" >


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


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

android:nume = „ru.learn2prog.usbhostexample.MainActivity”
android:label="@string/app_name" >
>

„android.intent.category.DEFAULT” />

„android.intent.category.LAUNCHER” />

>

>

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

>

Lista 5. Fișier de filtrare device_filter.xml (directorul/res/xml)

>

>

Operațiunile de asamblare și instalare a aplicației noastre nu sunt diferite de cele obișnuite (vezi exemplele în,). Aș dori să vă atrag atenția asupra acțiunilor filtrului de intenție - atunci când un dispozitiv este conectat la gazdă, sistemul de operare cere utilizatorului să lanseze aplicația noastră.

Literatură/Referințe: 11.
12.
13. http://developer.android.com/guide/topics/connectivity/usb/host.html - prezentare generală a claselor necesare pentru a lucra cu USB în Android
14. link către sursele aplicației

Programare prin portul USB

Programarea dispozitivului pentru configurare antene satelit SF-50 prin USB diferă de programarea prin RS-232 doar prin modul în care datele sunt transferate de la instrument la computer și de la computer la instrument. La programare prin USB, un portabil unitate USB(unitate flash). Acest lucru este convenabil atunci când, de exemplu, computerul dvs. sau, mai des, un laptop (netbook) nu are un port serial RS-232 pe șasiu.
Pentru a programa dispozitivul folosind o unitate USB, veți avea nevoie de:
- Unitate USB (unitate flash), formatată în sistem de fișiere FAT-32;
- Programul de editare AliEditor, situat în folderul Database_editor_new al secțiunii de software a dispozitivului OPENBOX SF-50.

Înainte de programare, trebuie să transferați baza de date de pe dispozitiv pe computer. Pentru a face acest lucru, porniți dispozitivul, conectați-vă la port unitate flash USB. Executați MENU – Sistem – Salvare pe USB,

Ieșiți din meniu apăsând butonul MENU până când apare canalul curent sau până când imaginea meniului principal dacă nu există încă canale și scoateți unitatea flash. Introduceți unitatea flash în computer.
Rulați programul Editor.exe din folderul Database_editor_new și deschideți imaginea de pe unitatea flash din el.

Când vi se solicită să selectați o bază de date, selectați Baza de date utilizator.

Faceți clic pe OK. Selectați Toate serviciile, se va deschide o listă cu toate canalele TV, radio și servicii scanate și salvate disponibile în baza de date.

Editați canalele după cum doriți, de exemplu, lăsând doar canalele deschise.
Pe tastatura computerului, țineți apăsat butonul Shift, apăsați săgeata în jos și evidențiați canalele pe care doriți să le ștergeți. Faceți clic pe Ștergere pentru a șterge cel selectat.

Pentru a edita setările satelitului, selectați Toate serviciile – Informații satelit – EUTELSAT W4, W7, apăsați butonul ENTER.

Dacă este necesar, editați valorile din Antena 1.
Pentru a elimina un transponder, stați pe cel inutil și apăsați butonul Șterge pe tastatura computerului, confirmați acțiunea selectată.

Pentru a adăuga un transponder, accesați numele satelitului, apăsați butonul din dreapta mouse-ul și selectați Adăugare informații (sau evidențiați satelitul și apăsați butonul Inserare de pe tastatură).

Introduceți datele pentru noul transponder, luându-l, de exemplu, de pe site-ul web lyngsat.com.

Faceți clic pe OK și asigurați-vă că transponderul este înregistrat.

Pentru a adăuga un satelit, accesați linia Informații satelit, apăsați tasta Inserare de pe tastatură și introduceți parametrii noului satelit.

închideți programul editor și scoateți unitatea.
Introduceți unitatea în dispozitivul OPENBOX SF-50, urmați secvența MENU – System – Update from USB, selectați modul „SAT&TP List”.

Selectați Start. Confirmați-vă intențiile.

Dispozitivul va actualiza baza de date și va reporni singur. După repornire, va trebui să setați limba meniului la rusă într-un mod nou. Resetați dispozitivul la setările din fabrică.
Ieșiți din meniul de setări apăsând de două ori butonul MENU. Apăsați butonul OK de pe canalul curent și asigurați-vă că lista de canale este editată.

De asemenea, vă puteți asigura că lista de transpondere și sateliți este editată.
Programarea este finalizată.