cancel
Showing results for 
Search instead for 
Did you mean: 

hard fault when calling standard library

joneyvindur
Associate II
Posted on July 12, 2012 at 02:23

Using stm32f4 discovery

I am off to a good start with this board. 

I can not do floating point numbers. 

That is annoying but ok. I decided to move on and not use floating point numbers. 

When I try to fixed point I don't seem to be able to do long division. 

Now I am going to try to go back and see if I can fix this. 

I stripped this down to the simplest program that creates the problem.

int main(void)

{

volatile int64_t x=0x12121212;

x = x/1000;

return 0;

}

Debugger stepping through:

0x8000340 <main+24>     blx    0x8000354 <__aeabi_ldivmod> 

0x8000e9c <WWDG_IRQHandler>     b.n    0x8000e9c <WWDG_IRQHandler>

I believe 

__aeabi_ldivmod comes from libgcc.a.  

(originally the fault interrupt was hardfault handler, but after I simplified the code it appears as WWDG_IRQHandler.)

$arm-none-eabi-nm -s:

08000354 T __aeabi_ldivmod

compiler:

~/sat/bin/arm-none-eabi-gcc -O3  -g -Wall -Werror  -mcpu=cortex-m4 -mthumb -mthumb-interwork -I/Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Project/Peripheral_Examples/hardfault -I/Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Libraries/CMSIS/Include -I/Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Libraries/CMSIS/ST/STM32F4xx/Include -I/Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I/Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Utilities/STM32F4-Discovery -DSTM32F4XX -DUSE_STDPERIPH_DRIVER   -c -o stm32f4_discovery.o /Users//Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Utilities/STM32F4-Discovery/stm32f4_discovery.c

linker command:

~/sat/bin/arm-none-eabi-gcc -v -g -o ADC_simple.elf -O3  -g -Wall -Werror  -fno-exceptions -fdata-sections -nostartfiles -Wl,--gc-sections,-T/Users/Me/Dropbox/Code/stm32f4/STM32F4-Discovery_FW_V1.1.0/Project/Peripheral_Examples/hardfault/stm32_flash.ld system_stm32f4xx.o main.o stm32f4_discovery.o startup_stm32f4xx.o

compiler details:

Target: arm-none-eabi

Configured with: ../gcc-linaro-4.5-2011.02-0/configure --target=arm-none-eabi --prefix=/Users//sat --enable-interwork --enable-multilib --enable-languages=c,c++ --with-newlib --with-gnu-as --with-gnu-ld --disable-nls --disable-shared --disable-threads --with-headers=newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp --disable-werror --with-system-zlib --disable-newlib-supplied-syscalls --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-libiconv-prefix=/opt/local

Thread model: single

gcc version 4.5.2 (Linaro GCC 4.5-2011.02-0)

I have seen a post here or elsewhere saying that there are two possibilities:

1) stm32f4 only supports thumb code. 

2) the jump is outside the section. 

I take that to be true, but I don't know how to use that info to fix the problem. 

Any suggestions?

#stm32f4-hardfault-blx
4 REPLIES 4
Posted on July 12, 2012 at 02:54

Probably linking against an ARM library, a quick disassembly or review of the MAP file should tell you that.

The FPU must be enabled, used to do that in startup.s but may be migrated to SystemInit() now. 4.6.2 or 4.7.1 should be able to generate instructions. Other potential causes of hard fault are reading/writing addresses not decoded by core or peripherals. The linker should take the '

-mcpu=cortex-m4 -mthumb

' options too.

void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
frankmeyer9
Associate II
Posted on July 12, 2012 at 08:11

1) stm32f4 only supports thumb code. 

That is correct, the Cortex M only supports thumb instructions.

The summon arm toolchain is certainly capable to generate working floating point code.

However, you have to change the make file manually. You need both to compile your code with the correct abi version (''-mfloat-abi=soft | softfp | hard''), and select the correct library version in the linker settings. It took me also some time to figure this out.

I have no idea how you end up in the WWDG interrupt handler. There seems something basically wrong. The 

__aeabi_ldivmod

function usually comes from libgcc.a.

Could you have linked against a library containing ARM code, and not THUMB code ?

Posted on July 12, 2012 at 18:44

I have no idea how you end up in the WWDG interrupt handler.

The dead-end interrupt handlers end up in the same infinite loop code, symbolically the WWDG is the last one listed. This is the same as the hard faulting address.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
joneyvindur
Associate II
Posted on July 13, 2012 at 00:07

That was it,

in my Makefile, LDFLAGS did not include MCUFLAGS but CFLAGS did. 

(MCUFLAGS=-mcpu=cortex-m4 -mthumb -mthumb-interwork)

Thanks for the help.