在gcc-arm-none-eabi

时间:2019-02-05 12:42:10

标签: gcc cross-compiling cortex-m3 newlib

我试图弄清楚如何为arm-none-eabi-gcc编译器启用软浮点支持。 arm-none-eabi-gcc的版本为gcc version 6.3.1 20170620 (15:6.3.1+svn253039-1build1)

我有一个带有以下编译器和链接器选项的Makefile:

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  

但是即使使用这些选项编译后,我也无法使用floatdouble,例如如果我尝试将doubletype转换为long例如,代码将不会执行。

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

我正在使用自定义链接描述文件,根据此NXP Community Link,我在链接描述文件的GROUP(libgcc.a libc.a libm.a)行之前添加了SECTIONS

我正在研究LPC1768微控制器。

更新:

经过一些发现,我发现Cortex-M3即将进入Hard Fault处理程序,因此我安装了一个自定义的Hard-fault处理程序以获取堆栈跟踪,并且发现从{{1}返回后,我的固件崩溃了。 }函数。

硬故障时ARM寄存器的内容:

__aeabi_d2uiz

反汇编摘录:

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

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 库函数调用之后,链接寄存器中的地址指向上述函数中的指令。
我不是那个组装专家,所以找不到根本原因。 我也尝试增加__aeabi_d2uiz,即我的应用程序固件的堆栈大小没有任何运气。
请任何人,让我知道如何找到此问题的可能解决方案。

1 个答案:

答案 0 :(得分:0)

在调试并在Internet上进行了一些搜索之后,我发现了此问题的根本原因。 问题出在链接脚本文件中,没有为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库函数对float到int的转换是递归的,因此需要堆栈展开,而以前没有。