Driver Code Structure
Most Windows CE–based device drivers use a layered approach. The advantage of this approach is that you only need to modify the upper or the lower layer. The upper layer is also known as the model device driver (MDD), and the lower layer is also known as the platform dependent driver (PDD).
Layered Code
Layered device drivers split the code into an upper layer called the model device driver (MDD) and a lower layer called the platform dependent driver (PDD). The MDD layer contains code that is common to all drivers of a given type. The PDD layer consists of the code that is specific to a given hardware device or platform. The MDD calls specific PDD routines to access the hardware or hardware specific information. When using a layered driver, you can reuse the common MDD code provided by Microsoft, and only write new PDD code that is specific to the your hardware. Alternatively, if you are porting one of the sample drivers to new hardware, you only need to port the PDD layer, and you can use the MDD layer directly from the sample driver.
The layered driver style is not required and may not be appropriate for all drivers. In particular, splitting device driver code into two layers imposes additional function call overhead in the device driver's operation. For performance critical situations, a monolithic driver may be more appropriate.
In general, 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:
· Links to the PDD layer and defines the DDSI functions it expects to call in that layer.
· Exposes DDI functions to the operating system.
· Handles complex tasks such as interrupt processing.
Each MDD handles a specific set of devices, such as audio hardware or touch screens.
The device driver interface (DDI) is a set of functions exposed by an MDD layer or monolithic driver and called by other OS modules. The device driver service provider interface (DDSI) is a set of functions exposed by the PDD layer of a layered device driver and called by the MDD. Classes of related device drivers can share the same DDI.
In contrast, DDSI layers are rarely the same from one PDD implementation to another. PDD implementations are designed to work with specific MDD implementations, and as such can vary widely from one layered device driver to the next. An exception is in cases where a single MDD layer is capable of using multiple PDDs, in which case the PDDs could expose the same set of DDSI functions. For example, a serial port MDD layer that supported multiple PDDs for controlling different types of serial port hardware, such as a 16550 UART based serial port and an infrared serial port, might require its PDDs to expose the same set of DDSI functions.
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.
You must develop the PDD layer specifically for your target platform. The PDD generally consists of functions that perform specific discrete tasks. These functions serve to isolate the MDD from the specifics of the hardware. Because the PDD is hardware-dependent, you must create a customized PDD for your platform hardware, or port one of the sample PDD layers to your hardware. To assist you, Microsoft provides several sample PDD layers for various built-in devices.
Monolithic Code
You can forego the MDD and PDD layers by implementing your device driver as a monolithic driver. Source code for a monolithic driver consists of both interrupt service thread code and platform specific code. For example, if performance is a critical factor for your device, 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 your device 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. 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 drivers.