The stream device driver is actually the driver for exporting standard stream interface functions. This is the definition above. In wince, all stream devices export stream device interfaces, so that Device Manager in wince can load and manage these stream device drivers.
Architecture of stream device driver
First, I declare that I copied this image. When wincestarts, oal(oal.exe) First loads the kernel. DLL, and then kernel. DLL load device. DLL, device. DLL loads devmgr. DLL, devmgr. DLL is actually the Device Manager module, which is responsible for loading, detaching, and interacting with stream devices. This can be seen.
Let's talk about the application. Generally, the application accesses the device through the file system interface. Call createfile to open the device and obtain the corresponding handle. Then, call readfile or writefile through the file system interface to access the corresponding stream device driver, or directly access the device through deviceiocontrol. Either way, you must use Device Manager to access the corresponding device driver, for example.
I do not know whether the above architecture is clear or not. The following describes the interface functions of the stream device driver:
1. DWORD xxx_init (lpctstr pcontext, DWORD dwbuscontext ):
This function is used to initialize a stream device driver. It is called when the device is loaded. After the call is successful, a handle is returned. Pcontext: A string dwbuscontext in the active Registry Key Path: not commonly used. Here it can be set to 0 2. bool xxx_deinit (DWORD hdevicecontext): Uninstall a device driver. Hdevicecontext: the handle of the device driver, which is returned when xxx_init is called.
3. DWORD xxx_open (DWORD hdevicecontext, DWORD accesscode, DWORD secure mode): Open a device.
Hdevicecontext: the handle of the device driver, which is returned when xxx_init is called.
Accesscode: access permission code, which is generally read-only or write-only
Sharing Mode: Shared Mode. Whether shared or exclusive mode is supported
4. bool xxx_close (DWORD hopencontext ):
Disable a device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
5. DWORD xxx_read (DWORD hopencontext, lpvoid pbuffer, DWORD count ):
Read data from the device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
Pbuffer: buffer for storing data
Count: the number of bytes to read data.
6. DWORD xxx_write (DWORD hopencontext, lpcvoid pbuffer, DWORD count ):
Write Data to the device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
Pbuffer: buffer for storing data
Count: the number of bytes written to the data.
7. DWORD xxx_seek (DWORD hopencontext, long amount, Word type ):
The data pointer in the mobile device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
Amount: number of bytes to move
Type: file_begin indicates moving from scratch
File_current indicates moving from the current position
File_end indicates moving forward from the end
8. Void xxx_powerup (DWORD hopencontext ):
Power on the device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
9. Void xxx_powerdown (DWORD hopencontext ):
Power off the device.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
10. bool xxx_iocontrol (DWORD hopencontext, DWORD dwcode, pbyte pbufin, DWORD dwlenin, pbyte pbufout, DWORD dwlenout, pdword pdwactualout ):
Device Io control operation function.
Hdevicecontext: the handle of the device driver, which is returned during the xxx_open call.
Dwcode: operation code
Pbufin: input buffer
Dwlenin: input buffer size
Pbufout: output buffer
Dwlenout: size of the output buffer
Pdwactualout: number of bytes actually output
11. bool xxx_preclose (DWORD hopencontext ):
Mark a handle to be closed as invalid and wake up all sleeping threads
Hdevicecontext: the handle of the device driver, which is returned when xxx_init is called.
12. bool xxx_predeinit (DWORD hdevicecontext ):
Mark a device instance as invalid and wake up all sleeping threads
Hdevicecontext: the handle of the device driver, which is returned when xxx_init is called.
The above functions are all the interface functions driven by the stream device, which should not be difficult to understand. The following is an example of a streaming Device Driver Based on wince6.0 (slightly different from wince5.0 in some configuration files ). Here we will introduce a stream device driver for operating gpio and the steps for adding a stream device driver:
(1) modify the BSP project file and add the gpio driver options:
In the "catalog" folder under the BSP directory, find "bspname. pbcxml" and open it with notepad. Then add the gpio driver option. First find <BSP>... </BSP> and add the following line in it:
<Bspitemid> item: Cirrus Logic: bsp_ep94xx_gpio_ep9407_ep94xx </bspitemid>
Then in <catalogfile>... </Catalogfile> Add the following driver description:
<Item id = "item: Cirrus Logic: bsp_ep94xx_gpio_ep9407_ep94xx">
<Title> gpio </title>
<Description> gpio driver </description>
<Type> bspspecific </type>
<Variable> bsp_ep94xx_gpio </variable>
<Location> device drivers </location>
<Sourcecode>
<Title> $ (_ winceroot) \ platform \ ep94xx \ SRC \ drivers \ gpio </title>
<Path> $ (_ winceroot) \ platform \ ep94xx \ SRC \ drivers \ gpio </path>
</Sourcecode>
</Item>
The gpio driver is actually added above. The environment variable is bsp_ep94xx_gpio, and the source code is located under the path "\ platform \ ep94xx \ SRC \ drivers \ gpio.
(2) create a gpio driver folder and change the Dir file:
Go to the \ platform \ ep94xx \ SRC \ drivers \ directory and create a folder named "gpio", which contains the gpio driver. Open the dirs file and add "gpio" at the end ".
(3) Develop the gpio DRIVER:
Go to \ platform \ ep94xx \ SRC \ drivers \ gpio and create the gpio. c file. encapsulate the corresponding stream device interface functions in the file, as shown below:
Gpi_init (..)
Gpi_deinit (..)
Gpi_read (..)
Gpi_write (..)
...
You can read the gpio status in the gpi_read function and set the gpio status in the gpi_write function. Of course, you can also use the gpi_iocontrol function.
Create a MAKEFILE file under the path and include the following line in it:
! Include $ (_ makeenvroot) \ makefile. Def
Next, create a module to export the gpio. Def file. The details are as follows:
Library gpio_lib
Exports
Dllentry
Gpi_init
Gpi_deinit
Gpi_open
Gpi_close
Gpi_read
Gpi_write
Gpi_seek
Gpi_iocontrol
Gpi_powerdown
Gpi_powerup
Finally, create the sources file for compilation. The specific content is as follows:
! Ifndef bsp_ep94xx_gpio
Skipbuild = 1
! Endif
Targetname = gpio
Releasetype = Platform
Targettype = dynlink
Targetlibs = \
$ (_ Sysgensdkroot) \ Lib \ $ (_ cpuindpath) \ coredll. Lib
Dllentry = dllentry
Sources = gpio. c
(4) Add the Registry configuration of the gpio DRIVER:
Open the platform. reg file under the "\ platform \ ep94xx \ files \" directory and add the following Configuration:
If bsp_ep94xx_gpio
; Add these entries to your registry to enable the gpio Device
[HKEY_LOCAL_MACHINE \ drivers \ builtin \ gpio]
Prefix "=" GPI"
"DLL" = "gpio. dll"
"Order" = DWORD: 1
Endif
(5) Add the driver module to NK.
Open the platform. bib file under the "\ platform \ ep94xx \ files \" directory and add the following content:
If bsp_ep94xx_gpio
Gpio. dll $ (_ flatreleasedir) \ gpio. dll NK Shk
Endif
That's all. The above example was actually done in the project. At that time, a customer wanted to directly operate gpio through the application, so I wrote this driver for them. As long as you have some basic knowledge of Wince BSP, it should be very easy to understand the above content. Because it is a project I have done, some of the above path, name and other settings are based on the bsp I use, for your reference only.