Search by Tags

asynchronous driver loading

 
Article updated at 02 Oct 2018

This article applies to IMX6 modules running Windows Embedded Compact 7 or Windows Embedded 2013 using BSP version 1.4b2 or newer.
To speed up the boot process and avoid issues related to non-responding external devices, the way drivers are loaded when the OS starts has been modified.

Synchronous loading

By default, all the drivers configured under HKEY_LOCAL_MACHINE\Drivers\Builtin are loaded in sequence. The system checks all the entries, verifies which ones have an Order value set and then sorts the drivers based on that value (drivers with order 0 are the first ones to be loaded, drivers with no order are loaded after all the drivers with a specified order). The OS calls the driver initialization function, wait until it's completed and then loads the next driver. In this way is simple to control load order, but only one driver a time is running its init function, even on multi-core systems.

Asynchronous loading

In this mode, the system is still checking all the drivers under HKEY_LOCAL_MACHINE\Drivers\BuiltIn but, instead of loading them sequentially, it will try to initialize them in parallel. Drivers will be initialized complaining of the value of their "Order" key, but it's not granted that the initialization of one driver is completed before the next one is called. This will spread initialization of devices across multiples cores and will use the time that a driver spends waiting for some event to run other initialization functions.
Of course, you may have drivers that rely on other drivers to work (ex: touch driver relies on I2C communication). Next chapter will show how to configure those dependencies.
Some drivers are still loaded synchronously because they are needed for basic system operativity (ex: clocks) or for compatibility reasons. To load a driver asynchronously you need to add the following entry to its load key (showing Audio driver as a sample):

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Audio]
	"LoadAsync"=dword:1

Disabling Asynchronous Driver Loading

To revert back to synchronous driver loading, you need to set the following registry value:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn]
	"Dll"="BusEnum.dll"

Configuring dependencies for asynchronously loaded drivers

To delay the initialization of a specific driver after the initialization of a different one has been completed you can add a subkey named "DependsOn" to the driver entry under HKEY_LOCAL_MACHINE\Drivers\BuiltIn. Then you can add values for the drivers that need to be initialized before the current one. Those entry are strings and contain the registry path of the required driver.
For example, the audio driver [HKLM\BuiltIn\Audio] depends on the I2C2 device and on the WAPIMAN virtual driver (managing audio drivers in Windows CE). Initializing the audio driver before those two components have been fully initialized will lead to an error and the audio driver will not work.
To add the required dependencies two entries must be added for the audio driver (those are, of course, already there in the default configuration):

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Audio\DependsOn]
	"I2C2"="Drivers\Builtin\I2C2"
	"WAPIMAN"="Drivers\BuiltIn\WAPIMAN"
 

The name of the string values has just a descriptive purpose, remember that backslashes must be double if you are editing a .reg file in text format.
The order entry is no longer used to manage dependencies between different drivers.

Waiting until flashdisk folder is mounted to load external drivers

If you need to load a driver that is not part of the OS image you'll probably load it from the internal flash, mounted as \FlashDisk folder in Windows CE. To ensure that this folder is ready when you need to load the driver you can add the Drivers\BuiltIn\Wait4Flash driver as a dependency of your driver.
If you need to load USB or SD-card drivers at boot you may need to add the following entries:

; you need this entry if you plan to load a driver for a SD device on slot 1
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\USDHC1\DependsOn]
"FlashDisk"="Drivers\\Builtin\\Wait4FlashDisk"
 
; you need this entry if you plan to load a driver for a SD device on slot 2
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\USDHC2\DependsOn]
"FlashDisk"="Drivers\\Builtin\\Wait4FlashDisk"
 
; you need this entry to load drivers for USB external devices at boot
; standard classes like HID or storage are supported by drivers that are part of the image
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\HCD_HSH1\DependsOn]
"FlashDisk"="Drivers\\Builtin\\Wait4FlashDisk"
 

Delaying application startup until driver is ready

If your application relies on a specific device you may want to wait until the corresponding driver is available. In the syncronous mode user mode applications are started always after the initialization of drivers.
In asynchronous mode an application may be started when some drivers have not been initialized yet. You can add a retry-polling loop, but the most efficent way is to use the same event that the driver loader uses.
If you use OpenEvent to create an event named LOAD_EVENT_DRIVERS+ you can then use it to wait until the driver is ready to accept your requests.
For example, if you need to access I2C1 driver, you can use this code:

HANDLE i2cevent=OpenEvent(EVENT_ALL_ACCESS,FALSE,TEXT("LOAD_EVENT_DRIVERS\\BUILTIN\\I2C1"));
 
if (WaitForSingleObject(gchalevent,<timeout>)!=WAIT_OBJECT_0)
{
   // driver initialization failed, driver not loaded or not initialized in the required timeout
   ...
}
else
{
    // driver loaded, you can access it
    ...
}