With the increasing of USB devices, development of USB driver is becoming more and more important in embedded development. Windows CE's support for USB 2.0 is a huge boost to this wave of new technologies. Recently, I am in charge of such a project to develop a USB interface Peripheral Device Driver Under wince. At that time, I spent a lot of time and energy on this project, and I was exhausted by many mistakes.
The requirement of the project is to develop a USB WiFi wireless NIC driver on the tuned arm9-board.ProgramThe specific requirement is that the driver platform is wince, And the CPU type supports the ARM architecture, which must be easily transplanted to x86; the driver interface types are USB2.0 and WLAN 802.11b. Later, the connection efficiency had been a problem, and the East was changed to the West. The last change was a mess. Fortunately, my boss is more tolerant and gives me plenty of time and support. Here I will share my understanding about USB driver development.
1. What is the wince device driver?
(1) Distinguish between driver Loading Methods
Before going into the peripheral device drivers supported by Windows CE, you should first understand the two types of devices used on the Windows CE platform: built-in devices and installable devices. Therefore, from the driver loading method, WinCE can be divided into local Device Driver (built-in driver), loadable Driver (loadable driver) and hybrid driver.
① Local device driver
The local device driver is native device drivers. Wince is designed to directly use built-in devices. These devices are controlled by the local driver process, and the local driver program is closely linked with the core components of wince. The devices corresponding to these drivers are usually loaded in the GWES process space when the system is started, so they do not exist in the form of independent DLL, therefore, each local driver must be consistent with a specific interface called the device driver interface (DDI.
The local device refers to the device integrated into the platform, including display, touch panel, audio, serial port, led, battery and PC card socket. Without these local devices, the entire system cannot communicate with users, such as touch panels and display. The local driver is generally designed as a dynamic link library, but there are two exceptions: the battery and LED Drivers are designed as static libraries due to small size (When CE images are established, they are linked to the GWES module ). Drivers of these devices are developed by OEMs during the development of the wince platform and stored in ROM or flash memory. Generally, only the OEM can modify the driver of the local device. Other free device manufacturers only provide additional hardware devices and do not involve too many drivers of the local device.
② Device drivers can be loaded
A portable device is a third-party interface device that can be connected and separated from the platform. It can be installed and detached by users at any time. The drivers of these peripheral devices are also called flow drivers, which can be dynamically loaded by the Device Manager at system startup or at any time after startup. These drivers usually exist in the form of DLL Dynamic Link Libraries. After the system is loaded, these drivers only run as user roles. The driver can be loaded by using the file operation API to obtain commands from the Device Manager and application. Typical load-able drivers in wince include: PCMCIA Driver (PCMCIA. DLL), serial driver (serial. DLL), ataflash Driver (ATA. DLL), Ethernet Driver (ne2000.dll, smsc100fd. DLL ).
Unlike local drivers, all load-able stream drivers share a public interface. This interface consists of 10 functions or record points in each driver that match the functions in the file API used by the application. Therefore, the stream interface driver that controls the device to be loaded is generally accessed by the application. The Stream interface driver displays the device functions to the application by a special file, this file can be opened, read, written, and closed. For example, after you connect a GPS device to the platform, you can start an application with the GPS function to access and use the device. Wince uses existing APIs to allow applications to access these drivers, rather than creating new APIs.
(2) classification at the driver level
Generally, it can be divided into two categories: independent drivers and hierarchical drivers. An independent driver is an independent driver that compiles a driver into a model Device Driver (MDD) and platform dependent Driver (PDD) layer. The advantage of using an independent driver is that it can save information transmission between the MDD and PDD layer drivers, which is very important in real-time processing. Independently drivenCodeThis includes interrupt service routines and platform-related processing functions. In addition, if the operation of the device is consistent with the interface description of the MDD driver layer, using an independent driver can improve the processing performance.
Hierarchical drivers are classified into two layers, the upper-layer MDD and the lower-layer PDD. MDD implements platform-independent functions, which describe a general driver framework, and PDD is composed of hardware and platform-related code. MDD calls a specific interface in PDD to obtain hardware-related information. When a hierarchical driver is used, you generally only need to modify the PDD program based on similar sample drivers and specific hardware. The framework established by MDD can continue to be used. However, the processing speed is slower than that of the independent driver due to layer-by-layer interface calls and message transmission. Therefore, hierarchical drivers are not suitable for embedded real-time environments with demanding requirements.
To put it simply, an independent driver writes PDD and MDD together without a strict distinction. Generally, this driver is relatively simple, such as atadisk. As for the local driver and the load-type stream driver, they are classified from the interfaces of the driver and other modules (callers) of the system. Therefore, an loaded driver can be an independent stream driver, such as atadisk, or a hierarchical stream driver, such as OHCI. That is to say, independence and layering are driving implementation methods, while local and loading streaming are driving models. The so-called local driver is that the operating system has a dedicated interface, and loading a stream driver refers to the interface for compiling DLL files to export various streaming interface functions.
With the increasing of USB devices, development of USB driver is becoming more and more important in embedded development. Windows CE's support for USB 2.0 is a huge boost to this wave of new technologies. The author of this article analyzes his own use-driven development experience, hoping that readers can take less detours.
With the increasing of USB devices, development of USB driver is becoming more and more important in embedded development. Windows CE's support for USB 2.0 is a huge boost to this wave of new technologies. Recently, I am in charge of such a project to develop a USB interface Peripheral Device Driver Under wince. At that time, I spent a lot of time and energy on this project, and I was exhausted by many mistakes.
The requirement of the project is to develop the driver for the USB WiFi wireless network card on the tuned arm9-board. The specific requirement is that the driver platform is wince, And the CPU type supports the ARM architecture, it is easier to port to x86. The driver interface types are USB and WLAN 802.11b. Later, the connection efficiency had been a problem, and the East was changed to the West. The last change was a mess. Fortunately, my boss is more tolerant and gives me plenty of time and support. Here I will share my understanding about USB driver development.
2. Key Points of USB-loaded streaming interface driver
To support different types of peripheral devices, the wince platform provides a stream interface driver model with custom interfaces. Because most USB peripheral devices are more suitable for the structure of the stream interface driver, they generally use the load-type stream interface driver model to develop the USB device driver.
(1) Structure Analysis of USB System
The USB system software under wince is composed of two layers: The driver layer of the higher USB device and the USB function layer. The lower USB function layer consists of two parts: the higher general serial bus driver (usbd) module and the lower master controller driver (HCD) module. The HCD module and usbd module are used to implement high-level usbd interface functions. The USB driver can communicate with peripheral devices.
During the data transmission process, the operation process is generally performed in the following order: ① the USB device driver initializes the data transmission, that is, a data transmission request is sent to the usbd module through the usbd interface function. ② The usbd module divides the request into several separate transactions. ③ The HCD module emits the transaction order. ④ The hardware of the master controller executes transactions. It should be noted that all transactions are sent from the host, and the peripheral devices are completely passively accepted.
(2) USB device driver entry point function
From the structure analysis, we can see that all USB device drivers must set certain entry points in their DLL libraries to interact with the usbd module properly. The entry point function has two functions: one is to enable the usbd module to interact with external devices, and the other is to enable the driver to create and manage any registration keys that may be required.
The following describes the functions of USB deviceattach: USB deviceattach runs when a USB device is connected to the master computer. The usbd module calls this function to initialize the USB device, obtain information about the USB device, and configure the USB device, and request required resources. USB installdrive is called first when the driver of the USB device is loaded for the first time. It enables the driver to create the required registration key, write the registry information required by a driver to the HKEY_LOCAL_MACHINE \ drivers \ USB \ clientdrivers directory, such as the device name. Note that the USB device driver uses the registerclientdriverid () and registerclientsettings () functions instead of the standard registry function to register the corresponding device information.
Usbuninstalldriver is called when a user deletes a USB device driver. It deletes the registration key and releases other related resources. It deletes all registration keys created by the driver's usbinstalldriver () function by calling the unregisterclientsettings () and unregisterclientdriverid () functions. Therefore, we need to strictly follow the prototype of the three functions in the driver, otherwise it cannot be recognized by the Device Manager.
1. What is the wince device driver?
(1) Distinguish between driver Loading Methods
Before going into the peripheral device drivers supported by Windows CE, you should first understand the two types of devices used on the Windows CE platform: built-in devices and installable devices. Therefore, from the driver loading method, WinCE can be divided into local Device Driver (built-in driver), loadable Driver (loadable driver) and hybrid driver.
① Local device driver
The local device driver is native device drivers. Wince is designed to directly use built-in devices. These devices are controlled by the local driver process, and the local driver program is closely linked with the core components of wince. The devices corresponding to these drivers are usually loaded in the GWES process space when the system is started, so they do not exist in the form of independent DLL, therefore, each local driver must be consistent with a specific interface called the device driver interface (DDI.
The local device refers to the device integrated into the platform, including display, touch panel, audio, serial port, led, battery and PC card socket. Without these local devices, the entire system cannot communicate with users, such as touch panels and display. The local driver is generally designed as a dynamic link library, but there are two exceptions: the battery and LED Drivers are designed as static libraries due to small size (When CE images are established, they are linked to the GWES module ). Drivers of these devices are developed by OEMs during the development of the wince platform and stored in ROM or flash memory. Generally, only the OEM can modify the driver of the local device. Other free device manufacturers only provide additional hardware devices and do not involve too many drivers of the local device.
② Device drivers can be loaded
A portable device is a third-party interface device that can be connected and separated from the platform. It can be installed and detached by users at any time. The drivers of these peripheral devices are also called flow drivers, which can be dynamically loaded by the Device Manager at system startup or at any time after startup. These drivers usually exist in the form of DLL Dynamic Link Libraries. After the system is loaded, these drivers only run as user roles. The driver can be loaded by using the file operation API to obtain commands from the Device Manager and application. Typical load-able drivers in wince include: PCMCIA Driver (PCMCIA. DLL), serial driver (serial. DLL), ataflash Driver (ATA. DLL), Ethernet Driver (ne2000.dll, smsc100fd. DLL ).
Unlike local drivers, all load-able stream drivers share a public interface. This interface consists of 10 functions or record points in each driver that match the functions in the file API used by the application. Therefore, the stream interface driver that controls the device to be loaded is generally accessed by the application. The Stream interface driver displays the device functions to the application by a special file, this file can be opened, read, written, and closed. For example, after you connect a GPS device to the platform, you can start an application with the GPS function to access and use the device. Wince uses existing APIs to allow applications to access these drivers, rather than creating new APIs.
(2) classification at the driver level
Generally, it can be divided into two categories: independent drivers and hierarchical drivers. An independent driver is an independent driver that compiles a driver into a model Device Driver (MDD) and platform dependent Driver (PDD) layer. The advantage of using an independent driver is that it can save information transmission between the MDD and PDD layer drivers, which is very important in real-time processing. Independent-driven code includes interrupt service routines and platform-related processing functions. In addition, if the operation of the device is consistent with the interface description of the MDD driver layer, using an independent driver can improve the processing performance.
Hierarchical drivers are classified into two layers, the upper-layer MDD and the lower-layer PDD. MDD implements platform-independent functions, which describe a general driver framework, and PDD is composed of hardware and platform-related code. MDD calls a specific interface in PDD to obtain hardware-related information. When a hierarchical driver is used, you generally only need to modify the PDD program based on similar sample drivers and specific hardware. The framework established by MDD can continue to be used. However, the processing speed is slower than that of the independent driver due to layer-by-layer interface calls and message transmission. Therefore, hierarchical drivers are not suitable for embedded real-time environments with demanding requirements.
To put it simply, an independent driver writes PDD and MDD together without a strict distinction. Generally, this driver is relatively simple, such as atadisk. As for the local driver and the load-type stream driver, they are classified from the interfaces of the driver and other modules (callers) of the system. Therefore, an loaded driver can be an independent stream driver, such as atadisk, or a hierarchical stream driver, such as OHCI. That is to say, independence and layering are driving implementation methods, while local and loading streaming are driving models. The so-called local driver is that the operating system has a dedicated interface, and loading a stream driver refers to the interface for compiling DLL files to export various streaming interface functions.
3. Implementation steps of USB device stream interface driver
From the analysis of the driver model and structure of the wince USB device, we can clearly see the implementation method between the host and peripherals. On the host end, the usbd module and the HCD module use the default pipe to access a common logical device. In fact, usbd and HCD are a set of logical interfaces used to access all USB devices, they manage the connection, loading, removal, data transmission, and general configurations of all USB devices. HCd is a host control driver, which provides underlying function access services for usbd, and usbd is a USB bus driver. It is located on the upper layer of HCD, and uses HCD services to provide high-level functions. Therefore, the following steps are required to implement a USB stream DRIVER:
(1) Select the prefix of the file name that represents the device. The prefix is very important. The Device Manager uses the prefix in the Registry to identify the device. In addition, This prefix is also used as the prefix of the entry point function during stream interface naming. If the device prefix is XXX, the stream interface corresponds to xxx_close and xxx_init.
(2) set each entry point function of the driver. The so-called entry point refers to the standard file I/O interface provided to the Device Manager. After a DLL is generated, replace xxx with the prefix of the device file name. Therefore, each loaded stream interface driver must implement a set of standard functions, such as xxx_init (), xxx_iocontrol (), and xxx_powerup, used to complete standard file I/O functions and power management.
(3) create a. Def file. After the Device Manager initializes the flow interface function compiled by the USB device, A. Def file must be created. The def file defines the interface set to be exported by the DLL, and most of the loaded stream drivers exist in the form of DLL, so the DLL and Def file names should be unified. The def file tells the linking program what kind of function to output, and finally compiles the driver into the kernel, so that the flow interface driver of the USB device can be called by the application.
(4) create a table entry for the driver in the registry. Create a driver entry point in the registry so that the Device Manager can identify and manage the driver. In addition, the Registry can store additional information that can be used after the driver is running.
During the development of the USB driver, I suffered a lot of mistakes. What impressed me most was that wince provided the general serial bus driver (usbd) module, the complete set of usbd interface functions, and the sample host controller driver (HCD) module. Therefore, we only need to use different functions provided by usbd Based on the hardware features of the USB device to realize the interaction between the streaming interface function and the peripheral device. Without special circumstances, my biggest achievement is to copy these public source programs, which can greatly shorten the development cycle and facilitate embedded development more quickly.