Using Minidrivers for Instant Device Activation

This chapter includes:

Advanced CPUs are providing higher levels of hardware integration than ever before, directly controlling such interfaces as CAN, J1850, and MOST. This approach saves on hardware costs by reducing the need for extra chips and circuitry, but it also raises concerns for the software developer.

For instance, a telematics control unit must be able to receive CAN messages within 30 to 100 milliseconds from the time that it's powered on. The problem is that the complex software running on such a telematics device can easily take hundreds of milliseconds—or more—to boot up.

As another example, consider the critical milestones during the boot process for an in-car telematics or infotainment unit that typically boots from a cold condition (completely powered off) or from CPU reboot condition (returning from a state where SDRAM has been turned off). The unit must be able to:

In order to address such timing requirements, many embedded system designs rely on a simple but expensive solution that uses an auxiliary communications processor or external power module. This auxiliary hardware can be reduced in scope and sometimes even eliminated by using Instant Device Activation. Also called minidriver technology, the approach consists of small, highly efficient device drivers that start executing before the OS kernel is initialized.

The minidriver basics

During the normal QNX Neutrino boot process, a driver process can't run until the OS image has been loaded into the RAM, and the kernel has been initialized. Depending on the particular hardware (processor, flash, architecture) and the OS image size, this time can be in the order of hundreds of milliseconds or even seconds. To reduce this time, a minidriver runs much earlier in the boot process to take care of the timing requirements for some bus protocols such as MOST or CAN.

Defined in the system's startup code, a minidriver runs user code before the operating system has been booted. This code could include responding to hardware power-up messages in a quick, timely fashion and ensuring that no message is lost when the OS boots up. Once the OS has booted, the minidriver may continue running, or it may pass control to a full-featured driver that can access any data the minidriver has buffered.


The minidriver


Booting process using instant device activation.

The minidriver architecture

A minidriver is a function that you link to the QNX Neutrino startup program, so that it runs before the system becomes operational and the kernel is initialized. A minidriver can access hardware and store data in a RAM buffer area where a full (process-time) driver can then read this buffered information.

During system startup, a minidriver handler function is periodically called (or polled). You can adapt this periodic/polled interval to suit your device's timing requirements with minor changes to the startup program. At some point in the system startup, interrupts become available, and this handler function becomes interrupt driven. The handler is called with a state variable, so the handler knows why it was called.

How does the minidriver work?

A minidriver is a function that you link to the QNX Neutrino startup program, so that it runs before the system becomes operational and the kernel is initialized. A minidriver can access hardware and store data in a RAM buffer area where a full (process-time) driver can then read this buffered information.

During system startup, a minidriver handler function is periodically called (or polled). You can adapt this periodic/polled interval to suit your device's timing requirements with minor changes to the startup program. At some point in the system startup, interrupts become available, and this handler function becomes interrupt driven. The handler is called with a state variable, so the handler knows why it was called.

Seamless transition

As soon as a full driver process is running in a fully operational system, transition takes place from the minidriver to a full driver. This transition is seamless and causes no blackout times. The full driver merely attaches to the device interrupt, which causes the minidriver to be notified that another process is attaching to its interrupt. The minidriver can then gracefully exit, and the full driver continues to run. The full driver has access to any buffered data that the minidriver chooses to store.

Running multiple handler functions

The minidriver can run multiple handler functions. For devices that must do something every n milliseconds, you could attach two handler functions:

Since the timer minidriver is intermittently polled (i.e., not invoked at a constant interval) during startup, the driver needs to use something to measure the time between the calls to get the proper interval.

This architecture allows device drivers to start very early in the system startup and allows the device to continue to function during all boot phases. If a full driver doesn't choose to take over device control, the minidriver continues to run when the system is fully operational.