April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Developing Windows CE Device Drivers: May a Regular Application Benefit from It?

  • May 4, 2006
  • By Alex Gusev
  • Send Email »
  • More Articles »

Brief Device Drivers Overview

What is a device driver? According to its definition, it is software that abstracts the functionality of a physical or virtual device. For instance, network adapters are physical devices whereas a file system or virtual serial port are of the second type. A device driver manages all operations of such devices. In this article, I don't pretend to make you an expert in device driver development, but rather give you an idea of how to use it for your own purposes as an application developer.

Under Windows CE, device drivers are trusted modules, but they aren't required to run in kernel mode. You might need to sign your driver with a certificate to run it on WM 5.0.

A couple of words about the driver's interface: Most Windows CE device drivers follow the common Windows philosophy and implement a Stream interface; in other words, they behave just like a file. Nevertheless, there are drivers with a different architecture; for example, for network or display adapters, keyboards, busses, ports, and so forth. I will show you "stream interface"-based device drivers on a simple power management driver as an example.

Stream drivers have to export the following functions:

  • XXX_Init
  • XXX_Deinit
  • XXX_Open
  • XXX_Close
  • XXX_IOControl
  • XXX_Seek
  • XXX_Read
  • XXX_Write

Actually, the first two functions are called during RegisterDevice and DeregisterDevice, respectively. All the rest of the implements stream the interface. I will discuss a device driver that also deals with power management, so you need the next two functions as well:

  • XXX_PowerDown
  • XXX_PowerUp

Now, let's take a look at actual implementation and later usage.

Sample Power Driver

Your sample device driver will perform simple yet important operations: It will notify applications when device power is about to be ON and OFF. The very first sight on the driver's code will lead you to the XXX_Init function:

PWRDRV_API DWORD PWR_Init(DWORD dwContext)
{
   // initialize the critical section
   // (used for changing the messaging HWND)
   InitializeCriticalSection(&g_csMsg);

   // create messaging working thread
   if (g_hMessageThread==NULL)
   {
      g_hMessageThread = CreateThread(NULL, 0, MessageThreadProc,
                                      NULL, 0,
                                      &g_dwMessageThreadId);
   }

   return TRUE;    // return non-zero value
}

First of all, the "XXX" placeholder was replaced by "PWR", which means that later on you can address this device as "PWR1:" and so forth. As was said above, this function is called during RegisterDevice. You will see how to use it later in this article.

So what does PWR_Init do? As you can see, only one simple thing—it starts a thread that periodically polls power state flags and in turn sends notifications if needed:

DWORD WINAPI MessageThreadProc(LPVOID lpParameter)
{
   while (1)
   {
      if (g_bPoweredUp && !g_bMsgSent)
      {
         g_bMsgSent = TRUE;
         EnterCriticalSection(&g_csMsg);
         if (g_hMsgWnd!=NULL)
         {
            PostMessage(g_hMsgWnd, WM_PWR_POWERUP, 0, 0);
         }
         LeaveCriticalSection(&g_csMsg);
      }

      // wait some time before polling again
      Sleep(1000);
   }

   return 0;
}

And finally, the PRW_Deinit function cleans up all resources:

PWRDRV_API BOOL PWR_Deinit(DWORD hDeviceContext)
{
   if (g_hMessageThread!=NULL)
   {
      TerminateThread(g_hMessageThread, 0);
   }

   DeleteCriticalSection(&g_csMsg);
   return TRUE;
}

In reality, you might want to add more initialization/deinitialization code, but for this simple purpose, it is enough. If you use such a driver from the application side, you have to call the open/close functions:

// Register power on notification driver DLL
hPwrDevice = RegisterDevice(
             TEXT("PWR"),          // device identifier prefix
             1,                    // device identifier index
             TEXT("PWRDRV.DLL"),   // device driver name
             0);                   // instance information (passed
                                   // to XXX_Init)

// open power on notification driver
g_hPwrDll = CreateFile(
            TEXT("PWR1:"),                      // "special" file name
            GENERIC_READ|GENERIC_WRITE          // desired access
            FILE_SHARE_READ|FILE_SHARE_WRITE,   // sharing mode
            NULL,                               // security attributes
                                                // (=NULL)
            OPEN_ALWAYS,                        // creation disposition
            FILE_ATTRIBUTE_NORMAL,              // flags and attributes
            NULL);                              // template file
                                                // (ignored)
...
// Close the power on notification driver
if (g_hPwrDll!=NULL) {
   CloseHandle(g_hPwrDll);
}
// Deregister the power on notification driver
if (hPwrDevice!=NULL) {
   DeregisterDevice(hPwrDevice);
}
...




Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel