Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C

Loading/Unloading WinCE Drivers at run time

0.00/5 (No votes)
6 Nov 2011CPOL4 min read 15.5K  
Describes a process to load/unload built in drivers under WinCE at run time to speed up development process
Introduction

Debugging of built in drivers under WinCE can be a time consuming process, as an image update (or at least a unit reset) is required every time the driver is changed. This is less noticeable when working with a retail image (from flash or KITL), however when working with a debug image, this can be quite painful. This tutorial goes over how to setup a driver so that it can be loaded/unloaded during run time, allowing for changes to be made to the driver while an image is running on the unit.

NOTE: I have only tested this with the WinCE 6.0. I'm not sure if the API calls are supported for earlier versions of WinCE.

NOTE: Not every driver is a good candidate for this (i.e., if there are dependencies on this driver at start-up by other drivers). Even if there are dependencies, it might be possible to work out a way to do this, but it might be more trouble than it's worth.

Requirements

The process described in this tutorial will work for retail and debug images. If code level debugging is required with a retail image (KITL), special steps must be taken to compile the driver properly and setup the image. The requirements for different image types are described in subsections below.

Release Image (Flash)

While it's possible to perform loading/unloading of built in drivers at run-time with this image type, it's a hassle. Not worth it, just remake the driver and re-make img and reload to the unit. It's not possible to debug at the code level with this type of image anyway.

Release Image (KITL)

With this image type, you will not be able to debug the driver at the code level but it's fairly straightforward to load/unload at run time.

The following are required:

  1. "Enable KITL" must be checked and "Write run-time image to flash memory" must be unchecked in the Build Options.
  2. Under "Tools"->"Release Directory Modules", ensure that the driver is set to load from release directory.

Release Image (KITL)

This case is almost identical to the previous one, but the benefit here is that code level debugging is possible. This provides the best trade off between loading an image quickly and still being able to debug the code. The downside is that it's not possible to debug everything in the image, just drivers which have been compiled specifically for this. In most circumstances, this is ideal.

The following are required:

  1. "Enable KITL" must be checked, "Enable kernel debugger" must be checked, and "Write run-time image to flash memory" must be unchecked in the Build Options.
  2. Under "Tools"->"Release Directory Modules", ensure that the driver is set to load from release directory.
  3. The driver must be compiled with the debug flag set.


Open a command prompt from Visual Studio (ensure it is set for retail), and use a script like this to compile the driver:

ECHO "Comping <xxx> Driver for Debug"
set WINCEDEBUG=debug 
cd "c:\WINCE600\PLATFORM\COMMON\SRC\<commoncode>\DRIVERS\<xxx>\"
build -c 
cd "c:\WINCE600\PLATFORM\<platformcode>\SRC\Drivers\<xxx>\"
build -c 
set WINCEDEBUG=retail 
makeimg</xxx></platformcode></xxx></commoncode></xxx>


This will ensure that the driver is compiled with debug flags and the result will be put in your OSDesigns retail folder. A new image will be created at the end as well (this is not technically necessary as KITL will load the driver from your OSDesigns folder).

Debug Image

Only the default debug image variation will be accounted for. In this image, everything is debug-able at the code level, no special steps need to be taken.

Loading/Unloading

To actually load/unload the driver during run time, a small utility is required.

NOTE: I plan to attach a sample application soon.

The API used is fairly straight forward and involves getting a list of running drivers from which the user can choose which devices to load/unload. The list of drivers can be filtered to specify specific ports (i.e., COM* for all COM ports).

The key pieces of code are:
FindFirstDevice(DeviceSearchByLegacyName,wszFilter,&di)
FindNextDevice(hDevice,&di)

Use these functions to go through and find all drivers that are found via the filter (wszFilter).

DeactivateDevice(di.hDevice),
ActivateDeviceEx(di.szDeviceKey,NULL,0,NULL) 

Use the di descriptor of your driver to Deactivate and Activate the driver. After you deactivate the driver, make the changes to your code, compile the driver and then Activate it.

When you recompile the driver, it gets put into your OSDesigns folder. If your image has KITL (and you added your driver to "Release Directory Modules"), the new driver will be loaded to the OS when you activate it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)