pretty

Friday, 7 September 2012

Dependency problems in Windows CE

Wonderfull operating system it is Windows CE! Except for the fact that it is built in a Platform Builder by countless number of eastern manufacturers. They all tend to have their own opinion what to have onboard, which DLL's to include and even - which functions from DLL to exclude. And then the majority of applications wouldn't start on these devices. I feel that they are even encouraged to rip off as many DLLs and functions from a devices as possible as they will have lower licencing fees.

As Windows Mobile market share started to diminish I thought Windows CE will follow. By the way, Windows CE is mostly found in GPS car navigators, while Windows Mobile - that's the name for Windows CE with strict subset of futures - was mostly installed on smartphones. But Windows CE is still widely used in navigators. It was a surprise to me when in 2011 Gartner recommended manufacturers to "Remain with Windows Mobile for ruggedized handheld-computer solutions ... ". I can clearly understand the benefits for manufacturers to stay with old OS as they won't need to rewrite drivers etc, but how about consumers? For the same price as Android navigation device you get the device with Windows CE that is generally twice slower and, what is more, you are locked in. You'll be able to use the software that is preinstalled, but most other winmobile apps would not run on it.

But enough of this palaver. I intended this post to be of some help to developers and users who can't run their programs on specific Windows CE device. First off I recommend you to read this wonderfull post by Lao K. It addresses three most common reasons why the specific program fails to run on a device.

The first two reasons, or heartaches, namely "Check the Platform" and "Check the SubSystem" are straightforward. I would only like to add that you can alternatively use the program ExecutabilityCheck to solve "Check the SubSystem" issue. This application can rewrite OS version in exe file.

The third issue, "DLL HELL", I'm going to discuss now. When application doesn't start due to missing DLL or missing function from a DLL we need to track down what exactly is missing on this OS build. I'm going to propose three ways of doing this.

1. Use ExecutabilityCheck. It can also check missing exports. The problem is, I found that on a lot of newer CE devices it doesn't work.

2. Use an app called TestWM5. It dumps all DLLs from the device ROM to SD card. Then you want to transfer them to desktop machine and put them in directory with your program. Launch Depends.exe now, open your program in it and see what is missing. Is is important to check your program against these downloaded-from-device DLLs, not the ones that reside on desktop Windows with the same names! By the way, downloaded from ROM DLLs are not usable, but they are fit for imports check.

3. Use an app that I've wrtitten - CEExports download link . Put CEExports.exe and file input.txt in the same directory on device. Input.txt is the file you should edit. Put all imports from your exe there. You can use dumpbin utility that goes with Visual Studio for this purpose or you can alternatively use Depends.exe.

This is the format used in input.txt:

[DLLNAME.DLL]
Functionname1
Functionname2

[DLLNAME.DLL]
Functionname1
Functionname2


Also you can put function ordinary instead of a name. See input.txt provided with program for example.

Run CEExports.exe and it will produce the file log.txt. In log.txt functions and/or DLLs missing will be listed.

If DLL couldn't be opened last error code will be mentioned. It means that you can check your own DLLs for compatabilty. If the DLL can't be opened for compatability reasons last error might be 193 (ERROR_BAD_EXE_FORMAT), if DLL can't be found you should see something like 126 (ERROR_MOD_NOT_FOUND). When you run CEExports with provided input.txt you would see log contents like:

10000 function ordinal is not exported from COREDLL.dll
SUPERDUPERDLL.DLL library not found
Last error code: 126
Total number of functions checked: 5
Total number of functions missing: 1


I intentionally checked for function ordinal 10000 in coredll which isn't exported. Further I'm checking for the presence of superduper.dll which can't be found. All other DLLs where succesfully opened, and 4 functions I check for are in place.

Hope you'll find these techniques for locating missing Windows CE exports usefull.

Thursday, 16 August 2012

Android: No USB driver? No problem.

Got another android tablet, and can't find usb driver for it, in order to use ADB? I'm going to show a step-by-step guide what to do in this case, suggested by my colleague. This approach worked on every device I have tested so far.

1. Connect the device to a computer with usb cable.

2. On Android device turn on Settings->Aplication->Development->USB Debugging option.

3. Open device manager on Windows, and there you should see Android Phone node with "Android Composite ADB Interface" leaf. Click on properties, go to details tab and select "Hardware Ids” from dropdown box. In "Value" window you'll see something like this (that's for my Altina tablet):

USB\VID_18D1&PID_0003&REV_9999&MI_01
USB\VID_18D1&PID_0003&MI_01.

Copy these values to notepad.

4. Now open ..\Android\android-sdk\extras\google\usb_driver\android_winusb.inf with notepad. This is standard android usb driver from SDK. It covers some of the phones as you can see, like HTC Dream and Google Nexus One. We are going to try to add a new device to it. Go to the [Google.NTx86] section in case you are on 32-bit Windows or to [Google.NTamd64] if you have a 64-bit os.

5. Copy the strings from HTC Dream and paste them before "; HTC Dream"

%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01

Then change USB\VID_0BB4&PID_0C01 and USB\VID_0BB4&PID_0C02&MI_01 with your device's strings saved in notepad. For instance, in my case it would look like:

%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0003&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0003&REV_9999&MI_01

Save and close android_winusb.inf.

6. Done. To check go to android-sdk\platform-tools\ and type adb devices. If everything worked out well you should see your device in the list of atached devices.

Tuesday, 24 July 2012

RVCT vs GCC - performance comparison on mergesort


I heard about RVCT compiler produced by ARM a lot of times. Some people are saying that it produces 30% faster code than GCC ARM compiler. Our real-time mobile application is compiled with GCC, so I decided to give RVCT a try.

I have downloaded 30-day evaluation RVDS Toolchain 4.1 which includes RVCT compiler. GCC that I use is of a little aged version 4.4.1 (July 22, 2009).

As the project we are working on is quite big and there is a lot of templates usage and so on, I would need to spend some time to make it compilable with RVCT ( "And then you discover that there are no two compilers that implement templates the same way" ). Just for now I have decided to make a small test apps to compare these compilers at first glance.

I am going to test the speed of the code that would implement two versions of a mergesort algorithm. First is iterative mergesort from here (replacing the line 34 with: l_max = (r - 1 < size) ? r - 1: size - 1;) iterative, and the second one is recursive from there . Both of the two versions I'm going to test on the same input file with 100000 unsorted integers. I generated the content for this file by heavy usage of rand() function.

The actual code looks like this, so I measure only time it takes merge to complete the sort.
DWORD t1 = GetTickCount();
mergeSort(arrayOne, arrayTwo, 100000);
DWORD t2 = GetTickCount() - t1;

On my desktop machine (Core i5-2400) the code compiled with Microsoft CL compiler with /O2 optimization took about 9-12 ms, and with optimization turned off 17-20 ms. But that's for comparison, lets move to GCC ARM and RVCT. I set GCC to -O3 optimization level, as well as RVCT. Here are the estimates for 5 consequential runs acquired on LG Optimus One P500 mobile phone with 600 MHz ARM 11 processor.

Iterative mergesort, milliseconds
RVCT - 133 135 133 135 140
GCC - 149 149 143 146 145

Recursive mergesort, milliseconds
RVCT - 92 89 88 88 91
GCC - 93 98 92 101 92

Results speak for themselves. It is prominent that in the above case implementation details of the same algorithm far outweigh the choice of a compiler. Anyway, I still have 20-something days left of evaluation for RVCT, and I am going to try it on a larger project. Upgrading GCC is an option also.