mfrias Posted April 23, 2010 Report Posted April 23, 2010 Hello, I am programming an interface of FSUIPC to the Tcl language. I have it working and basically I simply map the Open/Read/Write/Close functions to make them available on Tcl. My question is actually Tcl-independent. I'm having trouble reading some values at some times. For instance, the heading value (0x580) reads the correct value most of the times but some times I cannot seem to get a correct value. For example, if the memory holds the decimal value 916312602 (which corresponds to heading 76) I cannot seem to read it correctly. My "read" function receives as parameters the offset and the number of bytes to read. Here is my code: DWORD dwResult, offset, bytecount; void *data; // offset is sent as a parameter, in this case 0x580 // bytecount is sent as a parameter, in this case 4 for heading if (!FSUIPC_Read(offset, bytecount, data, &dwResult) || // If we wanted other reads/writes at the same time, we could put them here !FSUIPC_Process(&dwResult)) { sprintf_s(err, "FSUIPC: Failed to read from link: %s", pszErrors[dwResult]); // RETURN ERROR } // RETURN valid data Now the above code has been tested with many other variables. IAS also has this problem from time to time. But vertical speed for instance is always correct. Notice that I have confirmed that the problem is not when the value is returned to Tcl. Right after the FSUIPC_Read call, the value stored in data is incorrect. I tried programming it a different way and it seems to work correctly, although I didn't want to use this method: long val; if (!FSUIPC_Read(offset, 4, &val, &dwResult) || .... i.e., if I send a pointer to a long value, then it is obtained correctly. Another thing I tried was using "char * / char []" instead of "void *" for data. Problem remains. Tried also using "memset" to set all bits to 0. No good here either. Can someone point me out to what the problem is? Thanks, Miguel
Pete Dowson Posted April 23, 2010 Report Posted April 23, 2010 i.e., if I send a pointer to a long value, then it is obtained correctly. What are you normally sending a pointer to, then? Obviously that's where your problem lies -- in your consequent interpretation of the data due to using the wrong data type. Doesn't this "Tcl" have a debugger you can use? when the fault is in your own code that's usually the best way to locate it. Another thing I tried was using "char * / char []" instead of "void *" for data. Problem remains. You should always use the correct type for the value concerned. The heading is actually an unsigned 32-bit integer, so "unsigned int" (in C) would be correct. If you are interpreting it in any other way you are going to see wrong values. It is nothing to do with how the interface works. As far as FSUIPC is concerned all the data in all the offsets is just in single bytes, and you are reading an array of bytes of the length you request. But your code MUST interpret them in the correct way for their contents. The data isn't different (there's no way it can be!), it's how you are treating it. Regards Pete
mfrias Posted April 23, 2010 Author Report Posted April 23, 2010 Hello Pete, Thanks for your reply. I've tested the code with consecutive calls. Let me try to explain it for the "heading": function FSUIPCREAD(..., int offset, int numberofbytes, ....) { void *data; data=malloc(numberofbytes); // allocate 4 bytes in this case memset(data, 0, numberofbytes); // to make sure everything is clean FSUIPC_Read(offset, numberofbytes, data, &dwResult); // offset = 0x580 Tcl_SetResult(..., (char *) data,...); // this interfaces with Tcl and returns the value } Therefore, the "heading" is read and stored into "data" which has been initialized for 4 bytes. Tcl_SetResult is a function that returns the data to Tcl. However, whenever the problem occurs, I already have "data" with an incorrect value prior to returning it to Tcl. If I do the following cycle in Tcl (pseudo code below): while { forever } { val = Call_FSUIPCREAD_from_C 0x0580 4 ; // read 4 bytes from offset 0x580 (heading) val = $val * 360 / (65536*65536) ; // calculate heading write($val) ; // output to screen } It ends up doing something like this: 34 34 34 34 0 34 34 34 34 0 34 34 ....... Most of the times it reads the value well. When it doesn't, it reads as "0", or "1" or a low value. I found out why: when the result is incorrect, it is because the value returned is 1 byte misaligned. If I split the "heading" value that has been read, into hex components: 0x4BDEF017 => 0x4B 0xDE 0xF0 0x17 => 75 222 240 23 But, when the problem occurs, I see something like: 1582 240 23 0 (notice that 240 is now byte #2 and 23 is now byte #3) and a 0 appears. My doubt here is: why does this happen some times, in a non-deterministic way? I thought that using a "void *" in C would enable me to map the FSUipc_Read function to Tcl in a generic form, rather than having to create a function for each value I want to retrieve, depending on byte sizes, etc. Miguel
Pete Dowson Posted April 23, 2010 Report Posted April 23, 2010 Therefore, the "heading" is read and stored into "data" which has been initialized for 4 bytes. Tcl_SetResult is a function that returns the data to Tcl. However, whenever the problem occurs, I already have "data" with an incorrect value prior to returning it to Tcl. You have an error then. There is absolutely no other explanation. You need to use a debugger and work out what you are doing wrong. Sorry, I really cannot help you debug your code, especially stuff which makes no sense to me whatsoever. I can't even see where you are calling FSUIPC_Process to call FSUIPC. If your FSUIPC_Read is the one I supply in the library, then all that does is put your request into a queue in the shared memory-mapped file area. Regards Pete
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now