Is toolchain work correct with floating point and ARMv7?

Asked by Vitaliy Bortsov

Hello.
Here is code snippet which fail on Cortex-R4F and software floating point.

#include <iostream>
#include <cstdio>

int main()
{
    char buf[100];
    float f = 0.000187F;
    snprintf(buf, 100, "0.000187=%f %d", f, (int)(f*1e6f));
    while(1);
    return 0;
}

There will be invalid string in buf for both values.
Compiling and linking command string:
arm-none-eabi-g++ -Og mcpu=cortex-r4f -marm -g -mfloat-abi=soft -fmessage-length=0 -fno-builtin -c -std=c++11 -fno-rtti -fno-use-cxa-atexit main.cpp -o main.o

arm-none-eabi-g++ -Og -mcpu=cortex-r4f -marm -g -mfloat-abi=soft -fmessage-length=0 -fno-builtin -Wl,-T,rom.lds -Wl,--gc-sections --specs=nosys.specs main.o -o fw.elf
(plus additional startup object files)

If I remove <iostream> then buf containt correct string.

All floating point operations failed if I add #include <iostream>

How can I use <iostream> with working floating-point?

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Vitaliy Bortsov (bortsov) said :
#2

Hello.
It is a bug it toolchain even in toolchain v5.2
Stack aligment by 4 bytes (if not aligned to 8 bytes) lead to fail work with floating point.

In linker sript from toolchain there is no aligment for 8 bytes:
 __StackTop = ORIGIN(RAM) + LENGTH(RAM);
 PROVIDE(__stack = __StackTop);

Revision history for this message
Joey Ye (jinyun-ye) said :
#3

Vitaliy,

You are right the current linker script won't work if ORGIN(RAM) or LENGTH(RAM) is not 8 bytes aligned. There are other parts in the same script may not work if start address of flash/ram is not round to 4 bytes.

But how often does a chip has unaligned start address and RAM size, so that to justify the change?

Thanks,
Joey

Revision history for this message
Vitaliy Bortsov (bortsov) said :
#4

Hello, Joey.
I use linker script for Cortex-R4F that place stacks for all modes right after all data sections and sometimes begin address of stack frames is not aligned to 8 bytes. I want to check maximum used space in IRQ stack, FIQ stack, SVC stack and heap and because of that I fill stacks to some values and periodically check stacks and heap. Also I limit heap in _sbrk() in contrast of toolchains _sbrk().

Here is my linker script

/* Entry Point */
ENTRY(resetEntry)

SYS_STACK_SIZE = 512;
IRQ_STACK_SIZE = 1024;
FIQ_STACK_SIZE = 512;
SVC_STACK_SIZE = 4000;
ABT_STACK_SIZE = 128;
UND_STACK_SIZE = 128;
USR_STACK_SIZE = 128;

HEAPSIZE = 0x1000 + 0x1000 + 0x2000 + 0x4000;

/* Specify the memory areas */
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00140000
  RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 128K
}

/* Define output sections */
SECTIONS
{
    .vectors : {*(.intvecs)}

    .text :
    {
        CREATE_OBJECT_SYMBOLS
        . = ALIGN(4);
        *(.text) /* .text sections (code) */
        *(.text*) /* .text* sections (code) */

        *(.eh_frame)

        KEEP (*(.init))
        KEEP (*(.fini))

        *(.rodata)
        *(.rodata*)

        . = ALIGN(4);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array*))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(4);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array*))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(4);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array*))
        PROVIDE_HIDDEN (__fini_array_end = .);

    } >FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    __etext = .;

    .fastcode :
    { /* used for code executed from RAM and copied from ROM */
        __fastcode_load = LOADADDR (.fastcode);
        __fastcode_start = .;

        *(.glue_7t) *(.glue_7)

        /* functions with __attribute__ ((section (".fastcode.text")))*/
        *(.fastcode.text)
        /* add other modules here ... */

        . = ALIGN (4);
        __fastcode_end = .;
    } >RAM AT>FLASH

    .data :
    {
        __data_load = LOADADDR (.data);
        . = ALIGN(4);
        __data_start = .;
        *(vtable)
        *(.data*)
        KEEP(*(.jcr*))
        . = ALIGN(4);
        __data_end = .;

    } > RAM AT>FLASH

    .bss :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    } > RAM

    .stacks : {
        . = ALIGN(8);
        __irq_stack_bottom__ = . ;
        . += IRQ_STACK_SIZE;
        . = ALIGN(8);
        __irq_stack_top__ = . ;

        . = ALIGN(8);
        __fiq_stack_bottom__ = . ;
        . += FIQ_STACK_SIZE;
        . = ALIGN(8);
        __fiq_stack_top__ = . ;

        . = ALIGN(8);
        __svc_stack_bottom__ = . ;
        . += SVC_STACK_SIZE;
        . = ALIGN(8);
        __svc_stack_top__ = . ;

        . = ALIGN(8);
        __abt_stack_bottom__ = . ;
        . += ABT_STACK_SIZE;
        . = ALIGN(8);
        __abt_stack_top__ = . ;

        . = ALIGN(8);
        __und_stack_bottom__ = . ;
        . += UND_STACK_SIZE;
        . = ALIGN(8);
        __und_stack_top__ = . ;

        . = ALIGN(8);
        __sys_stack_bottom__ = . ;
        . += SYS_STACK_SIZE;
        . = ALIGN(8);
        __sys_stack_top__ = . ;
    } >RAM

    .heap : {
        . = ALIGN (0x1000);
        heapstart = .;
        . += HEAPSIZE;
        heapend = .;
    } >RAM

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

Can you help with this problem?

Provide an answer of your own, or ask Vitaliy Bortsov for more information if necessary.

To post a message you must log in.