[sorry if this gets *too* technical!  I tend to do that sometimes...]

On x86 processors using x87 floating-point math, there are a set of
integer registers with names like %eax, %ebx and so on, and a set of
floating-point registers organized as a stack, with %st or %st(0)
indicating the top of the stack, and %st(1) indicating the next element
of the stack.

In the Linux calling standard, a function that returns an 'int' returns
it in the %eax register, and a function that returns a floating-point
value (whether 'double' or 'float') returns it in the top-of-stack
register, %st.

Now consider the case when the compiler doesn't have the correct return
type.  For better or for worse, the C language specification says that
if you encounter a use of a function 'g' without a declaration, the
return type is assumed to be 'int'.  If the actual return type is
'double', then things will go badly awry.  An extra entry (the return
value of g) will be left on the 8-element floating point stack, because
g will put it there and the caller will not pop it.

After a very few invocations of the function, the stack will overflow.
This overflow is not noticed by emc (the x87 provides a way to notice
the stack overflow, but we do not enable it), and quite quickly fills
all the %st(#) registers with unused floating-point return values.  Then
an innocuous function which would push two values on the stack perform
an operation and then store the result will have the wrong input
operands--it will instead get left-over input operands from the bad
call.  (at least I think this is how the x87 behaves in case of
overflow; whatever the behavior *is*, it's sure not the desired behavior
anyway)

So why are sin() and cos() and atan2() OK, while tan() and atan() are
not?  RTAI provides the full set of trig functions in rtai_math.ko, but
their header files omit the declarations for them!  I put the absoltely
necessary declarations in our own header file "rtapi_math.h", but left
out some that are not necessary for any part of emc--apparently tan() is
in the latter category.

Why did it work with the simulator but not with realtime?  Because the
simulator uses the regular system <math.h> when you include
"rtapi_math.h", and <math.h> has the full set of declarations.
I am a bit surprised that you didn't get warnings like
    bug.c:1: warning: implicit declaration of function ‘tan’
but even if you did, you may have confused them with the (innocuous, or
else outright fatal at 'loadrt' time)
    WARNING: "rtf_get" [/usr/src/rtemc2.4/src/rtapi.ko] undefined!

I suspect that the behavior of your kinematics will quickly improve
if there are declarations of the offending functions, as added by the
following patch:
        
http://emergent.unpy.net/files/sandbox/0001-provide-a-prototype-for-tan-atan-in-kernel.patch
(the meat is:
+++ b/src/rtapi/rtapi_math.h
+extern double tan(double);
+extern double atan(double);
)
 
If you can confirm that this fixes the weirdness you've been chasing
recently, I'll make sure that these declarations are added to
v2.4_branch and master very soon.

Jeff

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Emc-developers mailing list
Emc-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-developers

Reply via email to