All Projects → ferenc-nemeth → arm-hard-fault-handler

ferenc-nemeth / arm-hard-fault-handler

Licence: MIT license
What to do when Hard fault hits? Debugger and error reporter solution for ARM Cortex M3 and M4.

Programming Languages

c
50402 projects - #5 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to arm-hard-fault-handler

Bugsnag Node
[DEPRECATED] Please upgrade to our Universal JS notifier "@bugsnag/js" • https://github.com/bugsnag/bugsnag-js
Stars: ✭ 48 (+50%)
Mutual labels:  error, debug, debugging-tool
Bugsnag Go
Automatic panic monitoring for Go and Go web frameworks, like negroni, gin, and revel
Stars: ✭ 155 (+384.38%)
Mutual labels:  error, debug, debugging-tool
STM32-Bare-Metal
STM32F103C8 bare metal template
Stars: ✭ 26 (-18.75%)
Mutual labels:  stm32, arm-cortex-m3, arm-cortex
Pyocd
Open source Python library for programming and debugging Arm Cortex-M microcontrollers
Stars: ✭ 550 (+1618.75%)
Mutual labels:  arm, debug
Probe Rs
A debugging toolset and library for debugging embedded ARM and RISC-V targets on a separate host
Stars: ✭ 435 (+1259.38%)
Mutual labels:  arm, debug
Avem
🚁 轻量级无人机飞控-[Drone]-[STM32]-[PID]-[BLDC]
Stars: ✭ 465 (+1353.13%)
Mutual labels:  arm, stm32
how-to-qemu-arm-gdb-gtest
How to run, debug, and unit test ARM code on X86 ubuntu
Stars: ✭ 19 (-40.62%)
Mutual labels:  arm, debug
Stm32l4xx Hal
A Hardware abstraction layer for the stm32l432xx series chips written in rust.
Stars: ✭ 65 (+103.13%)
Mutual labels:  arm, stm32
Stm32liquidcrystal
Liquid Crystal Library for STM32
Stars: ✭ 24 (-25%)
Mutual labels:  arm, stm32
Daplink
Stars: ✭ 1,162 (+3531.25%)
Mutual labels:  arm, debug
Stm32 graphics display drivers
STM32 LCD drivers (currently: spi(dma), gpio, fsmc(dma), st7735, st7783, ili9325, ili9328, ili9341, ili9486, ili9488, hx8347g)
Stars: ✭ 151 (+371.88%)
Mutual labels:  arm, stm32
kconfig
Kconfig for ARM based MCUs
Stars: ✭ 15 (-53.12%)
Mutual labels:  arm, stm32
async-stm32f1xx
Abstractions for asynchronous programming on the STM32F1xx family of microcontrollers.
Stars: ✭ 24 (-25%)
Mutual labels:  arm, stm32
Platformio Core
PlatformIO is a professional collaborative platform for embedded development 👽 A place where Developers and Teams have true Freedom! No more vendor lock-in!
Stars: ✭ 5,539 (+17209.38%)
Mutual labels:  arm, debug
toolchain68k
build a toolchain for cross developement. Supports motorola m68k-elf, avr and arm-none-eabi
Stars: ✭ 18 (-43.75%)
Mutual labels:  arm, stm32
Tinygo
Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
Stars: ✭ 9,068 (+28237.5%)
Mutual labels:  arm, stm32
Arm Cmake Toolchains
CMake toolchain configurations for ARM
Stars: ✭ 148 (+362.5%)
Mutual labels:  arm, stm32
Xpcc
DEPRECATED, use our successor library https://modm.io instead
Stars: ✭ 177 (+453.13%)
Mutual labels:  arm, stm32
Dirtyjtag
JTAG probe firmware for STM32F1
Stars: ✭ 183 (+471.88%)
Mutual labels:  arm, stm32
CML
Fast, safe and easy to use Cortex-M HAL Library, written in C++ 17
Stars: ✭ 17 (-46.87%)
Mutual labels:  arm, stm32

arm-hard-fault-handler

What to do when Hard fault hits? Debugger and error reporter solution for ARM Cortex M3 and M4.

Table of Contents

Introduction

Lot of people have no idea what to do when a Hard fault hits. I even met well-experienced, senior developers, who were like, "yeah Hard fault, what now". ARM provides us with some useful features and registers to help us in this case.
With this code, I would like demonstrate how it works on ARM Cortex-M3 and Cortex-M4. The main idea comes from the book "The definitive guide to ARM Cortex-M3 and Cortex-M4 processors" by Joseph Yiu [1], altough my version gives more details of the fault.

How it works

In case of a Hard Fault, my software writes out (through SWO trace interface) the stack frame registers, the Hard fault registers, and a short error report regarding the problem itself.
The files I created are in Src and Inc folders. Src holds the source codes, Inc holds the headers. The main() function is inside main.c, it has the line of code, that makes the Hard fault. The fault is simple: I try to write to a memory location (External Devices), where otherwise I am not supposed to. The Communication.c and Communication.h hold the function, that are necessary for the printf() trace feature. The FaultHandler.c and FaultHandler.h are where the real magic happens. There are two functions: HardFault_Handler() is the function where we get in case of a fault by default. It is provided by CMSIS. It contains an Assembly code, what determines which SP was used (MSP or PSP) with the help of LR.
After that, it passes the address of SP and value of LR to my function: ReportHardFault(). This function reads and then prints out the stack frame and the fault related registers with detailed information about the problem itself.
The registers are:

  • R0
  • R1
  • R2
  • R3
  • R12
  • Link Register
  • Program Counter
  • Program Status Register
  • Hard Fault Status Register
  • Configurable Fault Status Register
  • Memory Manage Address Register
  • Bus Fault Address Register
  • Auxiliary Fault Status Register
  • Exception Return

The exact description of these register are in the datasheet or on ARM's website. [2][3]
Finally, the program ends with a breakpoint and with a while(1) loop.

Figure 1. The Activity diagram of the software.

About the demo

As I mentioned, in the main function I try to force a (Bus) fault, with writing to the "External Devices" memory location. You can see the result from the included port window and you can verify the register values with the included disassembly code.

The output of the Bus fault:

!!!Hard Fault detected!!!

Stack frame:
R0 :        0x20000000
R1 :        0x00000000
R2 :        0x01234567
R3 :        0xAAAAAAAA
R12:        0xFB775B7C
LR :        0x0800051B
PC :        0x080004DC
PSR:        0x61000000

Fault status:
HFSR:       0x40000000
CFSR:       0x00000400
MMAR:       0xE000ED34
BFAR:       0xE000ED38
AFSR:       0x00000000

Other:
EXC_RETURN: 0xFFFFFFF9

Details of the fault status:
Hard fault status:
 - Forced Hard fault.
MemManage fault status:
 - MMAR holds an invalid address.
Bus fault status:
 - BFAR holds an invalid address.
 - Data bus error has occurred, but the return address in the stack is not related to the fault.
Usage fault status:

The disassembly code of the Bus fault:

  (*((volatile uint32_t *)(0xAAAAAAAA))) = 0x1234567;
 80004d4:	f04f 33aa 	mov.w	r3, #2863311530	; 0xaaaaaaaa
 80004d8:	4a01      	ldr	r2, [pc, #4]	; (80004e0 <main+0xc>)
 80004da:	601a      	str	r2, [r3, #0]
 80004dc:	e7fe      	b.n	80004dc <main+0x8>

I tried a second problem (not included): div-by-zero. I tried to div 0x0000FEC0 by 0x00000000. See the included port window and the disassembly code for the result.

The output of the Usage fault:

!!!Hard Fault detected!!!

Stack frame:
R0 :        0x20000000
R1 :        0x00000000
R2 :        0x00000000
R3 :        0x0000FEC0
R12:        0xFB775B7C
LR :        0x08000533
PC :        0x080004EE
PSR:        0x61000000

Fault status:
HFSR:       0x40000000
CFSR:       0x02000000
MMAR:       0xE000ED34
BFAR:       0xE000ED38
AFSR:       0x00000000

Other:
EXC_RETURN: 0xFFFFFFF9

Details of the fault status:
Hard fault status:
 - Forced Hard fault.
MemManage fault status:
 - MMAR holds an invalid address.
Bus fault status:
 - BFAR holds an invalid address.
Usage fault status:
 - The processor has executed an SDIV or UDIV instruction with a divisor of 0.

The disassembly code of the Usage fault:

  volatile int a = 0xFEC0;
 80004e0:	f64f 63c0 	movw	r3, #65216	; 0xfec0
 80004e4:	9301      	str	r3, [sp, #4]
  volatile int b = 0x0000;
 80004e6:	2300      	movs	r3, #0
 80004e8:	9302      	str	r3, [sp, #8]
  volatile int c = a/b;
 80004ea:	9b01      	ldr	r3, [sp, #4]
 80004ec:	9a02      	ldr	r2, [sp, #8]
 80004ee:	fb93 f3f2 	sdiv	r3, r3, r2

Porting

I created this software with Atollic TrueSTUDIO and used an STM32VLDISCOVERY board with STM32F100RB microcontroller. If you have them, you can try it out immediately.
The code inside the FaultHandler.c and FaultHandler.h should work on every ARM Cortex-M3 and Cortex-M4 systems. In theory it can be easily ported to M4F, I included the lazy stacking related problems, but I did not include the floating-point registers (S0-S15, FPSCR). About Cortex M0 and M0+... it's a different story.

References

[1] Joseph Yiu: The definitive guide to ARM Cortex-M3 and Cortex-M4 processors; 3rd Edition; ISBN: 9780124080829; 2013
[2] ARM Cortex-M3 Processor Technical Reference Manual
[3] ARM Cortex-M4 Processor Technical Reference Manual

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].