EmbDev.net

Forum: ARM programming with GCC/GNU tools Floating point stops processor


von Vkle V. (vkle)


Rate this post
useful
not useful
I use YAGARTO to compile my program for lpc2138 controler.
Everything is OK, except floating point operations.
Following code stops processor:
float a = 10.2f;
a = a/2.0f;

How to enable floating point support?

Thanks!

von Clifford S. (clifford)


Rate this post
useful
not useful
Vkle Vkle wrote:
> I use YAGARTO to compile my program for lpc2138 controler.
> Everything is OK, except floating point operations.
> Following code stops processor:
> float a = 10.2f;
> a = a/2.0f;
>
> How to enable floating point support?
>
> Thanks!

If you compiled the code for hardware floating point, an invalid
instruction exception would have occurred, since there is no floating
point hardware on that part. Despite the fact that FP hardware is
uncommon on ARM, -mhard-float is the default option. Use -msoft-float
explicitly.

Ref:
http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/ARM-Options.html#ARM-Options

Clifford

von Vkle V. (vkle)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Vkle Vkle wrote:
>> I use YAGARTO to compile my program for lpc2138 controler.
>> Everything is OK, except floating point operations.
>> Following code stops processor:
>> float a = 10.2f;
>> a = a/2.0f;
>>
>> How to enable floating point support?
>>
>> Thanks!
>
> If you compiled the code for hardware floating point, an invalid
> instruction exception would have occurred, since there is no floating
> point hardware on that part. Despite the fact that FP hardware is
> uncommon on ARM, -mhard-float is the default option. Use -msoft-float
> explicitly.
>
> Ref:
> http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/ARM-Options.html#ARM-Options
>
> Clifford

So this problem have an evolution...
when I use -msoft-float in gcc option, linker reports this error:

yagarto/lib/gcc/arm-elf/4.2.2\libgcc.a(_muldivsf3.o) uses hardware FP,
whereas main.elf uses software FP

arm-elf-objcopy -p libgcc.a shows:
...
_divsi3.o:     file format elf32-littlearm
private flags = 0: [APCS-32] [FPA float format]
...


Maybe libgcc.a was built without software floating point support?
Where can I download "good" libgcc?

von Michael F. (mifi)


Rate this post
useful
not useful
Hello,

I do not know where your problem is, but here it works with fp too.
Even I do not know which HW you used, therefore I have tested it
here with a STR710 target. Please use the following example:

http://www.yagarto.de/download/yagarto/STR7Test.zip

And modify main.c like this:

int main (void)
{
  DWORD a = 1;
  DWORD b = 2;
  DWORD c = 0;

  float e = 7.2;
  float f = 0;

  a = a + d;

  while (1)
  {
    a++;
    b++;
    c = a + b;

    f = (float)a + (e/2.0);
    e = e + 0.1;
  }

  /*
   * This return here make no sense.
   * But to prevent the compiler warning:
   * "return type of 'main' is not 'int'
   * we use an int as return :-)
   */
  return(0);
}

I could compile/link without problems here, even I could
debug it with Insight (YAGARTO version 08.04.2008).

Best regards,

Michael

von Clifford S. (clifford)


Rate this post
useful
not useful
Vkle Vkle wrote:
> Maybe libgcc.a was built without software floating point support?
> Where can I download "good" libgcc?

The standard Newlib installation comes provides several library builds.
The one in yagarto/lib/gcc/arm-elf/4.2.2. One solution is to specify the
linker option  -nostdlib, and then explicitly link the appropriate
library, something like the following:

-nostdlib
-L"c:/yagarto/lib/gcc/arm-elf/4.2.2/interwork/"
-L"c:/yagarto/arm-elf/lib/interwork"
--start-group -lm -lc -lgcc --end-group

However the same problem here:
http://en.mikrocontroller.net/topic/104158 was resolved simply by
specifying -mthumb-interwork, which I think works exactly because it
changes the default library to the interwork variant, but that is just a
guess.

Since -mthumb-interwork has a small code-size overhead, you may want to
use the first solution, this will use the interwork libraries, but your
code will be ARM mode code. Alternatively you might choose to compile
for thumb mode, in which case the yagarto/lib/gcc/arm-elf/4.2.2/thumb
library would be used, which I assume does not need fp hardware (I am
not sure if it is even possible!?)

Thumb mode has two advantages, increased code density, and on systems
using a 16bit data bus, faster execution (about 40% I have read). The
internal memory bus on your part is 32bit I believe, so Thumb code would
generally be slower than 32bit ARM code. It is useful though if you are
using external memory on a 16bit bus.

Clifford

von Clifford S. (clifford)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Vkle Vkle wrote:
> The standard Newlib installation comes provides several library builds.
> The one in yagarto/lib/gcc/arm-elf/4.2.2. One solution is to specify the
> linker option  -nostdlib, and then explicitly link the appropriate
> library, something like the following:

I really garbled that didn't I! Should have read:

The standard Newlib installation provides several library builds. One
solution is to specify the linker option  -nostdlib, and then explicitly
link the appropriate library, something like the following:

von Vkle V. (vkle)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Clifford Slocombe wrote:
>> Vkle Vkle wrote:
>> The standard Newlib installation comes provides several library builds.
>> The one in yagarto/lib/gcc/arm-elf/4.2.2. One solution is to specify the
>> linker option  -nostdlib, and then explicitly link the appropriate
>> library, something like the following:
>
> I really garbled that didn't I! Should have read:
>
> The standard Newlib installation provides several library builds. One
> solution is to specify the linker option  -nostdlib, and then explicitly
> link the appropriate library, something like the following:

I dont know what to say.
I reinstall YAGARTO and Eclipse, but problem is still actual.
This code
        float b = 2.0;
  b += 1;
tranlated into:
0x0000012c <main+20>: ldr   r3, [pc, #36]  ; 0x158 <main+64>
0x00000130 <main+24>: str   r3, [r11, #-20]
0x00000134 <main+28>: ldr   r0, [r11, #-20]
0x00000138 <main+32>: ldr   r1, [pc, #28]  ; 0x15c <main+68>
0x0000013c <main+36>: bl    0x30b8 <__aeabi_fadd>
0x00000140 <main+40>: mov   r3, r0

All seems to be fine, but bl 0x30b8 does not execute, it just returns
into <main+20> (possible controller reset).
I've tried with -mthumb and -mthumb-interwork in all combination. Don't
work.
Any ideas? Maybe loader script bug? Anything else?
If anybody has time to help me, please create Eclipse project for
LPC2138 with sample floating point code.
My robot is waiting for a new computer http://tinyurl.com/646afd =)

von Vkle V. (vkle)


Rate this post
useful
not useful
Vkle Vkle wrote:
> Clifford Slocombe wrote:
>> Clifford Slocombe wrote:
>>> Vkle Vkle wrote:
>>> The standard Newlib installation comes provides several library builds.
>>> The one in yagarto/lib/gcc/arm-elf/4.2.2. One solution is to specify the
>>> linker option  -nostdlib, and then explicitly link the appropriate
>>> library, something like the following:
>>
>> I really garbled that didn't I! Should have read:
>>
>> The standard Newlib installation provides several library builds. One
>> solution is to specify the linker option  -nostdlib, and then explicitly
>> link the appropriate library, something like the following:
>
> I dont know what to say.
> I reinstall YAGARTO and Eclipse, but problem is still actual.
> This code
>         float b = 2.0;
>   b += 1;
> tranlated into:
> 0x0000012c <main+20>: ldr   r3, [pc, #36]  ; 0x158 <main+64>
> 0x00000130 <main+24>: str   r3, [r11, #-20]
> 0x00000134 <main+28>: ldr   r0, [r11, #-20]
> 0x00000138 <main+32>: ldr   r1, [pc, #28]  ; 0x15c <main+68>
> 0x0000013c <main+36>: bl    0x30b8 <__aeabi_fadd>
> 0x00000140 <main+40>: mov   r3, r0
>
> All seems to be fine, but bl 0x30b8 does not execute, it just returns
> into <main+20> (possible controller reset).
> I've tried with -mthumb and -mthumb-interwork in all combination. Don't
> work.
> Any ideas? Maybe loader script bug? Anything else?
> If anybody has time to help me, please create Eclipse project for
> LPC2138 with sample floating point code.
> My robot is waiting for a new computer http://tinyurl.com/646afd =)

I solve this problem. But I don't know what was the solution =(.
I replace my Makefile, ld script, and crt0.s by files from this examples
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/lpc213x_lpc214x_examples_20061205.zip

Thanks!

von Clifford S. (clifford)


Rate this post
useful
not useful
Vkle Vkle wrote:
> I solve this problem. But I don't know what was the solution =(.
> I replace my Makefile, ld script, and crt0.s by files from this examples
> 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/lpc213x_lpc214x_examples_20061205.zip
>
Had you posted a complete build log before you made that change and then
again when it was fixed, perhaps we could have determined the
difference. Are you sure that it was not a simple stack overrun, and the
new linker script and start-up just allocate more?

von Vkle V. (vkle)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Vkle Vkle wrote:
>> I solve this problem. But I don't know what was the solution =(.
>> I replace my Makefile, ld script, and crt0.s by files from this examples
>> 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/lpc213x_lpc214x_examples_20061205.zip
>>
> Had you posted a complete build log before you made that change and then
> again when it was fixed, perhaps we could have determined the
> difference. Are you sure that it was not a simple stack overrun, and the
> new linker script and start-up just allocate more?

I've determined the difference. You are right, it's a stack problem.
Memory region "ram" was defined in ld-script, but .stack section put in
"RAM" section.
So, linker show only a warning (imho it's an error): memory region RAM
not declared.

von Vkle V. (vkle)


Rate this post
useful
not useful
Vkle Vkle wrote:
> Clifford Slocombe wrote:
>> Vkle Vkle wrote:
>>> I solve this problem. But I don't know what was the solution =(.
>>> I replace my Makefile, ld script, and crt0.s by files from this examples
>>> 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/lpc213x_lpc214x_examples_20061205.zip
>>>
>> Had you posted a complete build log before you made that change and then
>> again when it was fixed, perhaps we could have determined the
>> difference. Are you sure that it was not a simple stack overrun, and the
>> new linker script and start-up just allocate more?
>
> I've determined the difference. You are right, it's a stack problem.
> Memory region "ram" was defined in ld-script, but .stack section put in
> "RAM" section.
> So, linker show only a warning (imho it's an error): memory region RAM
> not declared.

My problem is came back after I've changed OPT flag in Makefile from
OPT=s to OPT=0. It's strange. I've changed flag back and problem
disappear. Do you have any suggessions about the reason of this
behaviour?

von Clifford S. (clifford)


Rate this post
useful
not useful
Vkle Vkle wrote:
> Vkle Vkle wrote:
> My problem is came back after I've changed OPT flag in Makefile from
> OPT=s to OPT=0. It's strange. I've changed flag back and problem
> disappear. Do you have any suggessions about the reason of this
> behaviour?

Not that strange. Otherwise benign code flaws can be exposed by
different optimisations. Are you sure that this is the exact same
problem and not just a problem with similar symptoms? And are we talking
about the processor halt or the library mismatch problem now?

Clifford

von Vkle V. (vkle)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Vkle Vkle wrote:
>> Vkle Vkle wrote:
>> My problem is came back after I've changed OPT flag in Makefile from
>> OPT=s to OPT=0. It's strange. I've changed flag back and problem
>> disappear. Do you have any suggessions about the reason of this
>> behaviour?
>
> Not that strange. Otherwise benign code flaws can be exposed by
> different optimisations. Are you sure that this is the exact same
> problem and not just a problem with similar symptoms? And are we talking
> about the processor halt or the library mismatch problem now?
>
> Clifford

Ok. My situation.
I've some code and I want to use floating point in my project.
For a test I've write a code:
int main()
    volatile float a = 10.2;
    while(1){
        asm("nop");
        //nop...65 times...
        asm("nop");
        a = a / 2.0;
    }
 return 0;
}

Without nop's code works.
With nops... I can't understand what happens. =(

Debugger stops on a = a / 2.0; instruction. Or shows "No source
available for """.

This strings appear in console:
Error:   gdb_server.c:1024 gdb_error(): unexpected error -308
Warning: arm7_9_common.c:1950 arm7_9_read_memory(): memory read caused
data abort (address: 0xffffffff, size: 0x1, count: 0x1)

I have not read or write any data except my variable "a".

My project here http://serenity.1adw.com/~vkle/clifford/Unit.zip.
Comment nops... it works. Uncomment nops - dosen't works. =(

Disassembly:
0x00007f44 andeq       r0, r0, r0
0x00007f48 andeq       r0, r0, r0
...
0x00007f5c andeq       r0, r0, r0

It's not a code it's a garbage.

section            size         addr
.text              4120            0
.data                 4   1073741824
.bss                 44   1073741828
.stack             9216   1073742080
.comment             36            0
.debug_aranges      208            0
.debug_pubnames     600            0
.debug_info        2099            0
.debug_abbrev       759            0
.debug_line        1370            0
.debug_frame        624            0
.debug_str          744            0
.debug_loc          529            0
.ARM.attributes      16            0
.debug_ranges        64            0
Total             20433

von Vkle V. (vkle)


Rate this post
useful
not useful
Change float to int - works, but I need floating point. =(

von Vkle V. (vkle)


Rate this post
useful
not useful
When calls ___floatsidf insight shows. It's strange. Help! =)
- 0x3280 <__floatsidf>: andeq r0, r0, r0
- 0x3284 <__floatsidf+4>: andeq r0, r0, r0
- 0x3288 <__floatsidf+8>: andeq r0, r0, r0
- 0x328c <__floatsidf+12>: andeq r0, r0, r0
- 0x3290 <__floatsidf+16>: andeq r0, r0, r0
- 0x3294 <__floatsidf+20>: andeq r0, r0, r0
- 0x3298 <__floatsidf+24>: andeq r0, r0, r0
- 0x329c <__floatsidf+28>: andeq r0, r0, r0
- 0x32a0 <__floatsidf+32>: andeq r0, r0, r0
- 0x32a4 <__floatsidf+36>: andeq r0, r0, r0
- 0x32a8 <__floatsidf+40>: andeq r0, r0, r0

von Vkle V. (vkle)


Rate this post
useful
not useful
IMHO libraries did not linked.

von Clifford S. (clifford)


Rate this post
useful
not useful
Vkle Vkle wrote:
> IMHO libraries did not linked.

If that were true, the whole binary would not have linked due to
unresolved symbols (unless you had specified a partial link, which would
be very unusual, and intentional).

Still seems more likely to be a stack issue. It looks like you have used
return value from a corrupted stack and ended up in the wrong location.

von Vkle V. (vkle)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Vkle Vkle wrote:
>> IMHO libraries did not linked.
>
> If that were true, the whole binary would not have linked due to
> unresolved symbols (unless you had specified a partial link, which would
> be very unusual, and intentional).
>
> Still seems more likely to be a stack issue. It looks like you have used
> return value from a corrupted stack and ended up in the wrong location.

I've a sample code in main.c, only this code:
int main(){
    float a = 10.2;
    while(1){
        a /= 2.0;
    }
    return 0;
}

I don't use any interrupts, so this code and startup are only executed.
Am I right?
If I remove all my files except main.c and startup.s from Makefile (from
SRC, SRCARM) this code normally work. When I step into __divsf3 function
I've see:
    0x4d8  <__divsf3>:    mov  r12, #255  ; 0xff
    0x4dc  <__divsf3+4>:    ands  r2, r12, r0, lsr #23
    0x4e0  <__divsf3+8>:    andsne  r3, r12, r1, lsr #23
    0x4e4  <__divsf3+12>:    teqne  r2, r12
    ...
If I turn my files back in Makefile I see this after step into __divsf3:
    0x35b0  <__divsf3>:    andeq  r0, r0, r0
    0x35b4  <__divsf3+4>:    andeq  r0, r0, r0
    0x35b8  <__divsf3+8>:    andeq  r0, r0, r0
    0x35bc  <__divsf3+12>:    andeq  r0, r0, r0
    0x35c0  <__divsf3+16>:    andeq  r0, r0, r0
    ...
What do you think about it?

von Vkle V. (vkle)


Rate this post
useful
not useful
Vkle Vkle wrote:
> Clifford Slocombe wrote:
>> Vkle Vkle wrote:
>>> IMHO libraries did not linked.
>>
>> If that were true, the whole binary would not have linked due to
>> unresolved symbols (unless you had specified a partial link, which would
>> be very unusual, and intentional).
>>
>> Still seems more likely to be a stack issue. It looks like you have used
>> return value from a corrupted stack and ended up in the wrong location.
>
> I've a sample code in main.c, only this code:
> int main(){
>     float a = 10.2;
>     while(1){
>         a /= 2.0;
>     }
>     return 0;
> }
>
> I don't use any interrupts, so this code and startup are only executed.
> Am I right?
> If I remove all my files except main.c and startup.s from Makefile (from
> SRC, SRCARM) this code normally work. When I step into __divsf3 function
> I've see:
>     0x4d8  <__divsf3>:    mov  r12, #255  ; 0xff
>     0x4dc  <__divsf3+4>:    ands  r2, r12, r0, lsr #23
>     0x4e0  <__divsf3+8>:    andsne  r3, r12, r1, lsr #23
>     0x4e4  <__divsf3+12>:    teqne  r2, r12
>     ...
> If I turn my files back in Makefile I see this after step into __divsf3:
>     0x35b0  <__divsf3>:    andeq  r0, r0, r0
>     0x35b4  <__divsf3+4>:    andeq  r0, r0, r0
>     0x35b8  <__divsf3+8>:    andeq  r0, r0, r0
>     0x35bc  <__divsf3+12>:    andeq  r0, r0, r0
>     0x35c0  <__divsf3+16>:    andeq  r0, r0, r0
>     ...
> What do you think about it?

SOLUTION (I hope...)

OpenOCD config file contains following string:

    flash bank lpc2000 0x0 0x40000 0 0 0 lpc2000_v2 14746 calc_checksum

but for LPC2138 0x40000 it's pnly a half of memory.
String sould be:

    flash bank lpc2000 0x0 0x7D000 0 0 0 lpc2000_v2 14746 calc_checksum

The reason of my errors was wrong data in flash after address 0x40000.

Clifford, thanks for all!

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.