gcc - 启用GCC-Arm-None-EABI中的浮点仿真

标签 gcc cross-compiling cortex-m newlib

I am trying to figure out how should I enable soft floating point support for arm-none-eabi-gcc编译器。 The version of arm-none-eabi-gccgcc version 6.3.1 20170620 (15:6.3.1+svn253039-1build1)

I have a Makefile with following compiler and linker options:

CFLAGS   = -W -Wall -O0 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb -msoft-float
CFLAGS  += -ffunction-sections -fdata-sections -mfloat-abi=soft -u _printf_float -u _scanf_float
LDFLAGS  = -nostartfiles -specs=rdimon.specs -specs=nano.specs -lc -lrdimon -u _printf_float -u _scanf_float  

But even after compiling with these options I am not able to use floatdouble , for e.g. the code doesn't execute after, if I try to typecast double to long e.g.

long var_tempNumber_u32;
double var_floatNumber_f32;
var_tempNumber_u32 = (long)var_floatNumber_f32;  

I am using a custom linker script and as per this NXP Community Link I have added GROUP(libgcc.a libc.a libm.a)之前SECTIONS line in linker script.

I am working on LPC1768 micro-controller.

Update:

After some findings I found out that Cortex-M3 is going into Hard Fault handler, so I installed a custom hard-fault handler to get the stack trace and I found out that my firmware is crashing after returning from __aeabi_d2uiz功能。

Contents of ARM registers at the time of Hard Fault:

r0: 0x81
r1: 0x43C0
r2: 0xC000
r3: 0x1
r12: 0x0000000000
LR: 0xBB1B
PC: 0x884A  

Excerpt from the disassembly:

0000baf0 <UART_TxFloatNumber>:
    baf0:   b590        push    {r4, r7, lr}
    baf2:   b085        sub sp, #20
    baf4:   af00        add r7, sp, #0
    baf6:   e9c7 0100   strd    r0, r1, [r7]
    bafa:   205a        movs    r0, #90 ; 0x5a
    bafc:   f7fe fcc8   bl  a490 <xMBPortSerialPutByte>
    bb00:   2058        movs    r0, #88 ; 0x58
    bb02:   f7fe fcc5   bl  a490 <xMBPortSerialPutByte>
    bb06:   200d        movs    r0, #13
    bb08:   f7fe fcc2   bl  a490 <xMBPortSerialPutByte>
    bb0c:   200a        movs    r0, #10
    bb0e:   f7fe fcbf   bl  a490 <xMBPortSerialPutByte>
    bb12:   e9d7 0100   ldrd    r0, r1, [r7]
    bb16:   f7fc fce5   bl  84e4 <__aeabi_d2uiz>
    bb1a:   4603        mov r3, r0
    bb1c:   60fb        str r3, [r7, #12]
    bb1e:   21ff        movs    r1, #255    ; 0xff
    bb20:   68f8        ldr r0, [r7, #12]
    bb22:   f7ff ff5d   bl  b9e0 <UART_TxDecimalNumber>
    bb26:   202e        movs    r0, #46 ; 0x2e
    bb28:   f7ff febc   bl  b8a4 <uart3_tx_byte>
    bb2c:   68f8        ldr r0, [r7, #12]
    bb2e:   f7fc f91f   bl  7d70 <__aeabi_ui2d>
    bb32:   4603        mov r3, r0
    bb34:   460c        mov r4, r1
    bb36:   461a        mov r2, r3
    bb38:   4623        mov r3, r4
    bb3a:   e9d7 0100   ldrd    r0, r1, [r7]
    bb3e:   f7fb ff8d   bl  7a5c <__aeabi_dsub>
    bb42:   4603        mov r3, r0
    bb44:   460c        mov r4, r1
    bb46:   e9c7 3400   strd    r3, r4, [r7]
    bb4a:   a30b        add r3, pc, #44 ; (adr r3, bb78 <UART_TxFloatNumber+0x88>)
    bb4c:   e9d3 2300   ldrd    r2, r3, [r3]
    bb50:   e9d7 0100   ldrd    r0, r1, [r7]
    bb54:   f7fc f98c   bl  7e70 <__aeabi_dmul>
    bb58:   4603        mov r3, r0
    bb5a:   460c        mov r4, r1
    bb5c:   4618        mov r0, r3
    bb5e:   4621        mov r1, r4
    bb60:   f7fc fcc0   bl  84e4 <__aeabi_d2uiz>
    bb64:   4603        mov r3, r0
    bb66:   60fb        str r3, [r7, #12]
    bb68:   21ff        movs    r1, #255    ; 0xff
    bb6a:   68f8        ldr r0, [r7, #12]
    bb6c:   f7ff ff38   bl  b9e0 <UART_TxDecimalNumber>
    bb70:   bf00        nop
    bb72:   3714        adds    r7, #20
    bb74:   46bd        mov sp, r7
    bb76:   bd90        pop {r4, r7, pc}
    bb78:   00000000    andeq   r0, r0, r0
    bb7c:   412e8480    smlawbmi    lr, r0, r4, r8  

The address in Link Register is pointing to the instruction inside the above function which is after __aeabi_d2uiz library function call.
I am not that expert in assembly so I am not able to find the root cause of it.
I also tried increasing the .stackarea i.e. stack size of my application firmware without any luck.
Please anyone, let me know how to find a possible resolution of this issue.

最佳答案

经过调试和在互联网上搜索了一下,我找到了这个问题的根本原因。 问题出在链接描述文件中,没有为 ARM 堆栈展开定义任何部分。
因此,我将以下行添加到链接器脚本文件中:

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

    /*
     * Arm stack unwinding.
     * If removed may cause random crashes.
     */
    .ARM.exidx :
    {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > IROM

问题已解决。
递归函数需要堆栈展开,因为浮点到整数转换的 GCC 库函数调用是递归的,所以需要堆栈展开,而这是以前不存在的。

关于gcc - 启用GCC-Arm-None-EABI中的浮点仿真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54534700/

相关文章:

c - C 中的整数溢出 : standards and compilers

c++ - 为什么 gcc 与 clang 相比会产生这种奇怪的程序集?

c++ - CMAKE 3.4.1和VS2015编译opencv3.0 extra models时找不到include文件如何解决

ffmpeg - 交叉编译 ffmpeg 时出现警告 "i686-mingw32-pkg-config not found, library detection may fail"

c++ - 为什么 G++12 vector 插入优化会破坏代码?

c - 我需要为编译器指定一个间接使用的库吗?

linux - Cygwin GCC 交叉编译二进制文件?

为无堆的 32 位微 Controller 编译 zbar 库

gdb - 找到在 cortex-m4 上发生中断的位置

arm - STM32F103中的ADC可以采样高达3Msps吗?