floating point operations cause unaligned usage fault

Asked by Jürgen Funck

Hello everybody,

I'm experiencing problems when using floating point operations on a cortex m3 processor (STM32F105 to be precise).

Debugging with the gdb tells me that a hard fault is generated inside the routine __mulsf3 which seems to be a part of the gcc soft floating point library. Here is the complete output from the gdb.

(gdb) info frame
Stack level 0, frame at 0x20004fc8:
 pc = 0x80010a8 in HardFault_Handler (stm32f10x_it.c:61); saved pc 0xfffffff9
 called by frame at 0x20004fe8
 source language c.
 Arglist at 0x20004fc8, args:
 Locals at 0x20004fc8, Previous frame's sp is 0x20004fc8
(gdb) info frame 0x20004fe8
Stack frame at 0x20004fe8:
 pc = 0x800110c in __mulsf3 (../../../gcc-4.5.1/libgcc/../gcc/config/arm/ieee754-sf.S:452); saved pc 0x8000164
 called by frame at 0x20005000, caller of frame at 0x20004fe8
 source language asm.
 Arglist at 0x20004fe8, args:
 Locals at 0x20004fe8, Previous frame's sp is 0x20004fe8

Examining the fautl status register of the cortex m3 tells me that the cause is "Unaligned access UsageFault":
Here is the complete output for the UsageFault status register:

(gdb) x /ht 0xe000ed2a
0xe000ed2a: 0000000100000000

Does anybody have an idea why this is happening? Is this likely to be a bug in the gcc or a related library, or is something going wrong during compilation of the program?

Here is the example program I'm using:

int main(void)
{
  volatile uint32_t i;
  volatile float x,y;

  /* GPIOC Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  /* Configure PC12 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  while (1)
  {
    /* Set PC12 */
    GPIOC->BSRR = 1 << 1;

    x = 2.5;
    y = 0.2;

    i = 1000000;
    while(--i);

    /* Reset PC12 */
    GPIOC->BRR = 1 << 1;

    y = y*x;

    i = 2000000;
    while(--i);
  }
}

This the output during compilation:
$ make
.compiling
arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0 -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/main.o main.c
arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0 -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/system_stm32f10x.o system_stm32f10x.c
arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0 -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/stm32f10x_it.o stm32f10x_it.c
.compiling libraries
arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0 -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/stm32f10x_gpio.o ./lib/src/stm32f10x_gpio.c
arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0 -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/stm32f10x_rcc.o ./lib/src/stm32f10x_rcc.c
..linking
arm-none-eabi-ld -g -v -nostartfiles -Map ./main.map -T./lib/stm32_flash.ld -o ./main.out obj/main.o obj/system_stm32f10x.o obj/stm32f10x_gpio.o obj/stm32f10x_rcc.o obj/stm32f10x_it.o obj/startup_stm32f10x_md.o libgcc.a
GNU ld (GNU Tools for ARM Embedded Processors) 2.23.2.20131129
arm-none-eabi-objcopy -O binary ./main.out ./main.bin
arm-none-eabi-objdump -x --syms -S ./main.out > ./main.list
...completed.

Regards,

Jürgen

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Joey Ye
Solved:
Last query:
Last reply:
Revision history for this message
Best Joey Ye (jinyun-ye) said :
#1

Jurgen, your linker command line is incorrect. Please use arm-none-eabi-gcc
as linker and give -mthumb -mcpu=cortex-m3 as command line.

More details please follow readme or samples.

Thanks
Joey
On Jan 13, 2014 11:58 PM, "Jürgen Funck" <
<email address hidden>> wrote:

> New question #242149 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/242149
>
> Hello everybody,
>
> I'm experiencing problems when using floating point operations on a cortex
> m3 processor (STM32F105 to be precise).
>
> Debugging with the gdb tells me that a hard fault is generated inside the
> routine __mulsf3 which seems to be a part of the gcc soft floating point
> library. Here is the complete output from the gdb.
>
> (gdb) info frame
> Stack level 0, frame at 0x20004fc8:
> pc = 0x80010a8 in HardFault_Handler (stm32f10x_it.c:61); saved pc
> 0xfffffff9
> called by frame at 0x20004fe8
> source language c.
> Arglist at 0x20004fc8, args:
> Locals at 0x20004fc8, Previous frame's sp is 0x20004fc8
> (gdb) info frame 0x20004fe8
> Stack frame at 0x20004fe8:
> pc = 0x800110c in __mulsf3
> (../../../gcc-4.5.1/libgcc/../gcc/config/arm/ieee754-sf.S:452); saved pc
> 0x8000164
> called by frame at 0x20005000, caller of frame at 0x20004fe8
> source language asm.
> Arglist at 0x20004fe8, args:
> Locals at 0x20004fe8, Previous frame's sp is 0x20004fe8
>
> Examining the fautl status register of the cortex m3 tells me that the
> cause is "Unaligned access UsageFault":
> Here is the complete output for the UsageFault status register:
>
> (gdb) x /ht 0xe000ed2a
> 0xe000ed2a: 0000000100000000
>
> Does anybody have an idea why this is happening? Is this likely to be a
> bug in the gcc or a related library, or is something going wrong during
> compilation of the program?
>
> Here is the example program I'm using:
>
> int main(void)
> {
> volatile uint32_t i;
> volatile float x,y;
>
> /* GPIOC Periph clock enable */
> RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
>
> /* Configure PC12 in output pushpull mode */
> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
> GPIO_Init(GPIOC, &GPIO_InitStructure);
>
> while (1)
> {
> /* Set PC12 */
> GPIOC->BSRR = 1 << 1;
>
> x = 2.5;
> y = 0.2;
>
> i = 1000000;
> while(--i);
>
> /* Reset PC12 */
> GPIOC->BRR = 1 << 1;
>
> y = y*x;
>
> i = 2000000;
> while(--i);
> }
> }
>
> This the output during compilation:
> $ make
> .compiling
> arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0
> -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o obj/main.o
> main.c
> arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0
> -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o
> obj/system_stm32f10x.o system_stm32f10x.c
> arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0
> -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o
> obj/stm32f10x_it.o stm32f10x_it.c
> .compiling libraries
> arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0
> -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o
> obj/stm32f10x_gpio.o ./lib/src/stm32f10x_gpio.c
> arm-none-eabi-gcc -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb -g -O0
> -I./ -I./lib/ -I./lib/inc/ -I./lib/inc/../../ -DTRACE_LEVEL=4 -o
> obj/stm32f10x_rcc.o ./lib/src/stm32f10x_rcc.c
> ..linking
> arm-none-eabi-ld -g -v -nostartfiles -Map ./main.map
> -T./lib/stm32_flash.ld -o ./main.out obj/main.o obj/system_stm32f10x.o
> obj/stm32f10x_gpio.o obj/stm32f10x_rcc.o obj/stm32f10x_it.o
> obj/startup_stm32f10x_md.o libgcc.a
> GNU ld (GNU Tools for ARM Embedded Processors) 2.23.2.20131129
> arm-none-eabi-objcopy -O binary ./main.out ./main.bin
> arm-none-eabi-objdump -x --syms -S ./main.out > ./main.list
> ...completed.
>
> Regards,
>
> Jürgen
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Jürgen Funck (juergen-funck) said :
#2

Thank you

After correcting the linker command line every thing is just working fine

Regards,

Jürgen

Revision history for this message
Jürgen Funck (juergen-funck) said :
#3

Thanks Joey Ye, that solved my question.

Revision history for this message
Thomas_Z (th-zoechbauer) said :
#4

Hello,

I have a similar problem that leads to a hard fault when I compile and link with "-mfloat-abi=softfp -mfpu=fpv4-sp-d16" (arm-none-eabi-g++.exe is used for both).

The following code leads to a fault:
-------------------------------------------------
int main()
{
    double d = 1.0;
    d += 2; // ok!

    float f = 1.0;
    f += 2.0; // this leads to a hard fault!

    while(1) { }
}
-------------------------------------------------
When I use double everything is fine. But when I try to add a value to a float variable the hard fault occurs.
If I leave "-mfloat-abi=softfp -mfpu=fpv4-sp-d16" it works fine too. But leaving this options means not using softfp.
Using hardfp ("-mfloat-abi=hard -mfpu=fpv4-sp-d16") also leads to a hard fault.

That's my build-log using hardfp:

/* compiling: */
arm-none-eabi-g++.exe -mcpu=cortex-m4 -mthumb -march=armv7e-m -fno-strict-aliasing -std=c++1y -Wall -fdata-sections -ffunction-sections -O0 -g -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c src\crt0.cpp -o obj\debug\src\crt0.o -MMD -I.\src
arm-none-eabi-g++.exe -mcpu=cortex-m4 -mthumb -march=armv7e-m -fno-strict-aliasing -std=c++1y -Wall -fdata-sections -ffunction-sections -O0 -g -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c src\crt0_init_ram.cpp -o obj\debug\src\crt0_init_ram.o -MMD -I.\src
arm-none-eabi-g++.exe -mcpu=cortex-m4 -mthumb -march=armv7e-m -fno-strict-aliasing -std=c++1y -Wall -fdata-sections -ffunction-sections -O0 -g -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c src\crt1.cpp -o obj\debug\src\crt1.o -MMD -I.\src
arm-none-eabi-g++.exe -mcpu=cortex-m4 -mthumb -march=armv7e-m -fno-strict-aliasing -std=c++1y -Wall -fdata-sections -ffunction-sections -O0 -g -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c src\int_vect.cpp -o obj\debug\src\int_vect.o -MMD -I.\src
arm-none-eabi-g++.exe -mcpu=cortex-m4 -mthumb -march=armv7e-m -fno-strict-aliasing -std=c++1y -Wall -fdata-sections -ffunction-sections -O0 -g -mfloat-abi=hard -mfpu=fpv4-sp-d16 -c src\main.cpp -o obj\debug\src\main.o -MMD -I.\src

/* linking: */
arm-none-eabi-g++.exe -mcpu=cortex-m4 -Wl,-script="./linkerscript.ld" -o bin\Debug\UnderstandTheLinker.elf obj\debug\src\crt0.o obj\debug\src\crt0_init_ram.o obj\debug\src\crt1.o obj\debug\src\int_vect.o obj\debug\src\main.o -Wl,-Map=bin\Debug\UnderstandTheLinker.map --specs=nano.specs -mthumb -nostartfiles --specs=nosys.specs -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16

Best regards,
Thomas