I bought an Uberboard some weeks ago. I have done a lot of tests and modifications on the original firmware and all worked perfectly.
I have only a problem. I’m not able to use floating variables for calculations.
So I restarted developing from the original firmware but still I can’t use floating point variable.
I’m not a newbie on general C programming (I normally use PIC for my devices), but it’s the first time I use LPC. So I think my question has a very simple answer… but I searched in this forum and over Internet but I found only people with my same problem, but not a solution for a newbie.
The problem is very simple:
if I define a float var, for example
float f;
f=2.9;
in f the LPC stores only “2” (integer truncation)
so, if I write for example
float f;
int t;
f=2.9;
t=(int)(f*10);
rprintf("\r\nt = %d",t);
results on “t = 20” on UART
There’s no warning or error message when I build the project, so I don’t know what’s wrong.
I think the solution is simply use a compiler option which enables floating calculations, but how? and where?
I use WinArm for developing this project and SparkFun USB bootloader.
That’s really puzzling Marco. AFAIK all you should need is libgcc. I struggled through your makefile and it includes that.
I have no experience with newlib. I guess in theory some library other than libgcc could be hijacking your gcc float functions (but what other library has routines with names like __mulsf3 and __fixsfsi ?). If your app doesn’t need them, you might try leaving out newlib and/or libm and see what happens.
Just grasping at straws here, hoping you can circle around your config problem and gather enough data to pinpoint it. I’m sure that if any library had massive side effects like truncating floats it would have been fixed long ago.
int t;
f=2.9;
t=(int)(f*10);
rprintf(“\r\nt = %d”,t);
results on "t = 20" on UART
There's no warning or error message when I build the project, so I don't know what's wrong.
Check the format options for rprintf. I haven’t programmed in C since the 1990’s but AFAIR if you want to write out floats the format was something like “%f4.2”. “%d” was for decimal (integer) formats.
He’s printing t, which is an int. So it would seem the problem is either in multiplying his float by 10, or in the float to int conversion.
I bought a jtag interface a few months ago. It was (or seemed like) a colossal effort to get it working. But now I can’t imagine how I ever debugged anything without it. Being able to step through the code and examine the variables would sure help out in a situation like this.
[edit] Other thoughts on tracking down the problem:
re-build your program with t and f as global variables. Then look at your map file and see how many bytes are allocated for each. (possibly add a few extra dummy variables to reduce the odds that f will be the last one in the .bss section.)
Use arm-elf-objdump -d to disassemble your output file (main.elf?). Then look at what functions are called at that point in the code. For example
arm-elf-objdump -d main.elf > main.txt
When I build with the Linux precompiled toolchain from gnuarm.com, the functions called are __aeabi_fmul and aeabi_f2iz.
(It can take some scrolling and head-scratching to locate the section of the disassembly file you want.)
theatrus:
This is not a toolchain issue. It is an understanding of C issue.
Your expression f10 is being done in integer math (2.9 truncated). You want to be explicit: f10.0f
That should not matter. In C if an int is multiplied by a float the int should be automatically promoted to a float. i.e. (f * 10) is equivalent to (f * 10.0). The result should be approximately 29.0. The int cast would then truncate that to 29 (or, at worst 28 if the intermediate value of f == 28.999999999).
I suspect the problem is in the rprintf function and recommend trying a simpler output function to display the value.
I tried his code exactly as given (among a few other variations), except that I don’t have printf or even rprintf available at the moment. But the value of t given by the debugger was 29. (I could have sent the hex bytes over the serial port but that seemed a waste of time.)
My initial reaction was also to suspect rprintf. And it might be the culprit. But…wow. If t has the value of 29 and rprintf prints 20, it is really REALLY messed up.
In surfing around I found some references to versions of newlib apparently built without any software floating support (the assumption being that all float processing would be done in hardware I presume). But I lack the knowledge and/or tenacity to pursue that any farther. (Seems a bit of a long shot. How / why would Marco have such a version?)