math-lib doesn't work

gluehbirne wrote on Friday, September 24, 2010:

I tried to use the math-lib to calculate for example a square root, but it doesn’t work.

The result of this example which is calculated periodically inside a test task is y = 2.565…. while x is about 25.0

x = 25.0 + 0.001 * x;
y = sqrt(x);

These are my linker-flags:

LINKER_FLAGS	  = -lm -lc -lgcc -mthumb -nostartfiles -Xlinker -o$(TARGET).elf -Xlinker -M -Xlinker -cref -lc -t -Map=$(MAP).map

I use an AT91SAM7S256 with yagarto

binutils: 2.20
gcc:      4.4.2
newlib:   1.18.0
gdb:      7.0.1
FreeRTOS V6.0.4

Does anybody have any idea how to solve this problem?

richard_damon wrote on Friday, September 24, 2010:

My first comment is that based on the code, you DON’T know that x is close to 25, it all depends on the value it had before executing those statements. If x is an auto variable, and hasn’t had a value previously assigned to it, it could have ANY value (or even no value) and the code has invoked undefined behavior, and can do anything. Given your answer, x probably starts with a value of about -28420.

gluehbirne wrote on Friday, September 24, 2010:

@richard_damon: I didn’t mention that the variables x and y are declared like

double x = 0.0;
double y = 0.0;

I use the gdb debugger in order to watch this expression, so I can see that x is about 25.0 and I can also see the result of y. I am sure that the debugger displays the correct values.

rtel wrote on Friday, September 24, 2010:

I presume, you are expecting y to be somewhere near 5.  Does the code work if you put it in main()?  If not then its not a FreeRTOS issue, but more likely a configuration issue.

The only problems with floating point in the past have been related to stack alignment, which was historically set to 4, but if you are using V6.0.4 then I think you should have 8 byte alignment as standard.  You might want to check though.


gluehbirne wrote on Saturday, September 25, 2010:

@richardbarry: I checked the following:

inside the main-function I added

double y = 0.0;
double x = 0.0;
while(1) {
        x = 25.0 + 0.001 * x;
        y = sqrt(x);
        x = 0.001 * x;

x is always about 25 and y is nan(0x8000000000000)

There is no task running, only this never ending loop exists.