Windows CE shows that the driver is not a flow interface driver, and it is a local driver. The Registry Information of the local driver is generally the path information starting with [HKEY_LOCAL_MACHINE \ SYSTEM \] in the registry, the stream-driven registry information is generally the path information starting with [HKEY_LOCAL_MACHINE \ drivers \ builtin.
The display driver is directly loaded by the graphics, window, and event subsystem (GWES), rather than the Device Manager. The driver loading process is as follows:
After GWES. dll is loaded, GWES will find the Display Driver Based on the items under the Registry key HKEY_LOCAL_MACHINE \ SYSTEM \ GDI \ displaycandidates. The following code is displayed in platform. Reg:
; GWES will pass this value to the Display driver; the driver will open the; key to which it points to read its configuration.[HKEY_LOCAL_MACHINE\System\GDI\DisplayCandidates]"Candidate10"="Drivers\\Display\\s3c6410\\Config"
[HKEY_LOCAL_MACHINE\Drivers\Display\s3c6410\Config]"DisplayDll"="My_s3c6410_disp.dll"[HKEY_LOCAL_MACHINE\System\GDI\Drivers]"Display"="My_s3c6410_disp.dll"; Settings to rotate the screen by 0 degrees clockwise upon download[HKEY_LOCAL_MACHINE\System\GDI\Rotation]"Angle"=dword:0
GWES can find and load the initi6410_disp.dll, and write the initi6410_disp.dll as an item to the HKEY_LOCAL_MACHINE \ SYSTEM \ GDI \ driver key:
"Display" = "maid"
Because the display needs to implement hardware-independent operations, the driver uses a layered architecture (which can be viewed as the MDD and PDD layers ).
1. display the driving MDD layer
When talking about the MDD layer of the display driver, You Need To Know The GPE class. The GPE class is equivalent to the MDD layer of the display driver. The standard definition of Gpe is the graphics primitive engine ), GPE is an abstract class that abstracts display devices and can be seen as a general implementation of the display driver. It contains many pure virtual functions. Therefore, you cannot directly define GPE variables, you can only use it as the base class to construct your own GPE inheritance class before defining the instance. We also use its inheritance class to abstract specific hardware, that is, to implement our PDD layer and to implement the corresponding functions in the base class. The GPE class is defined in The GPE. h file, and GPE. H is under % _ wincerootmon \ oak \ Inc.
DDI is the abbreviation of the display driver interface. If you have read the serial port functions, the communication between the MDD and the PDD layer of the serial port is implemented through a series of interface functions. Here, DDI serves as an excuse to associate GWES with the device driver (PDD, logically, the implementation code of the DDI function is essential to construct any dynamic link library of the display device driver. It does not need to be driven by developers. Microsoft has helped us implement the code. DDI interface functions are implemented in ddi_if.cpp. The source file is in % _ winceroot % public \ common \ oak \ drivers \ Display \ GPE. How are these functions called? In fact, developers need to design a GPE class inheritance class and define an instance of this class to pass its pointer to DDI functions for their own implementation, an example of this GPE inheritance class is the software abstraction of the display device of the target hardware platform. It must correctly reflect the characteristics of a specific display device.
2. display the driver's PDD Layer
The PDD layer of the display device is related to the specific hardware. It is an inherited class of The GPE class. Let's take the 6410 display driver as an example. To be accurate, the parent class of the initiation6410disp class is not Gpe, but ddgpe, and the parent class of ddgpe is GPE. The reason why a ddgpe class is added in the middle is that the display driver currently discussed must support DDI, directDraw is also supported. The ddgpe class is defined in the ddgpe. h file. The source file is under % _ winceroot % \ public \ common \ oak \ Inc. A gpe inheritance class instance corresponds to a display device hardware, so all data members of The GPE type correspond to one attribute data of a display device. You can implement data members and functions in GPE based on the features supported by specific hardware devices as much as possible.
3. How does the GWES subsystem obtain the DDI function?
The device driver of the Windows CE system needs to implement its own functions. It exports functions and starts to run the IST thread. However, the display driver only displays data to the screen and does not start the IST thread. The following figure shows the function for exporting the driver Dynamic Link Library:
LIBRARY DDIEXPORTS DrvEnableDriver HALInit
On the surface, there are only two export functions. However, only one drvenabledriver function provides 27 DDI function pointers to the GWES subsystem of the Windows CE operating system. The drvenabledriver function is an essential driver for any Windows CE display device. It is the entry function of the driver and provides DDI pointers to GDI. Drvenabledriver () calls the gpeenabledriver () function, which is implemented in ddi_if.cpp. In this function, we can see that through memcpy (pded,
& Pdrvfn, CJ); the Code assigns the DDI function interface pointer to pded for GWES. pdrvfn is an array of the drvenabledata type, and the drvenabledata data Data Structure organizes the DDI function pointer.
4. How does the DDI function Deal with the display device hardware?
In ddi_id.cpp, we can see a function safegetgpe (). Its implementation code is as follows:
GPE * safegetgpe (handle hdriver) {GPE * pgpe = NULL; _ Try {If (hdriver! = (Handle) single_driver_handle) & (pfngetgpepercard! = NULL) {pgpe = (* pfngetgpepercard) (INT) hdriver);} else {pgpe = getgpe (); // This function is defined in initi6410_disp.cpp.} _ expect T (exception_execute_handler) {pgpe = NULL;} return pgpe ;}
The safegetgpe function is so complex because multiple controllers coexist in the system. In fact, most embedded devices only have one display controller. Only the getgpe function is called here. The specific function content is as follows:
GPE *GetGPE(){ if (!gGPE) { gGPE = new S3C6410Disp(); } return gGPE;}
Here, ggpe is a global variable of The GPE pointer type, but the implementation code of the getgpe function directly assigns a pointer to a newly generated instance of the class '201706410disp' to it, the initi6410disp class is an inherited class of Gpe. the pointer of the parent class can reference variables of the inherited class, and references to data members and member functions are given priority to the implementation or definition of the inherited class, therefore, when using the data or function pointed to by ggpe, we can obtain the member data or function implementation of the variable of the type of initi6410disp, which is only in the undefined part of the initi6410disp, to use the data members and data of the parent class. In this way, the DDI function can use the pointer to the instance we created to access our specific driver.
The general steps for developing the display driver are as follows:
(1) inherit The GPE class and define an instance of the class.
(2) Implement the getgpe () function to return the instance of this class to the DDI interface on the upper layer.
(3) Implement the drvenabledriver (...) function and export this interface.
(4) Implement functions in The GPE class.