Win CE driver Quick Start

Source: Internet
Author: User

Someone may be as anxious as I am and want to know how to write a specific driver as soon as possible. Here, we assume you have a good understanding of the driver, let us know how to get on the road quickly. Of course, if you have enough time, I suggest you have a thorough understanding of CE's overall system architecture before you start.

In Ce, the simplest driver is the stream interface driver of a built-in (built-in) device. For a device that does not support hot plugging, the quickest way is to implement a built-in stream interface driver for it.

For such a type of driver, we only need to implement a dynamic library according to a specific rule, which calls all hardware functions and then adds this dynamic library to the system, set the related registry key so that the Device Manager can identify and load the device when the system starts.

3.1 Implement Dynamic Link Library
The dynamic link library is not very different from the library used at the application layer. The source file can be C, C ++, or even assembly, but it must implement the following functions.

L dllentry (hinstance dllinstance, int reason, lpvoid reserved)

This function is the entry to the dynamic link library. Each dynamic link library needs to output this function, which is called only when the dynamic library is loaded and detached, that is, when the device manager calls loadlibrary, it is called when it is loaded into the memory and called unloadlibrary to release it from the memory. Therefore, it is the earliest called function of each dynamic link library, it is generally used to initialize some global variables.

Parameters:

Dllinstance: The DLL handle, which is similar to the handler function of an EXE file. It can be used to obtain some resources in the DLL, such as a dialog box. In addition, it is generally useless.

Reason:

Generally, we only care about two values: dll_process_attach and dll_process_detach. Reason equals that the former is the dynamic library loaded, and the latter is the dynamic library released.

Therefore, when reason is equal to the former, it initializes some resources and is equal to the latter, it is released.

L DWORD xxx_init (lpctstr pcontext, lpcvoid lpvbuscontext );
It is the first function called after the driver's dynamic library is successfully loaded. Its call time is only the same as that of dllentry. In addition, when a library is used to generate more than one driver instance, only one dllentry is called, and xxx_init is called multiple times. The driver should initialize the hardware in this function. If the initialization is successful, it will allocate a memory space (usually represented by a struct) and save its status, return the address of the memory block as a DWORD value to the upper layer. The Device Manager will send this handle back when calling xxx_open, so that we can access our own status. If initialization fails, 0 is returned to notify the driver that the program is not loaded successfully. All the previously allocated system resources should be released, and the life of the program ends.
When this function is successfully returned, the Device Manager will not proceed with this program unless it has set more features. So far, a device of XXX has been loaded successfully. When the user program calls createfile to open this device, the device manager calls the xxx_open function.
 
Parameters:
Pcontext: The registry key passed in by the system. It can be used to describe the configuration information we set in the registry.
Lpvbuscontext: Generally, this is not required.
In fact, many programs write this function as DWORD xxx_init (DWORD pcontext)
We only need to convert the pcontext to the lpctstr.
 
L DWORD xxx_open (DWORD hdevicecontext, DWORD dwaccess, DWORD dw1_mode );
When the user program calls createfile to open the device, the device manager calls the xxx_open function of the driver.
Parameters:
The value that hdevicecontext xxx_init returns to the upper layer, that is, the pointer to the struct allocated in xxx_init to record driver information, in this function, we can directly convert it into the defined structure to obtain the driver information.
The access method required by the upper layer of dwaccess can be read or write, or 0, that is, neither read nor write.
The sharing mode requested by the upper-Layer Program of dwsharemode can be the logic or, or 0 of the two values of shared read and write, that is, exclusive access.
The system layer has processed the access permissions and sharing methods for device files, so these two parameters can be ignored in the driver.
Generally, this function does not require much processing. You can directly return hdevicecontext to indicate that the operation is successful. For a hardware that does not support multiple users, after the device has been turned on, it should always return 0 or even fail, then, createfile fails to be called.
 
L DWORD xxx_close (DWORD hdevicecontext );
When the user program calls closehandle to close the device handle, this function will be called by the Device Manager.
Parameters:
The value that hdevicecontext returns to the upper layer for xxx_open.
This function should be opposite to xxx_open, including releasing the memory allocated by xxx_open and reducing the memory opened by the driver.
 
L DWORD xxx_deinit (DWORD hdevicecontext );
This function is called when the device is detached. It should implement operations opposite to xxx_init, mainly to release all system resources occupied by the former.
Parameters:
The handle that the hdevicecontext xxx_init function returns to the upper layer.
L void xxx_powerup (DWORD hdevicecontext );
L void xxx_powerdown (DWORD hdevicecontext );
As shown in its name, these two functions are called during system powerup and powerdown. These two functions cannot use any function that may cause thread switching. Otherwise, the system will crash. Therefore, in these two functions, there is almost nothing to do. Generally, a flag is made in powerdown to let the driver know that it has been down by power. In the process of power down/on, the hardware may lose power. Therefore, even after power on, the original IO operation will continue to be executed, but may fail. At this time, when we find that an I/O operation fails because the program has been in the power down state, we re-initialize the hardware and perform the same I/O operation.
L bool xxx_iocontrol (
DWORD hdevicecontext,
DWORD dwcode,
Pbyte pbufin,
DWORD dwlenin,
Pbyte pbufout,
DWORD dwlenout,
Pdword pdwactualout
);
Almost all functions of a driver can be implemented in this function. For devices supported by a type of CE, they have been defined as a set of Io operations. We only need to implement all Io operations according to the defined content of various devices. But when we implement a custom device, we can define our own I/O operations as needed.
Parameters:
The handle that hdevicecontext xxx_open returns to the upper layer, that is, a structure defined by us to store all program information.
Dwcode Io operation code. If it is a device class supported by Ce, you can use it to define the code value. Otherwise, you can define it yourself.
The buffer passed in by pbufin. Each Io operation code defines its own Buffer structure.
Dwlenin pbufin size in bytes
Pbufout and dwlenout are the outgoing buffer, respectively, and the size recorded in bytes.
The size of the data actually filled in by the pdwactualout driver in pbufout in bytes
 
The first two parameters are required, and any other one may be null or 0.
Therefore, when assigning values to pdwactualout, you should first determine whether it is a valid address.
 
3.2 Registry Settings
L add the following items to the Registry. (Usually in platform. Reg)

[HKEY_LOCAL_MACHINE/Drivers/builtin/sampledev]

"Prefix" = "XXX"

"DLL" = "mydev. dll"

"Order" = DWORD: 1

L add a project to the bib file and add the files used to the binfile (usually in platform. bib ).

Mydev. dll $ (_ flatreleasedir)/mydev. dll NK sh

L note:

Sampledev is a string that does not have the same name as other projects.

The prefix XXX of each function name can be any uppercase string, as long as it is the same as the value after the prefix in the registry.

3.3 compile the program
Now that you know what needs to be implemented, you must know how to implement it. The most direct method is to create a directory under platform/bsp/drivers, and add the new directory name to the dirs file in the DRIVERS directory.

In the newly created directory, create your C source code file to implement the functions and functions described above. Create a file named sources, makefile, and mydev. DEF respectively. The content is as follows:

Makefile: only such a row is required.

! Include $ (_ makeenvroot)/makefile. Def

The mydriver. Def file defines the functions to be output. These functions can be called by other code using dynamic loading methods. Format:

Library mydev (this string must be the same as the name of the dynamic library to be generated)

Exports

Xxx_init

Xxx_deinit

Xxx_open

Xxx_close

Xxx_poweroff

Xxx_power_down

Xxx_iocontrol

Sources: this file is very important and has many contents. The most basic file should have the following content.

Targetname = mydev (specify the name of the dynamic library to be generated)

Targettype = dynlink (specify the dynamic library to be generated)

(The following two items specify the dynamic library to be linked to. Generally, the first item is enough)

Targetlibs = $ (_ commonsdkroot)/lib/$ (_ cpuindpath)/coredll. Lib

Sourcelibs = $ (_ commonoakroot)/lib/$ (_ cpuindpath)/ceddk. lib/

Deffile = mydev. Def (specify the def file)

Dllentry = dllentry (specify the entry function of the dynamic library)

Sources = (write the names of all your source files here and they will be compiled)

 

Now everything is ready, with only compilation left.

3.4 compile the driver library file with a project file
If you are using ce5.0, it is a good choice to construct a driver using a project. That is, when you create a project, set its type to DLL. You can set other settings as prompted. You can also place registry settings in the folder where the project is located.

3.5 Basic Debugging Method
Generally, the driver can be debugged in debug or output. We usually use these two functions to output debugging information: retailmsg and debugms. The latter can only be output in the debug version, while the former can both be output in the release and DEBUG Versions, you can select the debugging information that debugmsg outputs based on the debug zone during system operation.

The driver debugging can be divided into the following steps:

1. Check whether the driver's dllentry is called. If this function is called, the driver file is already in CE's image and the file name is the same as that set in the registry.

2. Check whether the init function is called. If it is called, it indicates that the Registry is set correctly. If it is not called, it is generally because the prefix setting in the registry is different from the three characters before the init function. Or the init function is not defined in the def file. If this function can be called but the driver still cannot be loaded correctly, check the code in detail.
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.