System Architecture for Native Device Drivers

The sample device drivers included with the Platform Builder come in two types: monolithic and layered. A monolithic driver, as the name implies, is based on a single piece of code that exposes the functionality of the hardware device to the operating system directly. In contrast to the monolithic driver, the layered driver consists of two customized layers: the upper layer is the model device driver (MDD), and the lower layer is the platform-dependent driver (PDD). Most of the sample device drivers are configured as layered, rather than monolithic.

The following illustration shows the integration of monolithic and layered drivers within the Windows CE operating system.

Microsoft provides the MDD for a layered driver. The MDD is common to all platforms and functions, both as source code and as a library. It performs the following tasks:

Each MDD also handles a specific set of devices, such as audio hardware or touch screens.

In general, the MDD requires no changes. If you choose to modify the MDD, be aware that Microsoft does not test, warrant, or support custom MDDs. You are responsible for all further MDD maintenance if Microsoft supplies an updated MDD in order to fix bugs or to support later versions of Windows CE. In addition, if you revise the MDD you must provide support to any IHVs who use those changes.

Unlike the MDD layer, the PDD layer, which interfaces with both the MDD and the hardware, is meant to be tailored to your target platform. A PDD consists of hardware-specific functions that correspond to an MDD. There is no direct one-to-one relationship between the functions in a PDD and the corresponding MDD; the MDD functions implement discrete tasks that the MDD uses to achieve its goals. Because the PDD is hardware-dependent, you must create a customized PDD and port it to your platform hardware. To assist you, Microsoft provides several sample PDD layers for various built-in devices.

You can forego the MDD and PDD layers by implementing your device driver as a monolithic driver. For example, if performance is a critical factor, a monolithic driver might be a better choice than a layered driver because a monolithic driver avoids the overhead associated with the function calls that take place between the MDD and PDD layers. You might also choose to implement a monolithic driver if the capabilities of the device in question are well matched to the tasks that the functions in the MDD layer perform. In such a case, implementing a monolithic driver might be simpler and more efficient than implementing a layered driver. However, regardless of whether you implement a monolithic driver or a layered driver, you can base your implementation on the source code for any of the sample layered drivers.

As shown in the previous illustration, the Device Driver Interface (DDI) is a set of functions implemented in the MDD and called by the GWES module; the Device Driver Service-provider Interface (DDSI) is a set of functions implemented in the PDD and called by the MDD. Use DDI functions for monolithic drivers and DDSI functions for layered drivers.

Finally, some of the sample device drivers are implemented as stream interface drivers, which means that the drivers use the stream interface as their DDI. In this case, you do not need to link such drivers with the GWES module. They exist as ordinary DLLs and are loaded as needed. The audio driver is an example of a device driver using the stream interface model. Because these drivers have an MDD and PDD that you can use as a basis for your development efforts, they are included here, in the native device driver section, rather than in Developing Stream Interface Device Drivers.