Files
MSE-SoftwEng/pico-sensor/McuLib/src/McuHardFault.c
2025-05-06 13:07:01 +00:00

245 lines
13 KiB
C

/* ###################################################################
** This component module is generated by Processor Expert. Do not modify it.
** Filename : McuHardFault.h
** Project : FRDM-K64F_Generator
** Processor : MK64FN1M0VLL12
** Component : HardFault
** Version : Component 01.024, Driver 01.00, CPU db: 3.00.000
** Compiler : GNU C Compiler
** Date/Time : 2022-07-19, 17:00, # CodeGen: 782
** Abstract :
** Component to simplify hard faults for ARM (Kinetis, S32K).
** Settings :
** Component name : McuHardFault
** Contents :
** HardFaultHandler - void McuHardFault_HardFaultHandler(void);
** Deinit - void McuHardFault_Deinit(void);
** Init - void McuHardFault_Init(void);
**
** * Copyright (c) 2014-2022, Erich Styger
** * Web: https://mcuoneclipse.com
** * SourceForge: https://sourceforge.net/projects/mcuoneclipse
** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx
** * All rights reserved.
** *
** * Redistribution and use in source and binary forms, with or without modification,
** * are permitted provided that the following conditions are met:
** *
** * - Redistributions of source code must retain the above copyright notice, this list
** * of conditions and the following disclaimer.
** *
** * - Redistributions in binary form must reproduce the above copyright notice, this
** * list of conditions and the following disclaimer in the documentation and/or
** * other materials provided with the distribution.
** *
** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
** ###################################################################*/
/*!
** @file McuHardFault.h
** @version 01.00
** @brief
** Component to simplify hard faults for ARM (Kinetis, S32K).
*/
/*!
** @addtogroup McuHardFault_module McuHardFault module documentation
** @{
*/
/* MODULE McuHardFault. */
#include "McuHardFault.h"
#if McuLib_CONFIG_CPU_IS_ARM_CORTEX_M
/*
** ===================================================================
** Method : McuHardFault_HandlerC (component HardFault)
**
** Description :
** This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
/**
* This is called from the HardFaultHandler with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
void McuHardFault_HandlerC(uint32_t *hardfault_args)
{
/*lint -save -e550 Symbol not accessed. */
static volatile unsigned long stacked_r0;
static volatile unsigned long stacked_r1;
static volatile unsigned long stacked_r2;
static volatile unsigned long stacked_r3;
static volatile unsigned long stacked_r12;
static volatile unsigned long stacked_lr;
static volatile unsigned long stacked_pc;
static volatile unsigned long stacked_psr;
static volatile unsigned long _CFSR;
static volatile unsigned long _HFSR;
static volatile unsigned long _DFSR;
static volatile unsigned long _AFSR;
static volatile unsigned long _BFAR;
static volatile unsigned long _MMAR;
stacked_r0 = ((unsigned long)hardfault_args[0]); /* http://www.asciiworld.com/-Smiley,20-.html */
stacked_r1 = ((unsigned long)hardfault_args[1]); /* oooo$$$$$$$$$$$$oooo */
stacked_r2 = ((unsigned long)hardfault_args[2]); /* oo$$$$$$$$$$$$$$$$$$$$$$$$o */
stacked_r3 = ((unsigned long)hardfault_args[3]); /* oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o o$ $$ o$ */
stacked_r12 = ((unsigned long)hardfault_args[4]); /* o $ oo o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o $$ $$ $$o$ */
stacked_lr = ((unsigned long)hardfault_args[5]); /* oo $ $ "$ o$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$o $$$o$$o$ */
stacked_pc = ((unsigned long)hardfault_args[6]); /* "$$$$$$o$ o$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$o $$$$$$$$ */
stacked_psr = ((unsigned long)hardfault_args[7]); /* $$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$ */
/* $$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$$$$$$ """$$$ */
/* Configurable Fault Status Register */ /* "$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$ */
/* Consists of MMSR, BFSR and UFSR */ /* $$$ o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$o */
_CFSR = (*((volatile unsigned long *)(0xE000ED28))); /* o$$" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$o */
/* $$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o */
/* Hard Fault Status Register */ /* o$$$oooo$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ o$$$$$$$$$$$$$$$$$ */
_HFSR = (*((volatile unsigned long *)(0xE000ED2C))); /* $$$$$$$$"$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$"""""""" */
/* """" $$$$ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" o$$$ */
/* Debug Fault Status Register */ /* "$$$o """$$$$$$$$$$$$$$$$$$"$$" $$$ */
_DFSR = (*((volatile unsigned long *)(0xE000ED30))); /* $$$o "$$""$$$$$$"""" o$$$ */
/* $$$$o o$$$" */
/* Auxiliary Fault Status Register */ /* "$$$$o o$$$$$$o"$$$$o o$$$$ */
_AFSR = (*((volatile unsigned long *)(0xE000ED3C))); /* "$$$$$oo ""$$$$o$$$$$o o$$$$"" */
/* ""$$$$$oooo "$$$o$$$$$$$$$""" */
/* ""$$$$$$$oo $$$$$$$$$$ */
/* Read the Fault Address Registers. */ /* """"$$$$$$$$$$$ */
/* These may not contain valid values. */ /* $$$$$$$$$$$$ */
/* Check BFARVALID/MMARVALID to see */ /* $$$$$$$$$$" */
/* if they are valid values */ /* "$$$"" */
/* MemManage Fault Address Register */
_MMAR = (*((volatile unsigned long *)(0xE000ED34)));
/* Bus Fault Address Register */
_BFAR = (*((volatile unsigned long *)(0xE000ED38)));
#if 0 /* experimental, seems not to work properly with GDB in KDS V3.2.0 */
#ifdef __GNUC__ /* might improve stack, see https://www.element14.com/community/message/199113/l/gdb-assisted-debugging-of-hard-faults#199113 */
__asm volatile (
"tst lr,#4 \n" /* check which stack pointer we are using */
"ite eq \n"
"mrseq r0, msp \n" /* use MSP */
"mrsne r0, psp \n" /* use PSP */
"mov sp, r0 \n" /* set stack pointer so GDB shows proper stack frame */
);
#endif
#endif
__asm("BKPT #0\n") ; /* cause the debugger to stop */
/*lint -restore */
}
/*
** ===================================================================
** Method : HardFaultHandler (component HardFault)
**
** Description :
** Hard Fault Handler
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
__attribute__((naked))
#if McuLib_CONFIG_SDK_VERSION_USED==McuLib_CONFIG_SDK_RPI_PICO
void isr_hardfault(void)
#elif McuLib_CONFIG_SDK_VERSION_USED != McuLib_CONFIG_SDK_PROCESSOR_EXPERT
void HardFault_Handler(void)
#else
void McuHardFault_HardFaultHandler(void)
#endif
{
__asm volatile (
".syntax unified \n" /* needed for the 'adds r1,#2' below */
" movs r0,#4 \n" /* load bit mask into R0 */
" mov r1, lr \n" /* load link register into R1 */
" tst r0, r1 \n" /* compare with bitmask */
" beq _MSP \n" /* if bitmask is set: stack pointer is in PSP. Otherwise in MSP */
" mrs r0, psp \n" /* otherwise: stack pointer is in PSP */
" b _GetPC \n" /* go to part which loads the PC */
"_MSP: \n" /* stack pointer is in MSP register */
" mrs r0, msp \n" /* load stack pointer into R0 */
"_GetPC: \n" /* find out where the hard fault happened */
" ldr r1,[r0,#24] \n" /* load program counter into R1. R1 contains address of the next instruction where the hard fault happened */
#if McuHardFault_CONFIG_SETTING_SEMIHOSTING
/* The following code checks if the hard fault is caused by a semihosting BKPT instruction which is "BKPT 0xAB" (opcode: 0xBEAB)
The idea is taken from the MCUXpresso IDE/SDK code, so credits and kudos to the MCUXpresso IDE team! */
" ldrh r2,[r1] \n" /* load opcode causing the fault */
" ldr r3,=0xBEAB \n" /* load constant 0xBEAB (BKPT 0xAB) into R3" */
" cmp r2,r3 \n" /* is it the BKPT 0xAB? */
" beq _SemihostReturn \n" /* if yes, return from semihosting */
" b McuHardFault_HandlerC \n" /* if no, dump the register values and halt the system */
"_SemihostReturn: \n" /* returning from semihosting fault */
" adds r1,#2 \n" /* r1 points to the semihosting BKPT instruction. Adjust the PC to skip it (2 bytes) */
" str r1,[r0,#24] \n" /* store back the adjusted PC value to the interrupt stack frame */
" movs r1,#32 \n" /* need to pass back a return value to emulate a successful semihosting operation. 32 is an arbitrary value */
" str r1,[r0,#0] \n" /* store the return value on the stack frame */
" bx lr \n" /* return from the exception handler back to the application */
#else
" b McuHardFault_HandlerC \n" /* decode more information. R0 contains pointer to stack frame */
#endif
);
}
/*
** ===================================================================
** Method : Deinit (component HardFault)
**
** Description :
** Deinitializes the driver
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void McuHardFault_Deinit(void)
{
#if McuHardFault_CONFIG_SETTING_DISABLE_WRITE_BUFFER
#if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT
SCB_ACTLR &= ~(SCB_ACTLR_DISDEFWBUF_MASK); /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */
#elif McuLib_CONFIG_NXP_SDK_USED && McuLib_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */
SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISDEFWBUF_Msk;
#endif
#endif
}
/*
** ===================================================================
** Method : Init (component HardFault)
**
** Description :
** Initializes the driver
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void McuHardFault_Init(void)
{
#if McuHardFault_CONFIG_SETTING_DISABLE_WRITE_BUFFER
#if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT
SCB_ACTLR |= SCB_ACTLR_DISDEFWBUF_MASK; /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */
#elif McuLib_CONFIG_NXP_SDK_USED && McuLib_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */
SCnSCB->ACTLR |= SCnSCB_ACTLR_DISDEFWBUF_Msk;
#endif
#endif
}
#endif /* McuLib_CONFIG_CPU_IS_ARM_CORTEX_M */
/* END McuHardFault. */
/*!
** @}
*/