PDD (lower layer)
|
Hardware dependent; typically must be customized and ported to
specific hardware.
Interfaces with MDD and hardware.
Implements a Device Driver Service Provider Interface (DDSI), a
set of functions called by the MDD layer.
There is no direct one-to-one relationship between the
functions in a PDD and the corresponding MDD.
Sample PPD layers are provided by Microsoft for a range of
devices.
Figure 1. Integration of monolithic and layered device drivers
within the Windows CE operating system
Each device driver model has advantages in the context of the
overall design considerations. Many of the sample drivers provided
by Microsoft use the layered organization because it reduces the
amount of code that developers must write when porting the sample
drivers to new devices. In some instances, however, a monolithic
driver might be a better choice than a layered driver. If
performance is a critical factor, for example, using a monolithic
driver avoids the overhead associated with the function calls that
take place between the MDD and PDD layers. A developer might also
choose to implement a monolithic driver if the capabilities of the
target device correspond closely to the semantics of the APIs
exposed by the MDD layer.
The Device Manager
The Device Manager is a user-level process that is typically
loaded at boot time on a Windows CE–based platform. It is an
application that interacts with the kernel, registry, file system,
and most device-driver DLLs. The Device Manager primarily manages
stream interface drivers. Stream interface drivers all expose the
same APIs to applications, so the drivers all can be managed in the
same way.
The Device Manager performs the following tasks:
- Loads and tracks device drivers.
- Registers special file names.
- Locates device drivers.
- Unloads device drivers from working RAM when they are no longer
being used.
The Device Manager uses a variety of registry entries in the
process of loading and unloading stream interface drivers. Some
keys relate to drivers that should always be present, and thus must
be loaded when the system boots. Other keys relate to devices that
are identified when they are connected to the Windows CE-based
platform through Plug and Play mechanisms. See the DDK
documentation for detailed discussion of these registry entries and
the ways that device drivers can be loaded.
Creating Windows CE Drivers
The process of writing a Windows CE device driver will vary
greatly in detail, depending on which of the two types of
drivers—stream interface drivers and native device drivers—you are
implementing, and whether you choose to use a layered or monolithic
design. Microsoft provides many resources to support this process,
including numerous sample device drivers, copious documentation,
and debugging tools for use both on the Windows CE platform and on
your development workstation.
Creating a device driver in Windows CE entails the following
steps.
- Identify the interface between the driver and the device:
- If the device driver will be communicating directly with the
hardware device, this interface will be the memory ranges,
registers, and/or ports through which I/O with the device takes
place. Two examples of this kind of device driver are a keyboard
driver and a display driver.
- If the device driver will be communicating with its device
through an intermediate device, this interface will be whatever
APIs the driver for the intermediate device exposes. This includes
any drivers that communicate with devices through data ports, such
as USB or serial. For instance, a GPS device driver will use the
serial port driver's API—the stream interface functions—to
communicate with a GPS receiver that is connected to the Windows CE
platform's serial port.
- Identify the APIs that the driver must expose:
- If the device driver will be providing services to a specific
component of the Windows CE kernel that already has a defined
interface, the device driver will expose the native API set for
that type of driver. For example, a battery driver must implement
the functions defined by GWES for battery drivers. Similarly, the
PDD layer of a layered driver must implement the DDSI functions
defined by the driver's MDD layer. In either case, the code you
will write must conform to an existing API set.
- If there is no predefined set of functions that your driver
must expose to the operating system or to applications, you must
design the upper interface. You are encouraged to make use of the
stream interface functions whenever possible. For example,
developers of USB device drivers often have to invent a way to
expose the USB device to applications. Because of the flexibility
of the stream interface functions and the fact that nearly all
devices can be treated as special files, using the stream interface
functions as the API by which applications use a USB device is
often a good design choice.
- Identify any additional interfaces that the device driver must
use, such as operating system services.
- Determine an appropriate mapping between the interfaces. This
is the essence of a device driver's job—mapping between the
functions that applications or the operating system will call in
the driver and the functionality provided by the device itself.
- Identify any additional architectural factors that are relevant
to your device driver, such as whether it must be organized as
specific modules and what functions are likely to have the most
time or memory constraints.
- Identify any pre-existing code that you can borrow or port.
- Implement any remaining code.
- Test and debug the device driver.
Loading Windows CE Drivers
Device drivers in Windows CE are managed by a variety of
different operating system modules. Drivers that are integral to a
Windows CE-based platform's user interface, such as the keyboard
and display, are managed by the Graphics, Windowing, and Event
(GWE) module. All of the device drivers managed by GWE are native
device drivers. GWE loads its drivers when the system boots. A
special process called the Device Manager handles stream interface
drivers. Device Manager loads some stream interface drivers when
the system boots if those drivers are listed in the registry.
Finally, any process has the ability to load a device driver after
the system has booted, generally because a user has connected an
installable device to the Windows CE-based platform. The Device
Manager does this for PC Card client drivers, the USBD module does
this for USB client device drivers, and so on.
Interrupt Handling
Windows CE uses interrupts to signal when a device needs
servicing by its driver. Windows CE 2.12 and earlier did not
support nested interrupts. In those versions, processing of one
interrupt must finish before another begins, and additional
interrupts are turned off while an interrupt is being processed.
Windows CE versions 3.0 and later introduce nested interrupts in
conjunction with Windows CE priority scheduling system. Interrupts
of a higher priority can occur while lower level interrupts are
being processed. While the higher-level interrupt is being
processed, no interrupts of a lower priority level will be
handled.
To minimize the amount of time during which lower-level
interrupts are disabled, Windows CE divides interrupt handling into
two processes: the kernel-mode
interrupt service routine (ISR)and the user-mode
interrupt service thread (IST). The ISR should be as small
and fast as possible. It is usually a few hand-coded assembly
instructions, whose sole job is to identify the hardware interrupt
and map it to a logical interrupt number, which it returns to the
kernel.
The kernel then identifies the IST that is registered for that
logical interrupt, and signals the thread that it must service an
interrupt. Because the IST is a user-mode thread, it is subject to
the same pre-emption and scheduling as any other thread in the
system, but also has access to the full range of operating system
services available to user-mode code. ISTs can perform much
lengthier interrupt processing tasks—such as coping data from a
hardware buffer into user memory while converting it from one
format to another—without preventing any interrupts from
occurring.
Stream Interface Drivers
All stream interface drivers expose a generic type of interface
to the operating system, a set of APIs known as the
stream interface functions. The stream interface driver
model can be used for any device whose functionality is similar to
a file. Any device whose logical behavior is to produce or consume
ordered streams of bytes can be treated as a special kind of file,
one that applications can read to and write from just as they do
with ordinary data files. It should come as no surprise, then, that
the stream interface functions are nearly identical to the standard
Win32 file I/O APIs.
Stream interface drivers are DLLs that typically are loaded,
controlled, and unloaded by the Device Manager. Stream interface
drivers are designed mainly for peripheral devices connected to a
Windows CE–based platform. Examples of these devices are modems,
printers, and digital cameras.
Stream interface drivers typically are designed by IHVs for
peripheral devices. However, OEMs who customize Windows CE–based
platforms by adding special built-in devices can write stream
interface drivers for those additional built-in devices. For
example, a Windows CE–based point-of-sale system might have a
bar-code scanner built into the hardware of the system, for which
the OEM could implement a stream interface driver. Internally, the
driver could respond to interrupts from the bar code scanner
hardware by storing the scanned data in a buffer. Applications
could then read from the buffer just as they would from a plain
text file. The driver would be responsible for removing data from
the buffer as applications read it.
Windows CE presents stream interface drivers to applications by
presenting them as special files in the file system. The names for
these special device files follow a particular naming convention
that differentiates the device files from ordinary files. Device
file names all consist of three upper case letters, a digit, and a
colon (for example, "COM1:" or "PGR7:"). Windows CE recognizes
these file names and redirects file I/O operations to the
appropriate stream interface driver. Thus, a stream interface
driver must convert file I/O operations into the relevant read and
write actions on the driver's device.
Stream interface drivers expose their implementations of the
stream interface functions by adding the same three-letter
combination used in the driver's special device file name to the
base function's name. The following table lists the stream
interface functions and briefly describes their purpose. (Replace
XXX with whatever prefix you choose for your stream interface
driver.)
Stream Interface Function
|
Purpose
|
XXX_Close
|
Release an application’s instance handle to the driver.
|
XXX_Deinit
|
Uninitialize the driver.
|
XXX_Init
|
Initialize the driver.
|
XXX_IOControl
|
Perform a driver-specific I/O control action.
|
XXX_Open
|
Get an instance handle to the driver for use by an
application.
|
XXX_PowerDown
|
Perform any processing necessary when the Windows CE platform
suspends.
|
XXX_PowerUp
|
Perform any processing necessary when the Windows CE platform
resumes.
|
XXX_Read
|
Read data from the driver.
|
XXX_Seek
|
Move forward or backward in the driver’s data stream.
|
XXX_Write
|
Write data to the driver.
|
Sample Code for Stream Interface Drivers
Windows CE provides the following sample drivers that implement
the stream interface.
Sample
|
Description
|
ATADISK and SRAMDISK
|
Illustrates device drivers for a PC Card-based ATA disk and SRAM
flash memory card.
|
Audio
|
Device driver for an audio device.
|
Serial
|
Device driver for devices that connect to a serial port.
|
Native Device Drivers
Native device drivers are drivers that expose any API set other
than the stream interface functions. Other than that, they are
exactly like stream interface drivers. They can use a monolithic or
layered design. They can serve devices that are built into a
Windows CE-based platform or installable devices. In addition, they
can be loaded either at the time that the system boots or at the
time that the user connects a device to the Windows CE-based
platform.
Many of the sample native device drivers provided in the Windows
CE Platform Builder happen to serve devices that are typically
built into a Windows CE-based platform. This is partly due to
legacy code reasons, but is primarily because the types of devices
that aren't suitable for stream interface drivers tend to be the
type of device that OEMs provide as part of their platforms. For
example, a display device is essentially a range of memory
addresses that are wired to a 2-dimensional surface that a user can
see. Addresses in that display memory can be written to in
arbitrary patterns and at any time, making a display device very
different than a producer or consumer of ordered streams of bytes.
Display drivers are thus not good candidates for using the stream
interface driver model. At the same time, display hardware is
generally built into Windows CE-based platforms, and not added by
end users. Similar logic applies to some other native device
drivers, such as the drivers for PC Card sockets, USB controller
chips, and so on.
Microsoft has already designed the APIs exposed by native device
drivers that interact with certain portions of the Windows CE
operating system, such as the Graphics, Windowing, and Events
System (GWES). Native device drivers that interact with GWES
include display drivers, notification LED drivers, battery drivers,
keyboard drivers, and so on. Further, Microsoft provides sample
code for these drivers. In most cases, an OEM only needs to port
Microsoft's sample native device drivers to their specific
hardware. For these specific native device drivers, you do not need
to define the API set that the driver will expose.
Platform Builder includes sample native device drivers for both
monolithic and layered drivers. Most native device drivers,
however, are configured as layered device drivers.
The sample native device drivers present a standard set of
functionality for all devices of a particular class, and all
representatives of a specific class conform to the same interface.
This enables the Windows CE operating system to treat all instances
of a particular device class similarly. For example, the operating
system treats both UHCI- and OHCI-compliant USB controller hardware
the same, because the USB host controller driver hides the
differences from the operating system, even though those two types
of USB controllers are internally very different.
Sample Code for Native Device Drivers
Windows CE provides many sample native device drivers, and using
code from these samples can significantly reduce development time.
Provided drivers include:
- Sample Battery Driver
- Sample Display Driver
- Sample Keyboard Driver
- Sample Notification LED Driver
- Sample PC Card Socket Driver
- Sample Touch Screen Driver
- Sample USB Host Controller Driver
Developing USB Device
Drivers
The USB is an external bus architecture for connecting
USB-capable peripheral devices to a host computer. USB is a
communications protocol that supports serial data transfers between
a host system and USB-capable peripherals. USB technology was
developed as a solution to the increasing user demands on computers
and the need for flexible and easy-to-use peripherals. A number of
standard PC peripherals, such as keyboards, mice, joysticks,
digital cameras, computer telephone integration (CTI), and video
conferencing products benefit directly from USB.
USB device drivers communicate with USB devices through logical
communication channels called pipes. The USB system software
implements APIs that USB device drivers use to open and close
pipes, configure them, read and write to them, and so on. Pipes are
connected to endpoints on the USB device, which are logical
producers or consumers of data. USB devices generally have several
endpoints, each with a specific purpose. All USB devices have a
special endpoint, endpoint number 0, which is used as a high-level
control channel.
Internally, the USB system software and hardware in Windows CE
handles the task of marshalling the data from all pipes going to
and from the endpoints on all USB devices connected to the Windows
CE-based platform onto a single USB cable.
Figure 2. Structure of the USB implementation in Windows CE
Windows CE supports the host side of the USB architecture, which
enables developers to write USB device drivers for any USB
peripheral devices. Windows CE provides limited support for the
device side of the USB architecture, which allows a Windows
CE-based platform to appear as a USB peripheral to other computers.
The host side exists to support the use of USB peripherals, while
the device side exists mainly to facilitate USB connectivity to
desktop computers. The USB architecture implemented in Windows CE
supports both device-specific USB drivers, and more generic USB
drivers known as class drivers, which can control a whole class of
similar devices. Microsoft supplies one sample USB driver: a class
driver for human interface-class (HID class) devices.
OEMs who wish to support USB on their Windows CE-based platforms
must port Microsoft's sample HCD module implementations to their
hardware. Microsoft supplies sample HCD modules for OHCI- and
UHCI-compliant host controller chips.
Writing USB device drivers is generally easy because the USB
infrastructure itself provides a rich set of services for accessing
USB peripheral devices. USB device drivers can use high-level data
transfer functions to send data to and read data from USB
peripherals, and thus the developer can concentrate on writing the
code that exposes the USB device to applications. Windows CE
supports all four types of data transfer defined in the Universal
Serial Bus Specification. USB device drivers can use any of the
transfer types that are appropriate for their peripherals.
Windows CE 3.0 also provides some support for the device side of
the USB device/host architecture. This allows Windows CE-based
platforms to communicate to other USB hosts, such as desktop PCs,
through a USB connection. Microsoft provides a sample USB function
controller driver that works with the Scanlogic SL11 USB function
controller chip.
Choosing Design Strategies for USB Device
Drivers
USB client drivers exist to make the services of peripheral
devices available to applications. OEMs and IHVs can choose among
the following three strategies to make the services of peripheral
devices available to applications:
- Using the stream interface functions.
- USB device drivers can expose the stream interface functions
like any other device driver. Applications can then treat the
peripheral device as a file and use standard file I/O functions to
interact with the device.
- Using an existing Windows CE API.
- USB device drivers can indirectly expose certain types of
peripherals to applications by interacting with a Windows CE API if
Windows CE has an existing API appropriate to the peripheral. For
example, USB drivers for mass storage devices, such as hard drives
and CD-ROM drives, can expose devices through the standard
installable file system interface. The sample HID-class driver
included in the DDK also uses this strategy. The driver does not
expose devices directly to applications; rather, it interacts with
existing Windows CE APIs in order to submit the correct input
events to the system. Thus, the USB nature of HID-class devices is
transparent to applications.
- Creating a native device driver.
- This strategy does not place any restrictions on the way a USB
driver exposes a device. It allows you to create whatever API best
maps to the ways in which applications are likely to use your USB
device. However, you must provide appropriate documentation for
application writers who will be writing applications that use the
driver because application writers cannot otherwise know what APIs
your driver exposes.
NDIS Drivers
The NDIS is the mechanism by which Windows CE supports network
connectivity. NDIS provides a pair of abstraction layers to connect
networking drivers to protocol stacks, such as TCP/IP and IrDA, and
to network adapters, such as Ethernet cards. NDIS presents two sets
of APIs for writers of network drivers. One set interfaces to the
networking protocol stacks, the other set interfaces to Network
Interface Cards (NICs).
Windows CE implements a subset of the NDIS 4.0 model used by the
Windows NT operating system, helping OEMs and IHVs to port
existing Windows NT networking drivers to Windows CE. The full NDIS
supports several types of network drivers, but Windows CE supports
only miniport drivers and intermediate drivers, not monolithic or
full NIC drivers. In addition, note that Ethernet (802.3), Token
Ring (802.5), WAN, and IrDA (both SIR and FIR) are the NDIS media
types directly supported in Windows CE. Several IHVs and OEMs
implement support for additional media types by writing drivers for
those media that emulate Ethernet. Additional media types supported
in this fashion include 802.11, HPNA, ArcNet, several types of
wireless media, and Powerline.
Windows CE 3.0 supports an array of new features including
intermediate drivers, NDIS WAN, Token Ring, improved adapter
binding, a layered miniport driver design, and an enhanced testing
application called NDISTest. NDISTest now includes tests for IrDA
and Token Ring as well as performance and stress tests.
For miniport drivers, Windows CE is largely source-code
compatible with Windows NT. With a few exceptions, Windows CE and
Windows NT support identical NDIS APIs. The primary exception
is that Windows CE does not provide direct memory access (DMA)
support, which is often used to transfer data between networking
stacks and user space. However, developers can implement DMA
mechanisms in their NDIS miniport drivers, but this will be new
code that isn't needed on the desktop versions of Windows. Still,
NDIS is similar enough from Windows NT to Windows CE that Microsoft
recommends you adapt a sample miniport driver or port an existing
miniport driver from another operating system, such as Windows NT,
rather than write one from scratch.
Sample Code for NDIS Drivers
Windows CE includes the following sample miniport drivers:
- Proxim wireless Ethernet PC Card.
- FastIR, which uses the National Semiconductor PC87338 chipset.
- NE2000-compatible network adapters for PCI, ISA and PCMCIA
busses.
- IrSIR infrared serial port intermediate miniport driver.
- Xircom CE 2 Ethernet PC Card.
For More Information
For tools and information pertaining to developing and debugging
products based on Windows CE, see Windows CE Platform Builder.
For extensive information on writing device drivers for Windows
CE, see the Windows CE Driver Development Kit (DDK) documentation,
included in Windows CE Platform Builder.
For additional information on the Win32 device drivers that are
used under Windows CE, especially NDIS drivers, see the Windows NT
DDK.
For papers and articles about Windows CE, see
http://msdn.microsoft.com/embedded/ce.net/default.aspx.
|