Error casting float to uint16_t

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm getting an error that's not flagged in my source code but apparently occurs in a library file.

uint16_t CALC_altitude(float baro)
    {
	  float dummy;
      uint16_t ialtitude;
	  dummy = pow(baro/29.9247, 0.19);
	  dummy = 1.0 - dummy;
	  dummy /= 0.000022558;
	  ialtitude = (uint16_t) dummy; // This statement causes error
  //  ialtitude = (uint16_t) ((ft_per_meter*(1-pow(baro/29.9247, 0.19))/22.558E-6));
      return(ialtitude);
    }  

I get this error:

c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr25\libc.a(floatsisf.o): In function `__floatunsisf':
(.text.avr-libc.fplib+0x0): multiple definition of `__floatunsisf'
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr25\libgcc.a(_usi_to_sf.o):c:\avrdev\gcc\build-avr\avr\avr25\libgcc/../../.././gcc/fp-bit.c:1391: first defined here
make: *** [Barometer.elf] Error 1
Build failed with 1 errors and 0 warnings...

My original calculation line is the one commented out. I tried to isolate the error by breaking it down into several steps using the "dummy" variable. This resulted in finding that the line causing the error is the one flagged as such with the comment.

Is casting the floating point value as a uint16_t the correct way to do this?

Thanks,

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't speak for the error, but the explicate cast is not required, as it happens implicitly due to the destination type. You can try leaving the explicate cast off to see if the error goes away. [though it should not make any difference]

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks like both the object files floatsisf.o
and _usi_to_sf.o contain a definition for __floatunsisf

What are your command line options? Are you included library's (or the same library) from multiple locations?

Last Edited: Sun. Oct 28, 2012 - 07:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Likely he does, this is the avr-libc hack that override libgcc functions. See my notes on the avr-gcc mailing lists from 2012-08-26.

Anyway, I cannot reproduce the linker problem. After completing the text above to

#include 
#include 

#define ft_per_meter 3.28083989

uint16_t CALC_altitude (float baro)
{
    float dummy;
    uint16_t ialtitude;
    dummy = pow (baro/29.9247, 0.19);
    dummy = 1.0 - dummy;
    dummy /= 0.000022558;
#if 1
    ialtitude = (uint16_t) dummy; // This statement causes error 
#else
    ialtitude = (uint16_t) ((ft_per_meter*(1-pow(baro/29.9247, 0.19))/22.558E-6)); 
#endif
    return ialtitude;
}

float volatile baro;

int main (void)
{
    return CALC_altitude (baro);
}

it compiles and links without problem:

    avr-gcc -mmcu=attiny85 foo.c -c -Os avr-gcc -mmcu=attiny85 foo.o -o foo.elf -lm
Used avr-gcc 4.3.3 from WinAVR-20100110.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely he just needs to add -lm as the last entry on the linker invocation?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestions. I tried getting rid of the explicit cast but there was no change.

Next I tried adding -lm to the linker options under Project -> Configuration Options with no change. (There was no way of making it the last option when using this method.)

Below is a more complete listing of my output:

Build started 28.10.2012 at 10:00:16
avr-gcc  -mmcu=attiny84 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT Barometer.o -MF dep/Barometer.o.d  -c  ../Barometer.c
avr-gcc -mmcu=attiny84 -lm  -Wl,-Map=Barometer.map Barometer.o LCD.o     -o Barometer.elf
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr25\libc.a(floatsisf.o): In function `__floatunsisf':
(.text.avr-libc.fplib+0x0): multiple definition of `__floatunsisf'
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr25\libgcc.a(_usi_to_sf.o):c:\avrdev\gcc\build-avr\avr\avr25\libgcc/../../.././gcc/fp-bit.c:1391: first defined here
make: *** [Barometer.elf] Error 1
Build failed with 1 errors and 0 warnings...

My project consists of two source files, each with a header file. The header file is made using information in the "C Large Project Tutorial". Each header does "#include ", but I haven't found that to cause a problem before.

Thanks,

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to find a way to make -lm last.
Putting it before all object files is useless.
If -lm won't work, could you list the actual library as an input?

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That build environment looks a lot like AS4. If so under Project config did you try the "libraries" section? I think you'll find libm.a listed in the left pane. Just select it and [add object->] to ensure it gets listed on the right. I'm pretty sure AS4 is then smart enough to add the -lm this generates to the end of the linker invocation.

If that fails do it under Custom Options-[Linker] but make sure it is the last thing listed which stands some hope of it being late on the command line.

If all else fails configure the project to "use external makefile" and hand edit the Makefile to make sure -lm is last.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

That build environment looks a lot like AS4. If so under Project config did you try the "libraries" section? I think you'll find libm.a listed in the left pane. Just select it and [add object->] to ensure it gets listed on the right. I'm pretty sure AS4 is then smart enough to add the -lm this generates to the end of the linker invocation.

If that fails do it under Custom Options-[Linker] but make sure it is the last thing listed which stands some hope of it being late on the command line.

If all else fails configure the project to "use external makefile" and hand edit the Makefile to make sure -lm is last.

Yes, it's AS4. I'd tried adding -lm using Custom Options - Linker but it puts the -lm at the front.

I tried doing under "libraries" and selecting libm.a and then [add object->] but at this point my project directory opens, offering me the opportunity to select a file, but I'm not sure what I'm supposed to do.

Next, I tried "use external makefile" to edit my Makefile. I edited the section:

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=Barometer.map, -lm

Quote:

and moved the -lm option to the end of the line, as shown.

But I'm not sure exactly what AS4 is telling me to do with these cautions for "use external makefile":

Quote:
1. Target name must equal project name.
2. Clean/rebuild support requires "clean" target.
3. Makefile and target must exist in the same folder

For #1, does that mean I must name my Makefile "Barometer"?
For #2, does that mean I should delete all previously generated files in my \default and \default\dep folders?
For #3, does this mean my new (edited) makefile should go in my Barometer\default\ folder?

I tried all the options but did not get through an attempted build with the edited makefile, so I'm not finished trying this option yet.

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I tried doing under "libraries" and selecting libm.a and then [add object->] but at this point my project directory opens, offering me the opportunity to select a file, but I'm not sure what I'm supposed to do.

Ah the 4.19 bug check the .map for your AVR architecture number then point the "Libraries" thing at the right version of libm.a under Winavr\avr\lib

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, attempting to follow those instructions blindly, since I don't know what the heck I'm doing. I found the Barometer.map file and it seems to talk about AVR25 a lot. So I go back to configurations - libraries, click libm.a and then "add object", then navigate to libm.a in winavr-20100110\avr\lib\avr25 and selected libm.a, then OK and try to build again. I get this message:

rm -rf Baro2.o  Baro2.elf dep/* Baro2.hex Baro2.eep Baro2.lss Baro2.map
Build succeeded with 0 Warnings...
avr-gcc  -mmcu=attiny84 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT Baro2.o -MF dep/Baro2.o.d  -c  ../Baro2.c
avr-gcc -mmcu=attiny84 -Wl,-Map=Baro2.map Baro2.o    -l\avr25\libm  -o Baro2.elf
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: cannot find -l\avr25\libm
make: *** [Baro2.elf] Error 1
Build failed with 1 errors and 0 warnings... 

I also tried another approach, which was to start all over and sneak in bits of the source code until it blew up again. Just a single source code file this time and its header. I was able to put in my function and a minimal main() and got a build with no errors. Then as I was adding stuff back, a statement in main() that calls the routine that I thought was the problem made the error return. It doesn't use a cast, so I guess that wasn't the issue. But the second mention of that function, either defining it or calling it, brings about the error. Oh, this time I put the function before main() and previously it was after main(), if that could make a difference.

Oh yeah, this barometer / altimeter project is one I had working on the Arduino. Now I'm trying to do it on an ATtiny84. I'm also changing the display from a weird LED set-top box display to a more standard two line LCD.

Nick

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's a difference between a library, specified with -lfoo for libfoo.a, and a library search path specified with -L.

If you need to specify -L to find libm.a you have a broken installation or otherwise mis-set tool options.

If your switch led to alling -lblabla then just add m and you get -lm on the command line which adds libm.a.

The compiler knows how to find the right libm.a incarnation. If not, you have a broken installation or otherwise mis-set tool options.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I did a search on the error message wording and found several hits, including a message from Clawson of February 23, 2009:

Quote:

You're not linking wit libm.a - in the project config go to the "libraries" section and copy libm.a from the left to the right window.

... which I hadn't understood earlier. Did that and now it builds OK.

Now back to the altimeter.

Nick