Monday, June 13, 2011

Using CeLog to capture logging output from drivers (and apps)

Last year I was working on a Windows CE 6.0 platform that was to be used for a device which we would operate remotely via an Ethernet connection. The platform was not originally developed for this purpose and none of the device drivers were writing debug and error messages to a log file, they would simply output text to the serial port. For the original purpose of the platform this was fine, but now it was becomming a problem that I could not see if the drivers had reported an error.

There are several ways of solving this issue, including attaching an external device that would allow me to log the serial port output, or rewriting the drivers to use a logging library. None of these solutions were very appealing, so I started thinking about alternatives...

I realized that I could use CeLog in a way it was probably never intended to, by simply ignoring most of the functionality and only ask it to capture RETAILMSG (and DEBUGMSG) output. For those who have never encountered CeLog, it is a general purpose event-tracking tool that can can log a number of kernel and coredll events. CeLog is normally not enabled in a run-time image, but is simple to add.

So, CeLog more or less solved my problem. It logs events to a memory buffer and a small included application (CeLogFlush.exe) can be configured to regularly dump this buffer to a file on disk. The format of the file generated by CeLogFlush.exe is rather cryptic (binary) and designed for offline processing on your development PC using a tool called Readlog.

While ReadLog is very flexible and can do all sorts of filtering of the data, I wanted a more simple way to see the log messages, and I wanted to be able to see it directly on the device - from a telnet session or via the webserver. So I created a small utility (dumplog.exe) that will dump the log messages from the file (and ignore any other event data, should more events be enabled). I also created a small webserver plugin that will do the same thing, but make the output available as a webpage. The output from both look similar to this:

Windows CE DumpLog 0.1 (Compile time: May 27 2011 11:00:01)
Copyright (C) 2009 by Bogong (www.bogong.dk)

Dumping celog file: celog.clg
00:00:02.461.338: PID=00400002 TID=00D60002: I2C ioexp: ETH reset toggle bus 8, uAddr 0x74, reg 2, ByteCnt 2, uValue0 0x00, uValue1 0x01
00:00:02.563.764: PID=00400002 TID=00D60002: UfnPdd_ContextSetup: Allocated DMA TX Region PA 0x83400000 VA 0xD0B10000 Size 0x400
00:00:02.571.313: PID=00400002 TID=00D60002: UfnPdd_ContextSetup: Allocated DMA RX Region PA 0x83400400 VA 0xD0B20400 Size 0x400
 

I have wrapped everything in a package that you can dump into your C:\WINCE600\3rdparty folder and then include in your image by checking one or both of the catalog items.

The tool is hosted on Codeplex, but you need to download from the Source Code tab since I have not yet created a zip-file. A few more details about the tool can be found under Documentation.

Thursday, May 26, 2011

Windows CE LoadDriver

A while ago I developed a small tool to help develop drivers for Windows CE. The tool is a command line application that can dynamically load and unload drivers, and lets the user specify a number of options using command line switches.

To give you an idea about what the tool can do, here is the help output:

Windows CE LoadDriver 0.2 (Compile time: Oct 30 2009 06:53:06)
Copyright (C) 2009 by Bogong (www.bogong.dk)

Options:

 -l <regkey>           Load driver with registry key <regkey>
 -ld <dll>             Load specified DLL (also requires -p)
 -u <id>               Unload driver with handle ID <id>
 -i                    List drivers and their handle IDs
 -f <flags>            Set flags value (overrides registry if exists)
 -p <prefix>           Set prefix value (overrides registry if exists)
 -o <order>            Set order value (overrides registry if exists)
 -n <index>            Set index value (overrides registry if exists)
 -c <name>=<value>     Create custom registry key (overrides registry if exists)
                       Use dword:<num> as value to create a dword. Default is string
 -h                    This help

Examples:

 To load a driver with settings already specified in registry
 HKLM\Drivers\BuiltIn\Serial1, use:

    loaddriver -l Serial1

 To load a custom driver with no settings in registry you must
 specify everything on the command line, e.g.:

    loaddriver -ld serial.dll -p COM -n 4 -c TxBufferSize=dword:1024

The tool is hosted at bogong.codeplex.com where both a binary version (for ARM) and the source is available for download. You can also find a little more details about the tool at codeplex.

Let me know if you find the tool useful!