Skip to main content

MIDP on WindowsCE 4.2 core

10 replies [Last post]
apmon
Offline
Joined: 2009-01-30

Hello,

I am trying to get PhoneMe to run on my WinCE 4.2 Core based satnav, so that I can port a midlet onto it that I am developing. I have found the page http://www.cs.kuleuven.be/~davy/phoneme/, but I am not entirely sure which version I should download. The section on WinCE 4.2 says PhoneME feature MIDP should work on WinCE 4.2, but there is only a link to PhoneME feature CLDC which if I understood correctly does not contain the MIDP libraries? So instead I tried to use the one for Windows Mobile 2003, but when I try and run it, the device complains that it is not a valid winCE binary. Similarly the pMEA dual stack for Windows mobile 2003 won't start. In contrast, both the pMEF CLDC and the pMEA pp for winCE 4.2 seem to run correctly and in the later case I can run the included test application without problems. I tried to copy the midp directory from the Windows mobile 2003 dual stack version to the pMEA pp winCE version and run my midlet, but although the JVM started it did not run with I think a ClassNotFound exception. Unfortunately, the window closes so fast, that I can not read which Class is missing and what else the JVM tells me. So I have two questions.

Which version of PhoneMe should I use for MIDP applications on WinCE?

Is there a way to log all errors into a file rather than the console, that immediately closes on exit?

I would very much appreciate any links or other help on how to get midlets to run on this device.

Thank you.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
davyp
Offline
Joined: 2007-01-03

Hi apmon,

I don't have any pure WinCE based hardware to test my builds with. I can only test the binaries on a WinCE 5.0 and 6.0 emulator (no 4.2 emulator I am afraid). I just checked again with a simple midlet on WinCE 5.0 and it appears to run fine. So the problem could be that although the sources are compiled for WinCE 4.20, it does not work because you don't have certain libraries on which my builds rely. In those cases I also get a "not a valid WinCE binary" error. As you probably know, most pure WinCE based devices use a customized OS and the manufacturer can decide which components are included in its WinCE image. In any case, I think the MIDP implementation for Windows Mobile 2003 is indeed your best choice because that WM2003 is based on WinCE 4.20.

It could also be that your midlet is using unsupported JSRs and therefore exits. This would also explain why the dual stack for Windows Mobile 2003 gives you a ClassNotFound exception. Could you verify with a simple "HelloWorld" kind of midlet?

apmon
Offline
Joined: 2009-01-30

Hi Davyp,

thanks for your answer. I downloaded PhoneME feature MIDP for Windows Mobile 2003 again and now it works. Not sure what I did wrong the first time, but the as long as it runs now, that is great. So thanks a lot for providing the WinCE builds of PhoneME!

Unfortunately I am now still seeing some problems when running my midlet, that seem to originate from floating point operations. Calling Math.tan and Math.cos on a variety of values seems to give me wrong results, including Infinity and NaNs where I wouldn't expect them. Is there a way to figure out what is going wrong here, or could this also be dlls missing?

Many thanks again

davyp
Offline
Joined: 2007-01-03

Can you give a small code snippet with some test input values so that I can compare the results?

Davy

apmon
Offline
Joined: 2009-01-30

I put the following test code into the midlet to test a couple of different tan and cos functions:

logger.info("Testing float: ");
logger.info("1 " + Math.tan(0.0));
logger.info("2 " + Math.tan(-0.01));
logger.info("3 " + Math.tan(0.01));
logger.info("4 " + Math.tan(0.0f));
logger.info("5 " + Math.tan(-0.01f));
logger.info("6 " + Math.tan(0.01f));
logger.info("4 " + Math.tan(10.0f));
logger.info("5 " + Math.tan(-10.01f));
logger.info("6 " + Math.tan(10.01f));
logger.info("7 " + Math.cos(0.0));
logger.info("8 " + Math.cos(0.01));
logger.info("9 " + Math.cos(-0.01));
logger.info("10 " + Math.cos(0.0f));
logger.info("11 " + Math.cos(0.01f));
logger.info("12 " + Math.cos(-0.01f));
logger.info("13 " + Math.cos(10.01f));
logger.info("14 " + Math.cos(-10.01f));

The output was as following:
1234258704215 I[Trace] Testing float:
1234258704240 I[Trace] 1 0.0
1234258704262 I[Trace] 2 1.4154236923197619E273
1234258704301 I[Trace] 3 -1.4154236923197619E273
1234258704333 I[Trace] 4 0.0
1234258704354 I[Trace] 5 1.4154232177620623E273
1234258704386 I[Trace] 6 -1.4154232177620623E273
1234258704468 I[Trace] 4 NaN
1234258704487 I[Trace] 5 NaN
1234258704506 I[Trace] 6 NaN
1234258704566 I[Trace] 7 5.299808824E-315
1234258704594 I[Trace] 8 1.1945227672265743E95
1234258704625 I[Trace] 9 1.1945227672265743E95
1234258704658 I[Trace] 10 5.299808824E-315
1234258704687 I[Trace] 11 1.19452266042792E95
1234258704718 I[Trace] 12 1.19452266042792E95
1234258704749 I[Trace] 13 -Infinity
1234258704772 I[Trace] 14 -Infinity

So apart from Math.tan(0.0) and Math.tan(0.0f) all other calls gave spurious results. These results seem to be stable across restarts of the midlet.

This test code ran embedded in a larger application (http://gpsmid.sourceforge.net/), but I hope that shouldn't matter.

Thanks

davyp
Offline
Joined: 2007-01-03

I get the same results with CLDC on the WinCE 5.0 and Windows Mobile emulator, so I can confirm this is an issue.

Davy

davyp
Offline
Joined: 2007-01-03

It turns out that the byte order of the double in Math.tan(double) and other methods is passed along in the wrong order to the native code jvm_tan(jdouble) in FloatNatives.cpp. It appears a big/little endian problem although it is not per byte but per 4 bytes that the order is wrong. I print out the jdouble argument of jvm_tan() and when calling Math.tan(-0.01) in Java, instead of -0.01, I get 19991597860339517000000000000000000000.000000:

Here are the hex values to show that the order is wrong per 4 bytes:
19991597860339517000000000000000000000.000000 => 47ae147bbf847ae1
-0.010000 => bf847ae147ae147b

But there appears to be another problem with the computation of the result as well. If for testing purposes I change the original implementation of jvm_tan(jdouble):

JVM_SOFTFP_LINKAGE jdouble jvm_tan(jdouble x) {
return jvm_fplib_tan(x);
}

to something like:

JVM_SOFTFP_LINKAGE jdouble jvm_tan(jdouble x) {
double tmp1, tmp2;
long *ptr_x, *ptr1, *ptr2;

ptr_x = (long *)(&x);
ptr1 = (long *)(&tmp1);
ptr2 = (long *)(&tmp2);
ptr1[0] = ptr_x[1];
ptr1[1] = ptr_x[0];

tmp2 = jvm_fplib_tan(tmp1);
ptr1[0] = ptr2[1];
ptr1[1] = ptr2[0];

return tmp1;
}

The tmp1 in "tmp2 = jvm_fplib_tan(tmp1)" prints out as -0.01, but I still do not get the correct result in Java. It should be Math.tan(-0.01) = -0.010000333346667207.

Instead I get for tmp1:
tmp1 = 1.0604E-314 (reswapping the result tmp2 of jvm_fplib_tan)
tmp2 = Inifinity (before reswapping)

Neither tmp1 nor tmp2 contains the correct value so I guess the jvm_fplib_tan function does not produce the correct result. If I change jvm_fplib_tan(tmp1) with its WinCE counterpart tan(tmp1) and keep swapping the order in tmp2, I get the correct value in Java.

Can somebody tell me what is going on and where I can fix this issue for WinCE without breaking other arm based platforms?

Davy

davyp
Offline
Joined: 2007-01-03

In my latest builds I have implemented a temporary workaround for the following methods, and
used the native WinCE implementation of the corresponding functions:

jdouble jvm_sin(jdouble x)
jdouble jvm_cos(jdouble x)
jdouble jvm_tan(jdouble x)
jdouble jvm_sqrt(jdouble x)
jdouble jvm_ceil(jdouble x)
jdouble jvm_floor(jdouble x)
jdouble jvm_asin(jdouble x)
jdouble jvm_acos(jdouble x)
jdouble jvm_atan(jdouble x)
jdouble jvm_atan2(jdouble x, jdouble y)

But probably this error may pop up elsewhere too where jdoubles are used. I still have not
figured out where I have to look to correct the order of the 2x4 bytes. Any hints from the
experts?

Davy

davyp
Offline
Joined: 2007-01-03

Nevermind, I found where to fix the jdouble issue without the hacks of above

Davy

apmon
Offline
Joined: 2009-01-30

Great! thank you very much. I have tried it out and all seems to work well now and my application is running smoothly. I am not sure which of your two versions I have tried though, as I downloaded the new version sometime yesterday evening (GMT). But with your PhoneME builds for WinCE, I can now run my mapping app on a whole new device class! So I only need to optimize the UI of my app to work a bit better with touchscreen input and figure out how to get access to the GPS receiver through the serial port and then I am very happy.

Many thanks again!

P.S. My test device has 64Mb of ram, but currently PhoneME only uses about 3Mb. Trying to pass in the e.g. -Xms16Mb in the .lnk file did not work and it complained, depending on the ordering of the parameter, that it could not execute the class Xmx16Mb or simply ignored it. Is there a way to tell it to use more memory, or should I rather try and get the PhoneME Advanced dual stack working?

davyp
Offline
Joined: 2007-01-03

The binaries you downloaded probably contained the old hacks where I swapped the two 4-byte
words of each double and that for each function. While I found how to solve the issue, I still
had to recompile the CLDC and MIDP sources for the various platforms.

So the new binaries with the generic fix were only available on my website from this morning
on around 11:30 CET (or 10:30 GMT).

The nice thing with this fix is that it immediately solves some issues I had with JSR 226 (SVG
support) on WinCE where certain SVG animations did not work correctly.

Davy