52964.fb2 Writing Windows WDM Device Drivers - читать онлайн бесплатно полную версию книги . Страница 23

Writing Windows WDM Device Drivers - читать онлайн бесплатно полную версию книги . Страница 23

Chapter 22The Human Input Device Model

HID Hides

This chapter describes the Human Input Device (HID) model, a standard way of interacting with user input devices. A HID device uses various descriptors to define its capabilities. A Report descriptor details the input reports that it can generate and the output reports it can receive. The next chapter describes how to write Windows client device drivers and user mode applications that can talk to HID devices.

The HID specification is an abstract model for most types of input device that people will use to control their computers. An input device can be a plain old keyboard, for example, a vehicle simulation rudder, or the soft on/off button for the computer.

The HID specification was written originally for USB devices and closely follows the USB descriptor model. However, it is sufficiently generic for HID to be used with other types of device.

Naturally, most of the time a HID device provides input data to the computer. However, you can output to a HID device (e.g., to turn on the NumLock LED on a keyboard). You can also control a feature of the device, such as the font used on a display device or an LED color.

In Windows, the system HID class driver provides an abstract view of the input device. The HID device itself can be a USB device, a IEEE 1394 device or even a plain PC-compatible device, provided an appropriate HID minidriver is written to interface to the bus or device.

In this chapter and the next, quite a few of the examples are about getting input from a keyboard. It does not matter whether you are using a USB keyboard or a (hypothetical) IEEE 1394 keyboard. The system still gets keystrokes in exactly the same way, from the HID class driver. As the next chapter shows, Windows does get input from an old PC-compatible keyboard by a different route. Perhaps eventually a minidriver will be written so that HID will provide all the keyboard input.

HID in Windows

Figure 22.1 shows how HID devices are used in Windows. A user mode or kernel mode HID client program calls the HID device stack. The stack always contains the system HID class driver, Hidсlass.sys, optionally with HID filter drivers above it. The HID class driver uses HID minidrivers to interface to hardware. In the figure, one of the minidrivers, HidUsb.sys. uses the USB stack to talk to a device.

Figure 22.1 HID drivers and clients

HID provides an abstract model of input devices, so client programs are not concerned with the details of where input comes from. HID models a device as various controls representing the device. A keyboard, therefore, usually has single-bit control representing the state of each modifier key, such as the left Shift key, and it has an array of scan code byte controls representing the other keys that are currently pressed.

Underlying the HID model are compact, but complicated, structures for passing information. HID device engineers and minidriver writers will need to know these structures. However, clients can just use various Windows parsing routines to access the relevant data. There are parsers for HID reports available to both kernel mode, Hidparse.dll, and user mode clients, Hid.dll.

The system HID class driver does most of the hard work. It delegates its hardware interactions to HID minidrivers. Windows includes a HID minidriver HidUsb.sys for the devices on the USB bus, but new minidrivers can be written, if necessary. New USB devices that have the appropriate HID Interface class constants and HID descriptors will not need a new minidriver. The system USB HID minidriver calls the system USB driver USBD.sys, optionally through any lower-level USB filter drivers. The system USB driver then talks to the device, etc.

A HID client, therefore, just talks to the HID class driver. The Windows operating system itself is an example of a kernel client, as it can get its keyboard and mouse input via HID. You can write kernel mode client drivers to use a HID device. However, it is often easier to write a Win32 program that talks directly to the HID class driver.

The HID Model

This section is a summary of the HID Model, particularly as seen by Windows device drivers and clients users. For full details, please read the HID specifications.

The HID specification documents are found on the USB website, www.usb.org/developers/. The "USB: Device Class Definition for HID" document usbhid10.pdf is referred to as the "HID Specification". The USB Compatibility Test software, also available there, includes the HIDView program to inspect and test HID devices. The "Ignore hubs (Memphis only)" box should be checked for Windows 98. The USB website also contains a tool for generating report descriptors, the Descriptor Tool dt. This contains several useful example report descriptors, as well as letting you build your own and check them for errors.

Reports

A computer primarily reads input data from a HID device. It can also send output data to it, and send and receive feature data.

Input data might represent a mouse movement or a keyboard keypress. Output data might mean setting the NumLock LED on a keyboard. A feature is something that controls the general operation of a device, such as the display character size. A feature is usually set by a Control Panel type application and not used by ordinary HID clients.

An individual transaction with a device is called a report, which groups several controls together. An input report from a keyboard says which keys are pressed and which modifier keys are pressed (i.e., Shift, etc.).

A control is a value of one or more bits. Control values can be converted from logical to physical form (i.e., scaled and given units). (Windows refers to some controls as buttons, while it calls others values.).

Reports may be grouped together in Collections. An Application top-level collection usually describes all the reports that a device can produce. More than one Application collection can be given. For example, if a keyboard has a built-in pointer (i.e., a mouse), it might well have an Application collection for a keyboard report and an Application collection for a pointer report. Reports and collections may contain other collections.

Figure 22.2 shows an overview of the Report descriptor for a HID keyboard. An input report contains eight control bits for the modifier keys and six byte values for all the keys that are simultaneously pressed. An output report just contains five output control bits for the keyboard LEDs. The full keyboard report descriptor also contains a "reserved" input control byte and a 3-bit control that pads out the output report.

Figure 22.2 Keyboard report descriptor overview

Usages

A HID device needs a standard way to tell programmers what their device is: what Input. Output, and Feature reports it can send and receive. Discovering this information is known as getting a device's capabilities.

Each control or collection of controls is assigned a usage that describes its purpose. The HID Specifications list a large number of usages for a range of standard devices. (I have yet to see a device with a "Do Not Disturb" LED. Did you know that a magic carpet has standard controls?)

A usage is, in fact, represented by two bytes: a Usage Page and a Usage. Table 22.1 shows the main usage categories.

Table 22.1 Main Usage categories

Usage PageUsage
Generic Desktoppointer
mouse
pen
joystick
gamepad
keyboard
keypad
Vehiclerudder
throttle
Virtual Reality
Sport
Game
Consumerpower amp
video disk
Keyboardall keys
LEDNumLock
CapsLock
ScrollLock
power
Button
Ordinal
Telephony

Note that usages are used both to specify the general characteristics of a device (i.e., of an Application collection) and the specifics of each control or group of controls.

The Application collection usage defines the overall purpose of a report. For example, a keyboard usually has an Application collection with a Usage Page of "Generic Desktop" and a Usage of "keyboard". The hidusage.h file defines these as byte constants HID_USAGE_PAGE_GENERIC and HID_USAGE_GENERIC_KEYBOARD, respectively. In most Usage Pages, Usage values in the range 1 to 0x1F usually indicate the overall purpose of a device.

The Application collection usage sometimes implies what controls should be in the report. A keyboard usually has eight input single-bit values, eight reserved bits, five output bits, three padding output bits and six input 8-bit values. Although some clients rely on devices having specific controls, most should be able to cope with different devices (e.g., with more controls) or controls in different reports.

Each control also has a usage. The eight single-bit input values in a keyboard report represent the modifier keys (i.e., whether a Shift, Ctrl, or Alt key is pressed at the same time). These modifiers are defined in the "Keyboard" Usage Page (HID_USAGE_PAGE_KEYBOARD). The first single bit value represents the state of the left control key and has a Usage of HID_USAGE_ KEYBOARD_LCTRL.

The HID Specification defines Usage values in the "Keyboard" Usage Page that represent all the common keyboard key scan codes. PC-AT keyboards return usages in the range 0 to 101.

However, the left control key has a usage of 240, HID_USAGE_KEYBOARD_LCTRL As described previously, this is usually returned as a bit value to indicate whether the key is pressed or not.

The HID Specification lets you define several reports in a report descriptor, each with different report IDs. However most Report descriptors do not use report IDs at all. For example, the keyboard Application collection just defines one report with both input and output controls in it. However, a keyboard with a built-in pointing device may have two Application collections with two reports, a keyboard report, and a pointer report.

Getting HID Capabilities

When first used, a HID device needs to be interrogated to find out what it is. The client gets the device capabilities, the list of reports that the device may generate or accept. The client then decides whether the device is of interest. The capabilities are in a slightly opaque format, so Windows provides a parser to help clients analyze them. The parser functions are described in the next chapter.

You may also want to read a HID device's string descriptors and physical descriptors. Both are not necessary for most HID interactions, so they are only covered briefly here. See the HID specification for more details.

Controls may optionally have a string index. You can ask the device for the corresponding string, identified by the string index and a language ID. The string descriptor for index zero is special; it provides a list of the language IDs that are supported. HID string descriptors are identical to their USB equivalent, described in the previous two chapters.

Physical descriptors describe which parts of the body can be used to activate a device's controls. Each control may optionally have a designator index that can be used to look up the appropriate physical descriptor.

Then…

After this, the device generates input reports whenever appropriate, perhaps regularly. You can send output reports to the device. It may be able to send and receive feature reports.

HID Model Representation

This section gives explicit details of how the HID model is represented in descriptors and reports. This is useful background for HID client programmers. Minidriver writers and firmware engineers will need to know these details.

HID minidrivers need to return specific data structures to the HID class driver to tell it the device's capabilities. For many new devices, these are provided by the device itself. The crucial data structures are:

• HID descriptor,

• device attributes,

• report descriptor,

• physical descriptors, and

• string descriptors.

The actual data is in little endian format, lowest byte first. A field cannot span more than four bytes in a report.

In a HID USB device, these descriptors will be hard-coded into the device ROM. If you are providing a HID minidriver for a different bus and device, your minidriver may need to synthesize these descriptors internally.

HID Descriptors

A HID descriptor provides the first information about a device. It mainly confirms that it is a HID device and gives the lengths of its report descriptor and any physical descriptors.

Table 22.2 shows the HID_DESCRIPTOR structure along with typical values. The Descrip-torList field usually just has one element, detailing "report descriptor" and its length. However, it may also specify physical descriptor sets that provide information about the part or parts of the human body used to activate the controls on a device.

Most hardware is not localized, and so should just specify zero for the Country Code.

Table 22.2 HID descriptor

FieldDescriptionTypical values
bLengthlength of HID descriptor9
bDescriptorTypedescriptor typeHID_HID_DESCRIPTOR_TYPE, 0x21
bcdHIDHID spec release0x0100
bCountrycountry code0 == Not Specified
bNumDescriptorsnumber of HID class descriptors1
struct _HID_DESCRIPTOR_DESC_LIST { UCHAR bDescriptorType; USHORT wDescriptorLength; } DescriptorList[1];descriptor type; total length of descriptorHID_REPORT_DESCRIPTOR TYPE, 0x22, sizeof(MyReportDescriptor)

Device Attributes

A Device Attributes HID_DEVICE_ATTRIBUTES structure simply has VendorID, ProductID, and VersionNumber fields, along with a Size.

Report Descriptors

A Report Descriptor is a somewhat complicated (but compact) structure detailing the device's capabilities. It may describe more than one report. A parser is provided by Windows to make sense of the format.

A Report Descriptor is a variable length structure made up of items that provide information about a device. A group of items might describe a single input, output, feature, or collection.

Overview

A Report descriptor usually has an Application collection defining one or more reports. Each report describes the input, output, or feature controls, and collections that it contains.

Each control has a data size and a usage. Controls can be given units, ranges, and scaling exponents. The data structure allows more than one control to be given usages, units, and exponents easily.

Table 22.3 Keyboard modifier keys example

ItemItem dataItem TypeActualBytes
Usage Page"keyboard"Global05 07
Usage Minimum"left control key"Local19 E0
Usage Maximum"left alt key"Local29 E2
Report Size1Global75 01
Report Count3Global95 03
Input(Data, Variable, Absolute)Main81 02

As an example, Table 22.3 shows how three single-bit input controls are specified, the first three modifier keys on a keyboard. The last item, Input, declares the control(s) and states that they are data values (i.e., not constants). Preceding items give more details of the control(s). The preceding Report Size item says that each control has 1 bit and the Report Count item says that there are 3 controls. The preceding Usage Page item specifies the "keyboard" usage page, while the Usage Minimum and Usage Maximum items say that the first input bit corresponds to the left control key of a keyboard and that the last is the left Alt key.

Note that the Item data is actually a byte (e.g., "keyboard" is the constant 07, HID_USAGE_PAGEKEYBOARD).

Item Parts

An item consists of one or more bytes that define an item type, an item tag, an item size, and possibly item data bytes.

An item may be in Short or Long format. Long format is not used yet, so it is not discussed here.

Figure 22.3 shows that the first byte of an item has a Tag of four bits, a Type of two bits and a Data size of two bits. Table 22.4 shows the interpretation of the size and type fields.

Figure 22.3 Short item format

Table 22.4 Short item values

Data Size0 = 0 bytes
1 = 1 byte
2 = 2 bytes
3 = 4 bytes
Type0 = Main
1 = Global
2 = Local
3 = Reserved

Main Item Tags

The Main item type is used for the Input, Output, Feature, Collection, and End Collection tags. A Main item is usually preceded by one or more Global or Local items that provide the rest of the description of the Main item.

Table 22.5 shows the set of possible item tags if the item type is Main (0). The number of data bytes and their definition is also shown. See the HID specification for full details.

Table 22.5 Main item tags

TagBitsNameDatabytesData
1000Input1-4Bit 0: 0=Data 1=Constant
Bit 1: 0=Array 1=Variable
Bit 2: 0=Absolute 1=Relative
Bit 3: 0=No Wrap 1=Wrap
Bit 4: 0=Linear 1=Non Linear
Bit 5: 0=Preferred State 1=No Preferred
Bit 6: 0=No Null position 1=Null state
Bit 7: Reserved
Bit 8: 0=Bit Field 1=Buffered Bytes
Bit 31-9: Reserved
1001Output1-4same as above, except Bit 7: 0=Non Volatile 1=Volatile
1011Feature1-4same as Output
1010Collection10x00      Physical    group of axes
0x01      Application mouse, keyboard
0x02      Logical     interrelated data
0x03-0x7F Reserved
0x80-0xFF Vendor-defined
1100End collection0
othersreserved

The Input, Output, and Feature tags allow for up to four data bytes. However, if all the data bits in the top bytes are 0, they can be missed out. So, if bits 8-31 are 0 then the item data size can be given as 1 byte. Further, if no data bits are set at all, the data size can be zero.

For example, two bytes A1 01 (1010 0001 0000 0001) represent "Collection, Main, 1 data byte". The data byte is 0x01 (i.e., Application). Therefore, A1 01 is interpreted as "Collection (Application)".

The one byte C0 (1100 0000) is "End collection, Main, 0 data bytes", and so just means "End Collection".

The two bytes 81 02 (1000 0001 0000 0010) represent "Input, Main, 1 data byte". The data byte just has bit 1 set and so means Data, Variable, Absolute, etc. So 81 02 can be written as "Input (Data, Variable, Absolute)".

Input, Output, and Feature Controls

As shown in the earlier example, an Input, an Output, or a Feature item must be preceded by various other items that further describe the controls. The preceding items can be Global if the setting lasts for more than one control. They can be Local if they provide just the setting for one control.

Input, Output, and Feature items must have Report Size and Report Count preceding Global items. Report Count specifies the number of controls, each of Report Size number of bits.

There must be a preceding Usage Page item. Then specify either a Usage for a single control or a Usage Minimum and Usage Maximum pair if more than one control is being defined.

Logical Minimum and Logical Maximum specify the range of values that may be returned. For example, even though a Report Size is eight bits, the actual values returned might be specified as being between Logical Minimum 0 and Logical Maximum 101 inclusive.

"Constant" bit values are often used to pad out a report so that controls are byte-aligned.

When "Array" is specified, it means that the actual report will contain an array of usage values that apply at the time of the report. Report Count sets the maximum number of usages that may be returned. If fewer usages apply then the array is padded with zeroes.

The full example below shows how various types of control are defined.

Collections

A Physical collection is used to group controls that represent related physical data. A mouse movement might consist of X and Y coordinates and various bit fields to indicate which buttons are pressed.

An Application or top-level collection groups together all the reports, controls and collections in a report descriptor. This is preceded by Usage Pace and usage items. The Application collection usage is often used by a client to determine whether the device is of any interest. For example, the Application collection usage might be "keyboard" or "mouse". A keyboard with an integrated pointing device could be defined as two different Application collections.

Collections may be nested.

Global Item Tags

Global item type tags define the attributes of any following Main items. The appropriate Global value remains in force for the rest of the report descriptor unless replaced.

Table 22.6 shows the set of possible item tags if the item type is Global (1). I have already described most of these tags.

Table 22.6 Global item tags

Tag BitsNameData bytes
0000Usage Page1
0001Logical Minimum1-4
0010Logical Maximum1-4
0011Physical Minimum1-4
0100Physical Maximum1-4
0101Unit Exponent1-4
0110Unit1-4
0111Report Size1+
1000Report ID1
1001Report Count1+
1010Push0
1011Pop0
othersreserved

While Logical Minimum and Logical Maximum bound the values returned by a device, Physical Minimum and Physical Maximum give meaning to those bounds. Physical values are logical values with units applied. For example, a thermometer might have logical extents of 0 and 999, but physical extents of 32 and 212 degrees. Logical 0 corresponds to 32 degrees and logical 999 with 212 degrees.

The Unit and Unit Exponent items further define the type and scaling of the subsequent control(s).

Push and Pop items allow the state of the item stack to be saved and restored.

Local Item Tags

Local item type tags define the attributes of the following Main item. The Local value is only in force for the following Main item.

Table 22.7 shows the set of possible item tags if the item type is Local (2).

Table 22.7 Local item tags

Tag BitsNameData bytesData
0000Usage1
0001Usage Minimum1
0010Usage Maximum1
0011Designator Index1
0100Designator Minimum1
0101Designator Maximum1
0111String Index1
1000String Minimum1
1001String Maximum1
1010Set Delimiter10 = open set 1 = close set
othersreserved

The Usage or Usage Minimum and Usage Maximum give the definition of the following Input, Output, or Feature items.

For example, a keyboard uses eight one-bit values to specify the state of its Ctrl, Shift, Alt, etc., modifier keys. The report descriptor, therefore, has input controls in the HID_USAGE_ PAGE_KEYBOARD Usage Page. Its Usage Minimum is HID_USAGE_KEYBOARD_LCTRL (i.e., 224) and Usage Maximum is HID_USAGE_KEYBOARD_RGUI (i.e., 231). This means that if the first input bit is set, the left Ctrl key is pressed, etc.

The Designator items determine the body part used for each control, and refers to a Physical Descriptor.

Strings can be associated with each control. The String items give the String descriptor index.

A control may have more than one usage, string, or physical descriptor associated with it. One or more alternative sets of local items may be associated with a control by simply bracketing each set with Set Delimiter items.

Example

A 105-key keyboard should report eight modifier keys (i.e., Shift, etc.) and up to six simultaneous key presses. It has five output LEDs (i.e., for NumLock, etc.). The complete report descriptor is shown in Table 22.8.

Table 22.8 A keyboard report descriptor

ItemDataData valueActual bytesInterpretation
Usage Page(Generic Desktop)HID_USAGE_PAGE_GENERIC05 01
Usage(Keyboard)HID_USAGE_GENERIC_KEYBOARD09 06
Collection(Application)A1 01"Keyboard"
Usage Page(Key Codes)HID_USAGE_PAGE_KEYBOARD05 07
Usage Minimumleft control keyHID_USAGE_KEYBOARD_LCTRL19 E0
Usage Maximumright GUI keyHID_USAGE_KEYBOARD_RGUI29 E7
Logical Minimum015 00
Logical Maximum125 01
Report Size195 01
Report Count875 08
Input(Data, Variable, Absolute)81 02Modifier key bits
Input(Constant)81 01Reserved byte
Usage Page(LEDs)HID_USAGE_PAGE_LED05 08
Report Count595 05
Usage MinimumNumLockHID_USAGE_LED_NUM_LOCK19 01
Usage MaximumkanaHID_USAGE_LED_KANA29 05
Output(Data, Variable, Absolute)91 02LEDs
Report Size375 03
Report Count195 01
Output(Constant)91 01padding
Usage Page(Key Codes)HID_USAGE_PAGE_KEYBOARD05 07
Usage Minimum019 00
Usage Maximum10129 65
Report Count695 06
Report Size875 08
Logical Minimum015 00
Logical Maximum10125 65
Input(Data Array)81 00Key array (6 bytes)
End collectionC0

The first three items specify the Application collection as being a keyboard in the generic usage page. A client will therefore know straightaway that this device is a keyboard.

The next items define the modifier input controls. There are eight single-bit inputs, each naturally reporting either 0 or 1. These inputs correspond to eight usage values in the keyboard usage page, the left Shi ft key being pressed, onwards.

The next item defines a reserved constant byte of eight single bits. Note how the Global Report Size and Report Count items persist after the previous Main item.

The next control is for the output LEDs. There are five of them, still bits needing values of 0 or 1. The LED usage page is now in force and the output bits correspond to the NumLock key, etc.

The next control is a 3-bit constant field, padding the output report to make it up to a complete byte.

The actual key presses are defined in a single Input item with its "Array" bit set. Up to 6-key scan codes may be read, each of eight bits. However, the actual values returned are in the range 0 to 101. The keyboard has 102 keys and three modifier keys, returned separately as three bits.

No Report ID items are given, and so the descriptor describes one report that contains the current state of all the input and output items. An actual input report, therefore, always contains the eight modifier bits, a reserved byte of 0x00, and one to six key scan codes padded to six bytes with zeroes. An actual output report just contains one byte with the lower five bits giving the required LED states.

Pressing Ctrl+Alt+Del might result in the six input reports shown in Table 22.9. The reserved byte values are not shown.

Table 22.9 Ctrl+Alt+Del input reports

TransitionModifier byteScan codes (hex)
Left Ctrl down0000000100, 00, 00, 00, 00, 00
Left Alt down0000010100, 00, 00, 00, 00, 00
Del down0000010163, 00, 00, 00, 00, 00
Del up0000010100, 00, 00, 00, 00, 00
Left Ctrl up0000010000, 00, 00, 00, 00, 00
Left Alt up0000000000, 00, 00, 00, 00, 00

Conclusion

This chapter has introduced you to the Human Input Device (HID) model. A HID device uses various descriptors to define its functionality. The most important of these, the Report descriptor, defines what input reports it generates and the output reports it can receive. The controls within a report are given "usage" values that define their function exactly. A full example of a Report descriptor was given for a HID keyboard.

The next chapter looks at how to use the HID class drivers in Windows. Both kernel mode drivers and user mode applications can access HID devices.