Windows Embedded Musings (CE/Compact/Standard)

Windows CE Drivers

Download GPIO Example driver and appplication source code In previous articles I have developed a driver to access GPIO Pins, Windows CE: Using a Driver to Read/Write Hardware Registers, and a wrapper API for the driver, Windows CE: Developing an API to Access a Driver. Now it is time to use them from an application. Because the real work is done in the driver, and because we have some simple to use wrapper functions, this application is very simple. It starts by calling the InitGPIOAPI() function, ......

Download GPIO Example driver and appplication source code A recent discussion thread in the Windows Embedded Compact Platform Development forum made it clear to me that for new Windows CE Software Engineers doing something as simple as accessing a hardware register can be very difficult. In the old days, Windows CE 5.0 and before, it was very easy; write an application that allocates a virtual address and then read or write a register. The problem with that is that allowing applications to access ......

Download GPIO Example driver and appplication source code In my article on reading and writing GPIO pins from a driver (see Windows CE: Using a Driver to Read/Write Hardware Registers) I developed a driver that exposes GPIO pins through DeviceIoControl() calls to the driver’s XXX_IOControl() function. Using DeviceIoControl() can be messy, so developing wrapper functions helps clean that up, but if the driver developer also created the wrapper and provided it as an API that would help. An API is really ......

One of our engineers was adding a third party driver to system today and had trouble getting it to work. When he installed from the CAB file that was provided, it worked correctly. When he built it into the OS, it wouldn’t work correctly (unfortunately I didn’t discuss it in enough detail to tell you what it was doing.) Just before the end of the day he called out to me and said he left the K flag out. For those of us who read the Platform Builder newsgroup regularly, we know that this is a common ......

A reader recently asked me the following: “What do you need to do exactly to change the legacy namespace of an existing driver? I have a serial port driver (for an expansion card with 4 serial ports) which works and uses the COM-prefix, but I want to change the COM-prefix to something else, so that it's easier to distinguish between onboard COM-ports and the ports on the expansion card... I've changed the prefix in the registry and also in the .def-files. But when I try to compile it, I get LNK2001-errors ......

There is a lesser known feature of stream interface drivers, the post init IOCTL. This is probably lesser known because there isn’t a good way to put this in the help index and it doesn’t appear to be mentioned in the stream interface section of the help contents. The post init IOCTL is an IOCTL that is called by the device manager after calling XXX_Init(). The purpose is that this allows your driver to do some initialization after XXX_Init() runs. Huh, initialization after XXX_Init() runs? Yes, ......

I was working on a driver suspend/resume issue this week. The driver was originally developed without support for the Power Manager, but really it would work better if it could respond to requests from the Power Manger to change power states. No problem, I just went to Windows CE: Stream Interface Driver Power Management and cut and pasted some code and in no time had the driver ready to work with the Power Manger. The next step was to advertise to the Power Manager that the driver wanted to be managed. ......

The Windows CE PCL printer driver seems to be a little bit simple in its support of different Dots Per Inch (DPI) settings. It only supports two; 150 and 300 DPI. Interesting since there appear to be settings for low and high resolution DPI in the registry for each printer, and they are different for the default printers. In this article, I will explain how to clone the PCL driver and modify to hard code new DPI settings – I will leave a fancier implementation up to you. Steps that I used to modify ......

CeSetPowerOnEvent() is an interesting and powerful function when used with Windows CE 4.1 and 4.2, but after that its behavior changes. CeSetPowerOnEvent() was created to allow drivers to set events in their XXX_PowerUp() and XXX_PowerDown() functions. The power functions must not call functions that block or could cause a context switch, which included SetEvent(), so CeSetPowerOnEvent() was created to queue up the events temporarily to be signaled later. Behavior of CeSetPowerOnEvent() in Windows ......

Maybe someone knows a better way to get the device emulator to suspend and resume, but since that wasn't my end goal this is a story of what I did to get the emulator to resume. I am sitting in a hotel room with nothing much to do so I thought it would be a good time to add power management capabilities to my Windows CE: A Stream Interface Driver Shell. I brought a device with me, and I have everything I need to use it, except a cable to connect to the serial debug port which I need. So since I already ......

You just created a new Stream Interface driver, but it isn’t being loaded. I hear this a lot and thought it would be good to look into the possible causes. Hopefully, if you are here you have already reviewed Windows CE: A Stream Interface Driver Shell which provides a very basic driver an all of code and other files to demonstrate a driver that actually loads. The first things to check: 1. Is the driver in you OS image? Check to see that it is in %_FLATRELEASEDIR%\ce.bib. 2. Do all of the functions ......

In the DriverShell Example that I posted (Windows CE: A Stream Interface Driver Shell), I included an XXX_Init() function that didn’t do very much. This post will discuss the things that you can do with XXX_Init(). For reference, this is the function as I originally posted it. DWORD XXX_Init(LPCTSTR RegistryPath, DWORD dwBusContect) { HKEY hKey; RETAILMSG( 1, (TEXT("XXX_Init\n"))); hKey = OpenDeviceKey(RegistryPath); if ( !hKey ) { RETAILMSG(1, (TEXT("Failed to open devkeypath,\r\n"))); } else { ......

I was working with a customer today and discovered that their application was calling into one of my drivers repeatedly to read 4 bytes at a time, each time reading the next 4 bytes of data. The driver reads a minimum of 4 bytes, or they probably would have read less, but the driver is capable of reading large quantities of data on each call from the application. This really isn’t all that uncommon though and it actually will read the data correctly. The problem is that each call to the driver has ......

In my post about a basic driver shell, I assumed that the driver was built into the system including the registry settings to cause the device manager to load the driver when the system booted. Sometimes there is a reason to load a driver when an application starts. For that there are several functions that can be used including; RegisterDevice, ActivateDevice and ActivateDeviceEx. RegisterDevice is maintained for backward compatibility, but for future compatibility you probably should start using ......

I thought I would spend some time to explain some basic USB terminology. This information might be helpful if you have been assigned the task of writing a USB driver, but don’t have any idea where to start. This will certainly not take the place of better sources like www.usb.org or books like USB Complete: Everything You Need to Develop Custom USB Peripherals by Jan Axelson. What I hope is to quickly give you enough information to hold a conversation about USB. Terminology: Host is the controller ......

Many Windows CE systems are kiosk type devices, where the Software running on the systems starts when the system boots. This causes a new problem for some software developers: the API may not be ready to be used when the software starts. To add to the fun, not all Windows CE systems are equal so some APIs may never become available. Early versions of Windows CE provide a simple method to determine if an API is available, the function IsAPIReady(). IsAPIReady() is a handy method to determine if an ......

This week I was asked how to access a stream interface driver from an application. The request came from someone who was trying to call the XXX_Open, XXX_Write… functions directly from his application. By directly, I mean using LoadLibrary() and GetProcAddress(). Let’s start with stating that calling the functions directly is not the way to call the functions in a driver. In fact, a Windows CE 6.0 kernel driver cannot be accessed at all by applications directly. Let us think about that for a moment ......

I have been working on a problem for a couple of weeks now. I even wrote about it in Windows CE: Finding an Out of Control Thread where I declared that I had found the thread that had the problem. It turns out that I was wrong, and I am willing to admit it. In Windows CE: Finding an Out of Control Thread I showed how I found the thread that was using 100% of the CPU time by finding the thread priority of the thread. I didn’t discuss it, but I did consider priority inversion and ruled that out. It ......

An Interrupt Service Thread (IST) is the way that drivers in Windows CE service an interrupt. Typically, a driver will contain a thread function that handles the interrupt, and does nothing else. A typical IST will do the following: 1. Create an Event 2. Register with the kernel 3. Set the thread priority 4. Wait for the event to be signaled 5. Service the hardware 6. Tell the kernel that the interrupt has been serviced 7. Repeat steps 3, 4 and 5 There are certainly variations in how ISTs are written ......

The UIProxy source code can be downloaded from: Download UIProxy Source Code In Windows CE 6.0: Using UIProxy I discussed how to use CeCallUserProc() and the UIProxy. I showed some simple code for displaying a very simple MessageBox(). For this post, I thought that it would be interesting to flesh that out a little more and create a user mode DLL that wraps MessageBox() and allows the driver to do everything with MessageBox() that it might do if it was calling it directly. Almost everything, except ......

Starting with Windows CE 6.0 kernel mode drivers cannot call User Interface (UI) functions. To overcome this Windows CE 6.0 provides the UIProxy and a new function, CeCallUserProc(). Kernel mode drivers can call CeCallUserProc() to request that a user mode dll be loaded and a function in the dll be called. When writing the driver, also write the user mode dll and provide functions that will present a UI for the driver. Luca Calligaris was nice enough to provide an example function in response to ......

Many of you already know about the use of the C/C++ keyword volatile, but I was having a discussion with a colleague this afternoon and the topic came up. The colleague is a bright up and coming engineer who finds himself writing software, but really wanting to design hardware. He was telling me about a test that he wrote to estimate the CPU speed of a board. Simple little application, get the current milliseconds using GetTickCount(), then run a busy loop. When the loop completes call GetTickCount() ......

If you have looked at my other posts on stream interface drivers, you have seen that the registry settings that I use for Driver Shell are: [HKEY_LOCAL_MACHINE\Drivers... "Dll"="DriverShell.dll" "Order"=dword:4 "Prefix"="XXX" "DeviceArrayIndex"=dword:1 "IClass"="{A32942B7-920C-48... I thought that I would discuss these a little more, and includes some other settings. Let’s start with the key HKEY_LOCAL_MACHINE\Drivers\... The key HKEY_LOCAL_MACHINE\Drivers\... ......

Yuqun Cao, SDE, Windows CE JDP of Microsoft, released a whitepaper on enhancing BusEnum a few months ago. I finally had a chance to read it yesterday and was impressed by the additions that he made to BusEnum. The changes allow for drivers to be loaded asynchronously. This change can be used to speed up the perceived time to boot a Windows CE system to the desktop or a kiosk application. The BusEnum that comes with Platform Builder loads drivers one at a time. It loads the drivers using ActivateDeviceEx() ......

Windows CE provides several ways to synchronize threads and access to data by multiple threads. These include the synchronization objects that are typical for a multithreaded operating system: mutex, semaphores, events and critical sections. These synchronization objects may be overkill for protecting access to a single variable. The Interlocked functions can be used to control access to a single 32 bit variable. The interlocked functions are: Function Name Action InterlockedCompareExchange Compares ......

I have written about cloning code from the Public tree to a platform in the past, but someone recently asked about cloning an MDD lib build directory. More specifically the question was about cloning ufnmdd.lib in Windows CE 5.0, which is actually created by linking three separate libs together. In this article, I will walk through the process by cloning one of those libs. Ufnmdd.lib is created by linking ufnmddbase.lib, ceosutil.lib and defbuslib.lib. I suspect that most people don’t really need ......

Posts About Stream Interface Drivers Windows CE: A Stream Interface Driver Shell This post contains all of the code necessary to create a driver which will actually be loaded by the device manager. It gives a simple starting point for developing a Stream Interface driver. Windows CE: Stream Interface Driver, DllEntry() A short post about what the DllEntry() function does in a device driver. Windows CE: Stream Interface Driver, XXX_Init() A discussion of what can and should be done by the driver XXX_Init() ......

The DriverShell source code can be downloaded from: Download DriverShell Source Code Windows CE runs on many battery powered devices and therefore needs to be able to minimize the power consumption to maximize battery life. To do this Windows CE has a power manager that can be used to notify device drivers when the system power state changes. Drivers can then respond to the notification by powering down the hardware that they manage. Basic Power Management The most basic power handling that a driver ......

When we first ported our BSP to Windows CE 6.0 we started to see this VMProcessPageFault Error: Page Fault message in our debug output during resume from sleep. The system seemed to be working okay, but this message seemed ominous so as we continued to work on the port we kept an eye on the problem and investigated the possible cause of the message. Others had reported this message and they discovered the cause was that they had a driver that was calling a system API in XXX_PowerUp. Microsoft has ......

Previously, I introduce a Stream Interface Driver that was just a shell of a driver or a driver that didn’t do anything useful. I thought that it would be good to flesh it out a little and add some code to demonstrate some driver features that are fairly common. To get started, let’s flesh out the first function that gets called when the driver loads; DllEntry(). DllEntry() is typically fairly basic, but does some important things. First, I will fill in the function, and then I will discuss what ......

Prior to Windows CE 5.0, you could only have up to 10 instances of a driver with the same prefix, like COM. So you could only CreateFile on COM0: through COM9:. Starting with Windows CE 5.0, there is support for BUS mount points ($bus\USBFN_1_0) and device mount points ($device\COM8) which can be used to open a handle to a driver. Platform Builder Help documents these in Device File Names, which isn’t so easy to find. I created a little test to show how to use the different names: void OpenADriver( ......

I recently posted a sample stream interface driver (Windows CE: A Stream Interface Driver Shell) and claimed that I included enough to cause the driver to be loaded by the device manager. The following code is how I know that it loaded. This code enumerates the running drivers using FindFirstDevice() and FindNextDevice() which are included in the device manager functions. There are several options for enumerating the drivers, this example uses DeviceSearchByLegacyName. I include this function in ......

Note: In Windows CE: Stream Interface Driver Power Management I have included a download of the source code for this driver. I thought that it might be useful to have a shell of a stream interface driver that I could use to start developing a driver from. I can’t believe that I never created this before, but here it is. I called this driver “DriverShell” because that is all that it is, a shell of a driver. This is a very basic starting point for creating a new driver. I have tested that this driver ......