在 gcc-arm-none-eabi 中启用浮点仿真
Enabling floating point emulation in gcc-arm-none-eabi
我想知道如何为 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
但即使在使用这些选项进行编译后,我也无法使用 float
或 double
,例如如果我尝试将 double 类型转换为 long,则代码不会在之后执行,例如
long var_tempNumber_u32;
double var_floatNumber_f32;
var_tempNumber_u32 = (long)var_floatNumber_f32;
我正在使用自定义链接描述文件,并且根据此 NXP Community Link 我在链接描述文件的 SECTIONS
行之前添加了 GROUP(libgcc.a libc.a libm.a)
。
我正在研究 LPC1768 微控制器。
更新:
经过一些调查,我发现 Cortex-M3 正在进入硬故障处理程序,所以我安装了一个自定义的硬故障处理程序来获取堆栈跟踪,我发现我的固件在从 [= 返回后崩溃了22=] 函数。
发生硬故障时 ARM 寄存器的内容:
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
Link寄存器中的地址指向上述函数中__aeabi_d2uiz
库函数调用后的指令。
我不是汇编方面的专家,所以我无法找到它的根本原因。
我还尝试增加 .stackarea
,即我的应用程序固件的堆栈大小,但没有任何运气。
请任何人告诉我如何找到可能解决此问题的方法。
在网上调试和搜索后,我找到了这个问题的根本原因。
问题出在链接描述文件中,没有为 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 的转换是递归的,因此需要堆栈展开,这在以前是不存在的。
我想知道如何为 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
但即使在使用这些选项进行编译后,我也无法使用 float
或 double
,例如如果我尝试将 double 类型转换为 long,则代码不会在之后执行,例如
long var_tempNumber_u32;
double var_floatNumber_f32;
var_tempNumber_u32 = (long)var_floatNumber_f32;
我正在使用自定义链接描述文件,并且根据此 NXP Community Link 我在链接描述文件的 SECTIONS
行之前添加了 GROUP(libgcc.a libc.a libm.a)
。
我正在研究 LPC1768 微控制器。
更新:
经过一些调查,我发现 Cortex-M3 正在进入硬故障处理程序,所以我安装了一个自定义的硬故障处理程序来获取堆栈跟踪,我发现我的固件在从 [= 返回后崩溃了22=] 函数。
发生硬故障时 ARM 寄存器的内容:
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
Link寄存器中的地址指向上述函数中__aeabi_d2uiz
库函数调用后的指令。
我不是汇编方面的专家,所以我无法找到它的根本原因。
我还尝试增加 .stackarea
,即我的应用程序固件的堆栈大小,但没有任何运气。
请任何人告诉我如何找到可能解决此问题的方法。
在网上调试和搜索后,我找到了这个问题的根本原因。
问题出在链接描述文件中,没有为 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 的转换是递归的,因此需要堆栈展开,这在以前是不存在的。