Linux下HID 设备.docx
《Linux下HID 设备.docx》由会员分享,可在线阅读,更多相关《Linux下HID 设备.docx(13页珍藏版)》请在冰豆网上搜索。
![Linux下HID 设备.docx](https://file1.bdocx.com/fileroot1/2023-2/25/bb907e07-4e94-4865-acdb-12cbb7f57588/bb907e07-4e94-4865-acdb-12cbb7f575881.gif)
Linux下HID设备
Linux下HID设备,如果非标准的输入设备(Keypad/MOUSE/JoyStick/inputeventdevice).
将会把信息转入hiddevice的设备结点。
这一点可以参见内核的关于hiddev的文档
http:
//lxr.free-
它在Documentation/usb/hiddev.txt目录下,大致有这样一个流程,
usb.c--->hid-core.c---->hid-input.c---->[keyboard/mouse/joystick/event]
|
|
-->hiddev.c---->POWER/MONITORCONTROL
关于操作非标准的HID设备,可以参见如下文档.
在设备文件系统中,会产生的/dev/hiddev0这样的结点,这类设备主设备号为180,从设备号最低为96
Cat/proc/device|grephiddev
mknod/dev/hiddev0c18096
mknod/dev/hiddev1c18097
mknod/dev/hiddev2c18098
mknod/dev/hiddev3c18099
...
mknod/dev/hiddev15c180111
对此设备结点的处理有两种接口,一种是read(),另一种是ioctl();
∙read():
Thisistheeventinterface.WhentheHIDdeviceperformsaninterrupttransfer,indicatingachangeofstate,datawillbemadeavailableattheassociatedhiddevdevicewiththecontentofastructhiddev_event:
structhiddev_event{unsignedhid;signedintvalue;};containingtheHIDusageidentifierforthestatusthatchanged,andthevaluethatitwaschangedto.
∙ioctl():
Thisisthecontrolinterface.Thereareanumberofcontrols:
HIDIOCGVERSION
int(read)
Getstheversioncodeoutofthehiddevdriver.
HIDIOCAPPLICATION
(none)
ThisioctlcallreturnstheHIDapplicationusageassociatedwiththehiddevice.Thethirdargumenttoioctl()specifieswhichapplicationindextoget.Thisisusefulwhenthedevicehasmorethanoneapplicationcollection.Iftheindexisinvalid(greaterorequaltothenumberofapplicationcollectionsthisdevicehas)theioctlreturns-1.Youcanfindoutbeforehandhowmanyapplicationcollectionsthedevicehasfromthenum_applicationsfieldfromthehiddev_devinfostructure.
HIDIOCGDEVINFO
structhiddev_devinfo(read)
Getsahiddev_devinfostructurewhichdescribesthedevice.
HIDIOCGSTRING
structstructhiddev_string_descriptor(read/write)
Getsastringdescriptorfromthedevice.Thecallermustfillinthe"index"fieldtoindicatewhichdescriptorshouldbereturned.
HIDIOCINITREPORT
Instructsthekerneltoretrieveallinputandfeaturereportvaluesfromthedevice.Atthispoint,alltheusagestructureswillcontaincurrentvaluesforthedevice,andwillmaintainitasthedevicechanges.
HIDIOCGNAME
string(variablelength)
Getsthedevicename
HIDIOCGREPORT
structhiddev_report_info(write)
Instructsthekerneltogetafeatureorinputreportfromthedevice,inordertoselectivelyupdatetheusagestructures(incontrasttoINITREPORT).
HIDIOCSREPORT
structhiddev_report_info(write)
Instructsthekerneltosendareporttothedevice.ThisreportcanbefilledinbytheuserthroughHIDIOCSUSAGEcalls(below)tofillinindividualusagevaluesinthereportbeforesendingthereportinfulltothedevice.
HIDIOCGREPORTINFO
structhiddev_report_info(read/write)
Fillsinahiddev_report_infostructurefortheuser.Thereportislookedupbytype(input,outputorfeature)andid,sothesefieldsmustbefilledinbytheuser.TheIDcanbeabsolute--theactualreportidasreportedbythedevice--orrelative--HID_REPORT_ID_FIRSTforthefirstreport,and(HID_REPORT_ID_NEXT|report_id)forthenextreportafterreport_id.Withouta-prioriinformationaboutreportids,therightwaytousethisioctlistousetherelativeIDsabovetoenumeratethevalidIDs.Theioctlreturnsnon-zerowhenthereisnomorenextID.TherealreportIDisfilledintothereturnedhiddev_report_infostructure.
HIDIOCGFIELDINFO
structhiddev_field_info(read/write)
Returnsthefieldinformationassociatedwithareportinahiddev_field_infostructure.Theusermustfillinreport_idandreport_typeinthisstructure,asabove.Thefield_indexshouldalsobefilledin,whichshouldbeanumberfrom0andmaxfield-1,asreturnedfromapreviousHIDIOCGREPORTINFOcall.
HIDIOCGUCODE
structhiddev_usage_ref(read/write)
Returnstheusage_codeinahiddev_usage_refstructure,giventhatgivenitsreporttype,reportid,fieldindex,andindexwithinthefieldhavealreadybeenfilledintothestructure.
HIDIOCGUSAGE
structhiddev_usage_ref(read/write)
Returnsthevalueofausageinahiddev_usage_refstructure.Theusagetoberetrievedcanbespecifiedasabove,ortheusercanchoosetofillinthereport_typefieldandspecifythereport_idasHID_REPORT_ID_UNKNOWN.Inthiscase,thehiddev_usage_refwillbefilledinwiththereportandfieldinfomationassociatedwiththisusageifitisfound.
HIDIOCSUSAGE
structhiddev_usage_ref(write)
Setsthevalueofausageinanoutputreport.
1测试代码/*
2Author:
AndrewHuang
3<>
4http:
//lxr.free-
5
6*/
7#include
8#include
9#include
10#include
11#include
12#include
13#include
14#include
15#include
16
17staticvoidshowReports(intfd,unsignedreport_type);
18staticvoidshow_all_report(intfd);
19staticintread_event(intfd);
20
21intmain()
22{
23chardev_name[64]="/dev/hiddev0";
24intfd=-1;
25intversion;
26charname[100];
27structhiddev_devinfodinfo;
28
29
30fd=open(dev_name,O_RDWR);
31if(fd==-1)
32{
33fprintf(stderr,"open%sfailure\n",dev_name);
34return-1;
35}
36
37
38printf("%sinfor\n",dev_name);
39
40if(ioctl(fd,HIDIOCGVERSION,&version)<0)
41perror("HIDIOCGVERSION");
42else
43{
44printf("HIDIOCGVERSION:
%d.%d\n",(version>>16)&0xFFFF,version&0xFFFF);
45if(version!
=HID_VERSION)
46printf("WARNING:
versiondoesnotmatchcompile-timeversion\n");
47}
48
49if(ioctl(fd,HIDIOCGDEVINFO,&dinfo)<0)
50perror("HIDIOCGDEVINFO");
51else
52{
53printf("HIDIOCGDEVINFO:
bustype=%dbusnum=%ddevnum=%difnum=%d\n"
54"\tvendor=0x%04hxproduct=0x%04hxversion=0x%04hx\n"
55"\tnum_applications=%d\n",
56dinfo.bustype,dinfo.busnum,dinfo.devnum,dinfo.ifnum,
57dinfo.vendor,dinfo.product,dinfo.version,dinfo.num_applications);
58}
59
60if(ioctl(fd,HIDIOCGNAME(99),name)<0)
61perror("HIDIOCGNAME");
62else
63{
64name[99]=0;
65printf("HIDIOCGNAME:
%s\n",name);
66}
67
68#if0
69printf("\n***INPUT:
\n");showReports(fd,HID_REPORT_TYPE_INPUT);
70printf("\n***OUTPUT:
\n");showReports(fd,HID_REPORT_TYPE_OUTPUT);
71printf("\n***FEATURE:
\n");showReports(fd,HID_REPORT_TYPE_FEATURE);
72#endif
73show_all_report(fd);
74
75read_event(fd);
76
77close(fd);
78
79
80
81}
82
83
84
85
86staticvoidshowReports(intfd,unsignedreport_type)
87{
88structhiddev_report_inforinfo;
89structhiddev_field_infofinfo;
90structhiddev_usage_refuref;
91inti,j,ret;
92
93rinfo.report_type=report_type;
94rinfo.report_id=HID_REPORT_ID_FIRST;
95ret=ioctl(fd,HIDIOCGREPORTINFO,&rinfo);
96while(ret>=0)
97{
98printf("HIDIOCGREPORTINFO:
report_id=0x%X(%ufields)\n",
99rinfo.report_id,rinfo.num_fields);
100for(i=0;i101{
102finfo.report_type=rinfo.report_type;
103finfo.report_id=rinfo.report_id;
104finfo.field_index=i;
105ioctl(fd,HIDIOCGFIELDINFO,&finfo);
106
107printf("HIDIOCGFIELDINFO:
field_index=%umaxusage=%uflags=0x%X\n"
108"\tphysical=0x%Xlogical=0x%Xapplication=0x%X\n"
109"\tlogical_minimum=%d,maximum=%dphysical_minimum=%d,maximum=%d\n",
110finfo.field_index,finfo.maxusage,finfo.flags,
111finfo.physical,finfo.logical,finfo.application,
112finfo.logical_minimum,finfo.logical_maximum,
113finfo.physical_minimum,finfo.physical_maximum);
114
115for(j=0;j116{
117uref.report_type=finfo.report_type;
118uref.report_id=finfo.report_id;
119uref.field_index=i;
120uref.usage_index=j;
121ioctl(fd,HIDIOCGUCODE,&uref);
122ioctl(fd,HIDIOCGUSAGE,&uref);
123
124printf(">>usage_index=%uusage_code=0x%X()value=%d\n",
125uref.usage_index,
126uref.usage_code,
127//controlName(uref.usage_code),
128uref.value);
129
130}
131}
132printf("\n");
133
134rinfo.report_id|=HID_REPORT_ID_NEXT;
135ret=ioctl(fd,HIDIOCGREPORTINFO,&rinfo);
136}
137}
138
139
140voidshow_all_report(intfd)
141{
142
143structhiddev_report_inforinfo;
144structhiddev_field_infofinfo;
145structhiddev_usage_refuref;
146intrtype,i,j;
147char*rtype_str;
148
149for(rtype=HID_REPORT_TYPE_MIN;rtype<=HID_REPORT_TYPE_MAX;
150rtype++){
151switch(rtype){
152caseHID_REPORT_TYPE_INPUT:
rtype_str="Input";break;
153caseHID_REPORT_TYPE_OUTPUT:
rtype_str="Output";break;
154caseHID_REPORT_TYPE_FEATURE:
rtype_str="Feature";break;
155default:
rtype_str="Unknown";break;
156}
157fprintf(stdout,"Reportsoftype%s(%d):
\n",rtype_str,rtype);
158rinfo.report_type=rtype;
159rinfo.report_id=HID_REPORT_ID_FIRST;
160while(ioctl(fd,HIDIOCGREPORTINFO,&rinfo)>=0){
161fprintf(stdout,"Reportid:
%d(%dfields)\n",
162rinfo.report_id,rinfo.num_fields);
163for(i=0;i164memset(&finfo,0,sizeof(finfo));
165finfo.report_type=rinfo.report_type;
166finfo.report_id=rinfo.report_id;
167finfo.field_index=i;
168ioctl(fd,HIDIOCGFIELDINFO,&finfo);
169fprintf(stdout,"Field:
%d:
app:
%04xphys%04x"
170"flags%x(%dusages)unit%xexp%d\n",
171i,finfo.application,finfo.physical,finfo.flags,
172finfo.maxusage,finfo.unit,finfo.unit_exponent);
173memset(&uref,0,sizeof(uref));