4 years, 11 months ago.

FRDM KL05z hardfault when compiled with offline GCC Embedded

Hi, I'm currently working with a FRDM-KL05Z trying to run a basic Blinky. The program compiles fine online and runs correctly.

However in the interest of CMSIS debugging I'm also trying to compile with GCC ARM for Embedded. By using OpenOCD I can use GDB through CMSIS. This is working fine.

However, my Blinky immediately enters the HardFault Handler with my exported program.

This is my GNU GCC Build Log:

Build log

-------------- Build: Debug in Blinky (compiler: GNU GCC Compiler for ARM Embedded)---------------

arm-none-eabi-g++.exe -mcpu=cortex-m0plus -mthumb -Wnon-virtual-dtor -Wundef -Wunreachable-code -Wmissing-include-dirs -std=c++98 -g -mcpu=cortex-m0plus -Wall -c -g -fno-common -fmessage-length=0 -fno-exceptions -ffunction-sections -fdata-sections -fpermissive -fomit-frame-pointer -MMD -MP -Texternal\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\MKL05Z4.ld -DTARGET_KL05Z -DTARGET_M0P -DTARGET_CORTEX_M -DTARGET_Freescale -DTARGET_KLXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0PLUS -DARM_MATH_CM0PLUS -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -Iexternal\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX\TARGET_KL05Z -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale -I.\external\mbed\TARGET_KL05Z -I.\external\mbed -I.\external -Iinclude -c external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\startup_MKL05Z4.s -o obj\Debug\external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\startup_MKL05Z4.o
arm-none-eabi-g++.exe -mcpu=cortex-m0plus -mthumb -Wnon-virtual-dtor -Wundef -Wunreachable-code -Wmissing-include-dirs -std=c++98 -g -mcpu=cortex-m0plus -Wall -c -g -fno-common -fmessage-length=0 -fno-exceptions -ffunction-sections -fdata-sections -fpermissive -fomit-frame-pointer -MMD -MP -Texternal\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\MKL05Z4.ld -DTARGET_KL05Z -DTARGET_M0P -DTARGET_CORTEX_M -DTARGET_Freescale -DTARGET_KLXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0PLUS -DARM_MATH_CM0PLUS -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -Iexternal\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX\TARGET_KL05Z -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale -I.\external\mbed\TARGET_KL05Z -I.\external\mbed -I.\external -Iinclude -c main.cpp -o obj\Debug\main.o
In file included from .\external\mbed/Serial.h:24:0,
                 from .\external\mbed/mbed.h:44,
                 from main.cpp:1:
.\external\mbed/SerialBase.h:110:5: warning: "DEVICE_SERIAL_FC" is not defined [-Wundef]
 #if DEVICE_SERIAL_FC
     ^
arm-none-eabi-g++.exe -mcpu=cortex-m0plus -mthumb -Wnon-virtual-dtor -Wundef -Wunreachable-code -Wmissing-include-dirs -std=c++98 -g -mcpu=cortex-m0plus -Wall -c -g -fno-common -fmessage-length=0 -fno-exceptions -ffunction-sections -fdata-sections -fpermissive -fomit-frame-pointer -MMD -MP -Texternal\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\MKL05Z4.ld -DTARGET_KL05Z -DTARGET_M0P -DTARGET_CORTEX_M -DTARGET_Freescale -DTARGET_KLXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0PLUS -DARM_MATH_CM0PLUS -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -Iexternal\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX\TARGET_KL05Z -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale -I.\external\mbed\TARGET_KL05Z -I.\external\mbed -I.\external -Iinclude
In file included from .\external\mbed/Serial.h:24:0,
                 from .\external\mbed/mbed.h:44,
.\external\mbed/SerialBase.h:110:5: warning: "DEVICE_SERIAL_FC" is not defined [-Wundef]
 #if DEVICE_SERIAL_FC
     ^
arm-none-eabi-gcc.exe -mcpu=cortex-m0plus -mthumb -Wundef -Wunreachable-code -Wmissing-include-dirs -g -mcpu=cortex-m0plus -Wall -c -g -fno-common -fmessage-length=0 -fno-exceptions -ffunction-sections -fdata-sections -fomit-frame-pointer -MMD -MP -Texternal\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\MKL05Z4.ld -DTARGET_KL05Z -DTARGET_M0P -DTARGET_CORTEX_M -DTARGET_Freescale -DTARGET_KLXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0PLUS -DARM_MATH_CM0PLUS -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -Iexternal\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX\TARGET_KL05Z -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_KLXX -I.\external\mbed\TARGET_KL05Z\TARGET_Freescale -I.\external\mbed\TARGET_KL05Z -I.\external\mbed -I.\external -Iinclude -c system_MKL05Z4.c -o obj\Debug\system_MKL05Z4.o
arm-none-eabi-gcc.exe -L.\external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM -Lexternal\mbed\TARGET_KL05Z\TARGET_Freescale\TARGET_LPC176X\TARGET_KLXX -Lexternal -o bin\Debug\Blinky.elf obj\Debug\external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\startup_MKL05Z4.o obj\Debug\main.o obj\Debug\system_MKL05Z4.o external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\board.o external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\cmsis_nvic.o external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\mbed_overrides.o external\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\retarget.o  -mcpu=cortex-m0plus -mthumb -Texternal\mbed\TARGET_KL05Z\TOOLCHAIN_GCC_ARM\MKL05Z4.ld -Wl,--gc-sections --specs=nano.specs -Wl,-Map=Blinky.map,--cref -mcpu=cortex-m0plus -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys 
Output file is bin\Debug\Blinky.elf with size 107.23 KB

After much searching (see comments below) I believe this might be a bug in the compiled mbed library version. When running with the debugger attached a basic Blinking Led program with a UART printf causes a hardfault handler to be called when performing the flush operation.

Here is the call stack after hitting the hard fault:

Note: automatically using hardware breakpoints for read-only addresses.

  1. 0 0x00000bea0x20000ad0 in HardFault_Handler ()
  2. 1 <signal handler called>
  3. 2 0x000017d40x20000b00 in _fflush_r ()
  4. 3 0x000018340x20000b08 in fflush ()
  5. 4 0x0000261c0x20000b28 in mbed::Stream::printf(char const*, ...) ()
  6. 5 0x000006340x20000b38 in main () at main.cpp:152

Somehow this issue seems to be related to the wait_ms/wait instruction. When blinking the led and putting a message uart without wait the program keeps running. When inserting a wait instruction the program stops after one or two iterations.

posted by K. N. L. V. 21 Dec 2014

When the UART crashes the following is the disassembly:

Note: automatically using hardware breakpoints for read-only addresses.

  1. 0 0x00000bea0x20000ad0 in HardFault_Handler ()
  2. 1 <signal handler called>
  3. 2 0x000017d40x20000b00 in _fflush_r ()
  4. 3 0x000018340x20000b08 in fflush ()
  5. 4 0x0000261c0x20000b28 in mbed::Stream::printf(char const*, ...) ()
  6. 5 0x000006340x20000b38 in main () at main.cpp:152
posted by K. N. L. V. 21 Dec 2014

Looks ot me you are using own makefile? Try to use mbed sources. if you suspect the bug in the compiled mbed library

posted by Martin Kojtal 22 Dec 2014

The above is not from a custom makefile but from my IDE (Code::Blocks). However, even with several makefiles (exported from the online compiler) such as the "Export EmBlocks" option and the "Export to GCC ARM" option and the makefile from the following source:

https://github.com/0xc0170/mbed_gcc_makefile

I have the same issue. The makefile exported from the online compiler (GCC ARM) option even needs some tweaking since I have to remove the -uprintf_float option for it to compile correctly for the kl05z.

I will try comparing each of those makefiles again and see if all enter the hardfault handler at the same location.

posted by K. N. L. V. 22 Dec 2014

Quick confirmation:

https://github.com/0xc0170/mbed_gcc_makefile > Fails with callstack:

HardFault_Handler <signal handler called> _fflush_r fflush mbed::Stream::puts(char const*)

Make file exported from online compiler using GCC ARM as export target fails with:

HardFault_Handler <signal handler called> _fflush_r fflush mbed::Stream::puts(char const*)

Question now is how do I verify the source? Is it useful to try another version of the compiler? I'm currently on the latest 4.9

posted by K. N. L. V. 22 Dec 2014

Just tested the https://github.com/0xc0170/mbed_gcc_makefile with a kl25z board I also have lying around. The same Blinking Led + uart works fine on this target.

posted by K. N. L. V. 22 Dec 2014
Comment on this question

1 Answer

4 years, 11 months ago.

In your MKL05Z4.ld linker script trying changing:

  RAM (rwx) : ORIGIN = 0x1FFFFC00, LENGTH = 4K - 0xC0

to

  RAM (rwx) : ORIGIN = 0x1FFFFCC0, LENGTH = 4K - 0xC0

It looks like there is probably a bug in the GCC linker script for this target which would have global variables and the in-RAM vector table colliding with one another. The change above should correct that.

Correct! I tested this with the mbed-src for this target and the basic blinking led + uart (rx interrupt driven) is working fine now. I highly appreciate the fix. Hopefully this can be commited to the repo for a next release

posted by K. N. L. V. 23 Dec 2014

I am happy to hear that it corrected your problem. I have submitted a pull request with this small update.

posted by Adam Green 24 Dec 2014