I thought about putting this in the "other API" forum, but I think this has enough wacky stuff going on to qualify for "advanced".
Further, I think that this problem is sooooo challenging .... the answer has been soooooooo elusive .... that I'm putting up an embroidered JavaRanch hat - mailed to anywhere in the world, for the first person that can solve this.
In this pic: You see sheriffs Jim, Marilyn, Jeanne and Ilja. Jeanne is wearing a hat just like the one I'm offering.
Here's the big challenge/problem...
(I'm numbering the bits and bobs to put this whole thing together so that I can compound the points)
147) I have a "windows mobile" handheld contraption. The about screen says "Microsoft Pocket PC version 4.20.0"... later it says "processor: ARM XScale". Another info page says "processor: Intel PXA255(A0)". When I run my app, a libary I'm using (more on that later) sends some info to the console: 'os.name="Windows CE" os.arch="arm"'
201) My tiny app uses serial stuff. I use the serialio library from serialio.com. I have the app running just peachy on windows XP pro. I have purchased the serialio "pro" version that supports all kinds of chips including the ARM stuff.
222) At one point, I would run my tiny app and on the console I got an exception. The root problem behind the exception was that it could not find/load jspWceArm.dll (don't let "jsp" confuse you - this is not "java server pages" but "java serial port"). With other JVM's, the solution would be to put the DLL in the \Windows directory. That didn't work. I tried putting the DLL in all sorts of directories and finally when I put it in "\Program Files\Mysaifu JVM\jre\bin" then I got the message that a problem occurred and an error file was written. I present the contents of that file to you as exibit 222a:
257) The jvm I'm using is mysaifu jvm. It's free! I made a copy of my app that would run on the little contraption that emulated the serial stuff. Everything worked just fine. There are other JVM's available, but my impression is that there is a per-installation charge for them.
301) Most of my work for my current gig has been server stuff. I've done mountains of server stuff for many years, and I REALLY like the idea of this little side project at work, getting a wee app to run on this handheld contraption. I think that if I don't come up with a solution quickly (with a free jvm), then the project will be dropped.
501) I talked to a helpful support guy for the serialio libraries. Dave. Dave says that they have fired up the serialio stuff up with a few different JVM's for this contraption. But never the JVM I'm trying. He says it should work fine. The JVM just isn't loading the DLL right.
I feel like this is one of those things that will be fixed in about 60 seconds once I have the secret code to make everything work.
When executing your code are you able to put switches in for it? For example, if I were running a java app from the command line and it required a DLL of sorts I *might* to something like this:
java -Djava.library.path=/path/to/DLL SomeApp
Note that the /path/to/DLL doesn't include the DLL itself, only the path to where it exists.
I looked in his diary to check if there was anything related to your problem. The only thing I found what that he already encountered a "data misalignment" problem when using the ARM version. It was in 2005, so it has been fixed already. (no solution yet, sorry)
Do you really *need* serialio library? I had some folks do a handheld app for us. An iPAQ that talked to a Garmin bluetooth GPS unit from Java on WinCE using... new FileInputStream("COM1") !
Originally posted by Ernest Friedman-Hill: Do you really *need* serialio library? I had some folks do a handheld app for us. An iPAQ that talked to a Garmin bluetooth GPS unit from Java on WinCE using... new FileInputStream("COM1") !
Ooooooo .... I like this idea ... gonna try it later ....
Of course when writing the app, the message was "you will only read, never write". And as soon as I have it working "it has to write too!"
So when I try to open a stream to "COM1:" to write when I already have a read open, I get an exception with the message "access is denied".
I thought about doing something where I could try to quickly close the writer and then open the reader, but I cannot help but think I am going to lose stuff doing that.
If you have access to NIO, then yes. Try something like this:
Using RAF may seem an odd choice, but it's the only way I know to get a FileChannel that can both read and write. [ March 05, 2008: Message edited by: Mike Simmons ]
It seems to work for a bit. On my second write to the serial port, the write() method blocks. Everything stops. Any suggestions.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Not really. I haven't done it myself, I just posted because it seemed like it might give you a working bidirectional connection. I guess you could try using RandomAccessFile rather than FileChannel. I wouldn't use any of the methods that specify an offset. But you'll probably just get the same result.
It might be good to test what happens when you close one stream and open another one. Maybe there's some sort of buffering that will save input that arrives while you're not connected? You can insert a Thread.sleep() to make sure there's a noticeable gap between closing one stream and opening another, and then see if it picks up new input that arrived during the gap.
It seems like there ought to be some way to treat COM1 like a socket, and open a ServerSocket. But maybe I'm dreaming.
Closing one stream and opening another stream had problems too. Something about how the resource is already in use. I thought about putting a 50 millisecond sleep between them, but then I would lose the data that I need to grab. So that doesn't really work.
Too soon to tell, but ... I made something that will not be a general solution, but will work for this app. Every time I send data, I know what I will receive. So when I read (and the only reads available to me are blocking reads) I read one char at a time. Once I have received everything I expect, I do not read again - because if I read one more char, it would be a blocked read until after I send something. So every time I write, I am not currently in a blocked read state.
My preliminary tests have this working.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Was it even the write() that was blocking earlier, or was it the read()? A more general solution might be to use separate threads for reading and writing. Unless that's what you were doing, and the blocking read() in one thread interfered with the write() in the other. Is that what was happening?
(sigh) I got it working great on my desktop. But it doesn't work on the handheld device. No exceptions or anything - just no data ever comes back. Data did come back before when I was just reading.
Mike, yeah, I had two threads before - one for reading and one for writing.
The JVM comes with a serial package. It doesn't work according the standard it is trying to support, but if you root through the source code you can find a way to get it to work.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Congratulations!
Nicholas Jordan
Ranch Hand
Joined: Sep 17, 2006
Posts: 1282
posted
0
Okay, it looks like the caps are popular, the Data misalignment may or may not have been fixed, and has zero latch on streams, buffering, synchro or anything so high-level. Win *expects* the processor will do data alignment, that assumption is built into the compiler, as well as their entire camp. Handhelds are generally programmed by compilers that assume the compiler will do the data alignment.
You may have fixed the problem, but I would document your steps while they are fresh in your mind.
Kevin Erickson
Greenhorn
Joined: May 27, 2008
Posts: 1
posted
0
Paul: Any chance you've been able to document what you've done to talk via serial? I'm about to embark on a similar task and wouldn't mind a little insight.
Well, I don't work at that company anymore, so I don't have the source.
I seem to remember something about how the little serial library that you can find on their page was very basic. I think it included source - and there isn't much. But if you fish through the source, you can kinda get an idea of how somebody must have done just enough to get their own serial stuff working - and then they ran with that.
You can use system.load(path of the dll) instead of system.loadlibrary()
System.loadlibrary() searches at code base. [ May 30, 2008: Message edited by: Pratap Chowdary ]
Pratap koritala
Ranch Hand
Joined: Sep 27, 2006
Posts: 251
posted
0
when you are creating the binary stream, do you ensure that data types are aligned for target CPU.
For example,
VOID SomeFunc(PVOID pvDataBuffer) {
// The first byte in the buffer is some byte of information char c = * (PBYTE) pvDataBuffer;
// Increment past the first byte in the buffer pvDataBuffer = (PVOID)((PBYTE) pvDataBuffer + 1);
// Bytes 2-5 contain a double-word value DWORD dw = * (DWORD *) pvDataBuffer; // raises exception
} the above code can generate data misalignment exception on some CPUs
For Windows Machine, calling SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT) will result in silently correcting misaligned data accesses.
I think on your windows machine with Intel Processor, the data misalignment is corrected by default i.e processor aligning the data. But,On your hand held with ARM processor , It is generating the exception. [ May 30, 2008: Message edited by: Pratap Chowdary ]
Pratap koritala
Ranch Hand
Joined: Sep 27, 2006
Posts: 251
posted
0
Data is aligned when the memory address of the data modulo of the data's size is 0. For example, a WORD value should always start on an address that is evenly divided by 2, a DWORD value should always start on an address that is evenly divided by 4, and so on.
When the CPU attempts to read a data value that is not properly aligned, the CPU will do one of two things. It will either raise an exception or the CPU will perform multiple, aligned memory accesses to read the full misaligned data value.
Processors are designed in such a way,its not bug.
So,when you are creating or reading the binary stream, the above exception may occur.