From: David Brown on
On 19/03/2010 10:34, Habib Bouaziz-Viallet wrote:
> David Brown a �crit :
>> On 18/03/2010 18:47, linnix wrote:
>>> In response to another thread, I am still getting these problems with
>>> WinAVR 2010. I think the linker is hitting some AVR limits. There
>>> are similar reports on the web as well.
>>> -------------------------------------------------------------------------------------------------
>>>
>>>
>>> unsigned char u;
>>> float f;
>>>
>>> u = (unsigned char) f;
>>>
>>> ---------------------------------------------------------------------------------------------------
>>>
>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>> (.text.avr-libc.fplib+0x10): relocation truncated to fit:
>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>> (.text.avr-libc.fplib+0x20): relocation truncated to fit:
>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>
>> Normally, comp.arch.embedded is a helpful place, but some of the
>> "answers" is this thread are ridiculous! People are leaping to
>> conclusions like "the avr can't do floating point", "gcc can convert a
>> floating point to an int, but not to a char", "try disabling
>> optimisations", etc.
>>
>> It seems no one has asked any /relevant/ questions the would have
>> helped you out.
>>
>> Have you got a minimal code snippet that illustrates the problem, and
>> is valid and compilable C code? In this case, you would probably have
>> something like:
>>
>> // Use "volatile" so the code won't be optimised away
>> volatile unsigned char u;
>> volatile float f;
>>
>> int main(void) {
>> u = (unsigned char) f;
>> return 0;
>> }
>>
> In that case i'm quite sure gcc promote internally the (unsigned char)f
> to an int. Differences appears when actually using the u variable
> (instead of just evaluate like in your code snippet) that's IMHO the
> initial issue.
>

gcc does not promote the "(unsigned char) f" to an int - it would only
do that if you were doing maths on the value.

The function used for this conversion is "__fixunssfsi", which converts
a float into and unsigned int. gcc then converts this into an unsigned
char (by simply taking the lower 8-bit register). But that's not
"promotion", and it is a perfectly correct implementation.

You can be pretty confident that gcc gets the promotions and
interpretations of the code correct. While the avr port is a relatively
"small" compiler, the gcc front-end that interprets the C code is the
same for all gcc ports.

But it is certainly possible that issues appear when the value is used -
that's why the original poster has to provide a minimal code snippet
that shows the problem.


> Why not verifying this with
> avr-gcc -S yourfile.c
>
> and read the assembler yourfile.s ...
>

I have done exactly that, using the command line:

D:\Micros\WinAVR-20100110\bin\avr-gcc -mmcu=atmega128 -Os -std=gnu99
-Wa,-ahlsd=test.avr.20100110.lst -fverbose-asm test.c -o test.elf

(Obviously the path to avr-gcc will vary).

The relevant assembly code is:

64 .global main
66 main:
67 /* prologue: function */
68 /* frame size = 0 */
69 0022 6091 0000 lds r22,f ; f.0, f
70 0026 7091 0000 lds r23,(f)+1 ; f.0, f
71 002a 8091 0000 lds r24,(f)+2 ; f.0, f
72 002e 9091 0000 lds r25,(f)+3 ; f.0, f
73 0032 0E94 0000 call __fixunssfsi ;
74 0036 6093 0000 sts u,r22 ; u, tmp44
75 003a 80E0 ldi r24,lo8(0) ; ,
76 003c 90E0 ldi r25,hi8(0) ; ,
77 /* epilogue start */
78 003e 0895 ret


And the elf output is properly linked against the required libraries
(automatically - you don't need to specify the library on the command line).

But all I can do here is show that avr-gcc has no problems compiling and
linking this code snippet correctly. To help the O/P, we need a snippet
that fails for him, not one that works for me. Once he posts that
snippet and the command line, people can really start to help him out
rather than making wild hand-waving suggestions.

> What makes you think guys down here make ridiculous answers when
> obviously the initial question is not clearly exposed.
>

That's kind of the point, really. The OP hasn't given enough
information to be able to diagnose his problem and help him out. But
instead of asking for more information, people here have given a variety
of useless information and suggestions. Not all the answers have been
bad - suggestions to break it into steps and to look at the size of the
code are good ideas. But none have asked him for the information that's
needed.

If I were to post a question in a car newsgroup saying my Volkswagon is
making a funny noise, I would expect to be asked to describe the noise,
or to say if it was constant or comes and goes, or asked what year and
model I have. I would not expect to be told that if I want a noise-free
drive I should buy a Ferrari, or that someone else's bus makes a
different noise.
From: Habib Bouaziz-Viallet on
David Brown a �crit :
> On 19/03/2010 10:34, Habib Bouaziz-Viallet wrote:
>> David Brown a �crit :
>>> On 18/03/2010 18:47, linnix wrote:
>>>> In response to another thread, I am still getting these problems with
>>>> WinAVR 2010. I think the linker is hitting some AVR limits. There
>>>> are similar reports on the web as well.
>>>> -------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>>
>>>> unsigned char u;
>>>> float f;
>>>>
>>>> u = (unsigned char) f;
>>>>
>>>> ---------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>>> (.text.avr-libc.fplib+0x10): relocation truncated to fit:
>>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>>> (.text.avr-libc.fplib+0x20): relocation truncated to fit:
>>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>>
>>> Normally, comp.arch.embedded is a helpful place, but some of the
>>> "answers" is this thread are ridiculous! People are leaping to
>>> conclusions like "the avr can't do floating point", "gcc can convert a
>>> floating point to an int, but not to a char", "try disabling
>>> optimisations", etc.
>>>
>>> It seems no one has asked any /relevant/ questions the would have
>>> helped you out.
>>>
>>> Have you got a minimal code snippet that illustrates the problem, and
>>> is valid and compilable C code? In this case, you would probably have
>>> something like:
>>>
>>> // Use "volatile" so the code won't be optimised away
>>> volatile unsigned char u;
>>> volatile float f;
>>>
>>> int main(void) {
>>> u = (unsigned char) f;
>>> return 0;
>>> }
>>>
>> In that case i'm quite sure gcc promote internally the (unsigned char)f
>> to an int. Differences appears when actually using the u variable
>> (instead of just evaluate like in your code snippet) that's IMHO the
>> initial issue.
>>
>
> gcc does not promote the "(unsigned char) f" to an int - it would only
> do that if you were doing maths on the value.
That is exactly the point. Why in the earth someone would need to
convert a float (doing sine and cosine) to a unsigned char ???

I said that extracting the integer part of the float is ok when casting
a float to an int.

When you make a cast from a float to an unsigned int it would result a
zero if the float is negative (not quite sure either ... just conjecture)

BTW i don't know what would be the result if the target has a FPU (like
our big bunch desktop machines) ... :-)

>
> The function used for this conversion is "__fixunssfsi", which converts
> a float into and unsigned int. gcc then converts this into an unsigned
> char (by simply taking the lower 8-bit register). But that's not
> "promotion", and it is a perfectly correct implementation.
>
> You can be pretty confident that gcc gets the promotions and
> interpretations of the code correct. While the avr port is a relatively
> "small" compiler, the gcc front-end that interprets the C code is the
> same for all gcc ports.
>
> But it is certainly possible that issues appear when the value is used -
> that's why the original poster has to provide a minimal code snippet
> that shows the problem.
>
>
>> Why not verifying this with
>> avr-gcc -S yourfile.c
>>
>> and read the assembler yourfile.s ...
>>
>
> I have done exactly that, using the command line:
>
> D:\Micros\WinAVR-20100110\bin\avr-gcc -mmcu=atmega128 -Os -std=gnu99
> -Wa,-ahlsd=test.avr.20100110.lst -fverbose-asm test.c -o test.elf
>
> (Obviously the path to avr-gcc will vary).
>
> The relevant assembly code is:
>
> 64 .global main
> 66 main:
> 67 /* prologue: function */
> 68 /* frame size = 0 */
> 69 0022 6091 0000 lds r22,f ; f.0, f
> 70 0026 7091 0000 lds r23,(f)+1 ; f.0, f
> 71 002a 8091 0000 lds r24,(f)+2 ; f.0, f
> 72 002e 9091 0000 lds r25,(f)+3 ; f.0, f
> 73 0032 0E94 0000 call __fixunssfsi ;
> 74 0036 6093 0000 sts u,r22 ; u, tmp44
> 75 003a 80E0 ldi r24,lo8(0) ; ,
> 76 003c 90E0 ldi r25,hi8(0) ; ,
> 77 /* epilogue start */
> 78 003e 0895 ret
>
>
> And the elf output is properly linked against the required libraries
> (automatically - you don't need to specify the library on the command
> line).
>
> But all I can do here is show that avr-gcc has no problems compiling and
> linking this code snippet correctly. To help the O/P, we need a snippet
> that fails for him, not one that works for me. Once he posts that
> snippet and the command line, people can really start to help him out
> rather than making wild hand-waving suggestions.
>
>> What makes you think guys down here make ridiculous answers when
>> obviously the initial question is not clearly exposed.
>>
>
> That's kind of the point, really. The OP hasn't given enough
> information to be able to diagnose his problem and help him out. But
> instead of asking for more information, people here have given a variety
> of useless information and suggestions. Not all the answers have been
> bad - suggestions to break it into steps and to look at the size of the
> code are good ideas. But none have asked him for the information that's
> needed.
>
> If I were to post a question in a car newsgroup saying my Volkswagon is
> making a funny noise, I would expect to be asked to describe the noise,
> or to say if it was constant or comes and goes, or asked what year and
> model I have. I would not expect to be told that if I want a noise-free
> drive I should buy a Ferrari, or that someone else's bus makes a
> different noise.

Volkwagon have funny noises even fresh out of the factory ... (Just a joke)

Habib.
From: David Brown on
On 19/03/2010 12:11, Habib Bouaziz-Viallet wrote:
> David Brown a �crit :
>> On 19/03/2010 10:34, Habib Bouaziz-Viallet wrote:
>>> David Brown a �crit :
>>>> On 18/03/2010 18:47, linnix wrote:
>>>>> In response to another thread, I am still getting these problems with
>>>>> WinAVR 2010. I think the linker is hitting some AVR limits. There
>>>>> are similar reports on the web as well.
>>>>> -------------------------------------------------------------------------------------------------
>>>>>
>>>>>
>>>>>
>>>>> unsigned char u;
>>>>> float f;
>>>>>
>>>>> u = (unsigned char) f;
>>>>>
>>>>> ---------------------------------------------------------------------------------------------------
>>>>>
>>>>>
>>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>>>> (.text.avr-libc.fplib+0x10): relocation truncated to fit:
>>>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/
>>>>> avr35\libc.a(fp_powsodd.o): In function `__fp_powsodd':
>>>>> (.text.avr-libc.fplib+0x20): relocation truncated to fit:
>>>>> R_AVR_13_PCREL against symbol `__mulsf3' defined in .text section in
>>>>> c:/wavr10/bin/../lib/gcc/avr/4.3.3/avr35\libgcc.a(_mul_sf.o)
>>>>
>>>> Normally, comp.arch.embedded is a helpful place, but some of the
>>>> "answers" is this thread are ridiculous! People are leaping to
>>>> conclusions like "the avr can't do floating point", "gcc can convert a
>>>> floating point to an int, but not to a char", "try disabling
>>>> optimisations", etc.
>>>>
>>>> It seems no one has asked any /relevant/ questions the would have
>>>> helped you out.
>>>>
>>>> Have you got a minimal code snippet that illustrates the problem, and
>>>> is valid and compilable C code? In this case, you would probably have
>>>> something like:
>>>>
>>>> // Use "volatile" so the code won't be optimised away
>>>> volatile unsigned char u;
>>>> volatile float f;
>>>>
>>>> int main(void) {
>>>> u = (unsigned char) f;
>>>> return 0;
>>>> }
>>>>
>>> In that case i'm quite sure gcc promote internally the (unsigned char)f
>>> to an int. Differences appears when actually using the u variable
>>> (instead of just evaluate like in your code snippet) that's IMHO the
>>> initial issue.
>>>
>>
>> gcc does not promote the "(unsigned char) f" to an int - it would only
>> do that if you were doing maths on the value.
> That is exactly the point. Why in the earth someone would need to
> convert a float (doing sine and cosine) to a unsigned char ???
>

I don't think I'm following your argument here.

> I said that extracting the integer part of the float is ok when casting
> a float to an int.
>
> When you make a cast from a float to an unsigned int it would result a
> zero if the float is negative (not quite sure either ... just conjecture)
>

An "unsigned char" is just a silly name for an uint8_t - an unsigned
integer in the range 0 .. 255. Why do you see this as any different
from converting the float to an integer in the range -32768..+32767 ? I
presume the OP has made sure that the float in question is within a
reasonable range for the conversion - otherwise his data will be invalid
(though the program will still compile, link and run) - I don't know how
overflows and underflows are handled by the cast-to-integer operations.

To take a simple example, you might want a make a pwm sine wave by:

uint8_t pwmPercent;
pwmPercent = 100 * ((sinf(omega * time) + 1) / 2);

This is doing floating point calculations and then casting it to an
"unsigned char". The results would be exactly the same if pwmPercent
were an "int".



> BTW i don't know what would be the result if the target has a FPU (like
> our big bunch desktop machines) ... :-)
>

It should be the same (to within rounding errors). avr-gcc, like most
compilers, implements basic IEEE floating point standards. As far as I
know, it doesn't implement NaNs, signed zeros, and other wierdo floating
point stuff, just like most other compilers and most hardware FPUs.

>>
>> The function used for this conversion is "__fixunssfsi", which
>> converts a float into and unsigned int. gcc then converts this into an
>> unsigned char (by simply taking the lower 8-bit register). But that's
>> not "promotion", and it is a perfectly correct implementation.
>>
>> You can be pretty confident that gcc gets the promotions and
>> interpretations of the code correct. While the avr port is a
>> relatively "small" compiler, the gcc front-end that interprets the C
>> code is the same for all gcc ports.
>>
>> But it is certainly possible that issues appear when the value is used
>> - that's why the original poster has to provide a minimal code snippet
>> that shows the problem.
>>
>>
>>> Why not verifying this with
>>> avr-gcc -S yourfile.c
>>>
>>> and read the assembler yourfile.s ...
>>>
>>
>> I have done exactly that, using the command line:
>>
>> D:\Micros\WinAVR-20100110\bin\avr-gcc -mmcu=atmega128 -Os -std=gnu99
>> -Wa,-ahlsd=test.avr.20100110.lst -fverbose-asm test.c -o test.elf
>>
>> (Obviously the path to avr-gcc will vary).
>>
>> The relevant assembly code is:
>>
>> 64 .global main
>> 66 main:
>> 67 /* prologue: function */
>> 68 /* frame size = 0 */
>> 69 0022 6091 0000 lds r22,f ; f.0, f
>> 70 0026 7091 0000 lds r23,(f)+1 ; f.0, f
>> 71 002a 8091 0000 lds r24,(f)+2 ; f.0, f
>> 72 002e 9091 0000 lds r25,(f)+3 ; f.0, f
>> 73 0032 0E94 0000 call __fixunssfsi ;
>> 74 0036 6093 0000 sts u,r22 ; u, tmp44
>> 75 003a 80E0 ldi r24,lo8(0) ; ,
>> 76 003c 90E0 ldi r25,hi8(0) ; ,
>> 77 /* epilogue start */
>> 78 003e 0895 ret
>>
>>
>> And the elf output is properly linked against the required libraries
>> (automatically - you don't need to specify the library on the command
>> line).
>>
>> But all I can do here is show that avr-gcc has no problems compiling
>> and linking this code snippet correctly. To help the O/P, we need a
>> snippet that fails for him, not one that works for me. Once he posts
>> that snippet and the command line, people can really start to help him
>> out rather than making wild hand-waving suggestions.
>>
>>> What makes you think guys down here make ridiculous answers when
>>> obviously the initial question is not clearly exposed.
>>>
>>
>> That's kind of the point, really. The OP hasn't given enough
>> information to be able to diagnose his problem and help him out. But
>> instead of asking for more information, people here have given a
>> variety of useless information and suggestions. Not all the answers
>> have been bad - suggestions to break it into steps and to look at the
>> size of the code are good ideas. But none have asked him for the
>> information that's needed.
>>
>> If I were to post a question in a car newsgroup saying my Volkswagon
>> is making a funny noise, I would expect to be asked to describe the
>> noise, or to say if it was constant or comes and goes, or asked what
>> year and model I have. I would not expect to be told that if I want a
>> noise-free drive I should buy a Ferrari, or that someone else's bus
>> makes a different noise.
>
> Volkwagon have funny noises even fresh out of the factory ... (Just a joke)
>
> Habib.

From: Cesar Rabak on
Em 18/3/2010 17:39, linnix escreveu:
> On Mar 18, 11:21 am, Habib Bouaziz-Viallet<h.bouazizvial...(a)free.fr>
> wrote:
>> Le Thu, 18 Mar 2010 10:47:44 -0700, linnix a �crit :
>>
>>> unsigned char u;
>>> float f;
>>
>>> u = (unsigned char) f;
>>
>> In what kind of situation you need to cast a float to that unsigned
>> char ???
>> If you want to extract the integer part of the float, let me tell you
>> that this way is a bit silly.
>>
>> Question yourself before asking to C.
>>
>> Habib
>
> f is result of k1 * sine x + k2 * cosine y.
>
> How would you extract the integer part without casting?

I would use round(), trunc(), ceil() or floor() as each could better fit.

--
Cesar Rabak
GNU/Linux User 52247.
Get counted: http://counter.li.org/
From: Hans-Bernhard Bröker on
[F'up2 set --- this has nothing to do with electronics design]

Habib Bouaziz-Viallet wrote:
> David Brown a �crit :
>> On 19/03/2010 10:34, Habib Bouaziz-Viallet wrote:

>>> In that case i'm quite sure gcc promote internally the (unsigned char)f
>>> to an int.

You're sure of something incorrect there.

> That is exactly the point. Why in the earth someone would need to
> convert a float (doing sine and cosine) to a unsigned char ???

That's none of your business. It's perfectly allowed C code, so the
compiler _must_ support it.

> When you make a cast from a float to an unsigned int it would result a
> zero if the float is negative (not quite sure either ... just conjecture)

Well, wrong again. Values from 0 (inclusive) to -1 (exclusive) convert
to zero, all other negative values cause undefined behaviour.

> BTW i don't know what would be the result if the target has a FPU (like
> our big bunch desktop machines) ... :-)

That has nothing to do with it, in principle.

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: NET tips to expand your biz
Next: IR is insane