mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
215 lines
6.4 KiB
C
215 lines
6.4 KiB
C
/* ---------------------------------------------------------------------------- */
|
|
/* Atmel Microcontroller Software Support */
|
|
/* SAM Software Package License */
|
|
/* ---------------------------------------------------------------------------- */
|
|
/* Copyright (c) 2015, Atmel Corporation */
|
|
/* */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without */
|
|
/* modification, are permitted provided that the following condition is met: */
|
|
/* */
|
|
/* - Redistributions of source code must retain the above copyright notice, */
|
|
/* this list of conditions and the disclaimer below. */
|
|
/* */
|
|
/* Atmel's name may not be used to endorse or promote products derived from */
|
|
/* this software without specific prior written permission. */
|
|
/* */
|
|
/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
|
|
/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
|
|
/* DISCLAIMED. IN NO EVENT SHALL ATMEL 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
|
|
* This file contains the default exception handlers.
|
|
*
|
|
* \note
|
|
* The exception handler has weak aliases.
|
|
* As they are weak aliases, any function with the same name will override
|
|
* this definition.
|
|
*/
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Headers
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#include "chip.h"
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Exported functions
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* \brief Default NMI interrupt handler.
|
|
*/
|
|
void NMI_Handler(void)
|
|
{
|
|
printf("\r\n-E- Enter NMI_Handler!");
|
|
|
|
while (1);
|
|
}
|
|
|
|
/**
|
|
* \brief This function back trace the stack to give exact address where fault
|
|
happened
|
|
**/
|
|
__STATIC_INLINE uint32_t StackUnwind(void)
|
|
{
|
|
uint32_t Fault_Add;
|
|
|
|
#if defined (__CC_ARM)
|
|
uint32_t temp;
|
|
__ASM("mrs temp, msp ");
|
|
__ASM{ ldr Fault_Add, [temp, #28]}
|
|
#else
|
|
__ASM("mrs r0, msp ");
|
|
__ASM("ldr %0, [r0,#28]" : "=r" (Fault_Add));
|
|
#endif
|
|
return Fault_Add;
|
|
}
|
|
|
|
/**
|
|
* \brief If Other Faults are enabled then HardFault error will look for those
|
|
* errors to give more detail about fault
|
|
**/
|
|
static void HardFault_reason(void)
|
|
{
|
|
uint32_t CFSRValue;
|
|
TRACE_DEBUG("In Hard Fault Handler\n\r");
|
|
TRACE_DEBUG("SCB->HFSR = 0x%08x\n\r", SCB->HFSR);
|
|
|
|
if ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk)) {
|
|
TRACE_DEBUG("Debug Event Hard Fault\n\r");
|
|
TRACE_DEBUG("SCB->DFSR = 0x%08x\n", SCB->DFSR);
|
|
}
|
|
|
|
if ((SCB->HFSR & SCB_HFSR_VECTTBL_Msk)) {
|
|
TRACE_DEBUG("Fault was due to vector table read on \
|
|
exception processing\n\r");
|
|
}
|
|
|
|
// Forced HardFault
|
|
if ((SCB->HFSR & SCB_HFSR_FORCED_Msk)) {
|
|
TRACE_DEBUG("Forced Hard Fault\n\r");
|
|
TRACE_DEBUG("SCB->CFSR = 0x%08x\n\r", SCB->CFSR);
|
|
|
|
// Usage Fault
|
|
if ((SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk)) {
|
|
CFSRValue = SCB->CFSR;
|
|
TRACE_DEBUG("Usage fault: ");
|
|
CFSRValue >>= SCB_CFSR_USGFAULTSR_Pos;
|
|
|
|
if ((CFSRValue & (1 << 9)))
|
|
TRACE_DEBUG("Divide by zero\n\r");
|
|
|
|
if ((CFSRValue & (1 << 8)))
|
|
TRACE_DEBUG("Unaligned access error\n\r");
|
|
|
|
if ((CFSRValue & (1 << 3)))
|
|
TRACE_DEBUG("Coprocessor access error\n\r");
|
|
|
|
if ((CFSRValue & (1 << 2)))
|
|
TRACE_DEBUG("Integrity check error on EXC_RETURN\n\r");
|
|
}
|
|
|
|
// Bus Fault
|
|
if ((SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk)) {
|
|
CFSRValue = SCB->CFSR;
|
|
TRACE_DEBUG("Bus fault: ");
|
|
CFSRValue >>= SCB_CFSR_BUSFAULTSR_Pos;
|
|
|
|
if ((CFSRValue & (1 << 7)) && (CFSRValue & (1 << 1))) {
|
|
TRACE_DEBUG("Precise data access error. Bus Fault Address \
|
|
Register is: %x \n\r", SCB->BFAR);
|
|
}
|
|
|
|
if ((CFSRValue & (1 << 4)))
|
|
TRACE_DEBUG("Bus fault has occurred on exception entry\n\r");
|
|
|
|
if ((CFSRValue & (1 << 3)))
|
|
TRACE_DEBUG("bus fault has occurred on exception return\n\r");
|
|
|
|
if ((CFSRValue & (1 << 2)))
|
|
TRACE_DEBUG("Imprecise data access error\n\r");
|
|
|
|
if ((CFSRValue & (1 << 0))) {
|
|
TRACE_DEBUG("This bit indicates a bus fault on an instruction \
|
|
pre-fetch. \n\r");
|
|
}
|
|
}
|
|
}
|
|
|
|
// MemoryFault
|
|
if ((SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk)) {
|
|
CFSRValue = SCB->CFSR;
|
|
TRACE_DEBUG("Memory fault: ");
|
|
CFSRValue >>= SCB_CFSR_MEMFAULTSR_Pos;
|
|
|
|
if ((CFSRValue & (1 << 9)) != 0)
|
|
TRACE_DEBUG("Divide by zero\n\r");
|
|
}
|
|
|
|
__ISB();
|
|
__DMB();
|
|
__ASM volatile("BKPT #01");
|
|
}
|
|
/**
|
|
* \brief Default HardFault interrupt handler.
|
|
*/
|
|
|
|
void HardFault_Handler(void)
|
|
{
|
|
printf("\n\rHardFault at address 0X%x\n\r", (int)StackUnwind());
|
|
__ISB();
|
|
__DMB();
|
|
HardFault_reason();
|
|
}
|
|
|
|
#ifndef MPU_EXAMPLE_FEATURE
|
|
/**
|
|
* \brief Default MemManage interrupt handler.
|
|
*/
|
|
void MemManage_Handler(void)
|
|
{
|
|
printf("\n\rMemoryMemFault (MPU fault) at address 0X%x\n\r",
|
|
(int)StackUnwind());
|
|
__ISB();
|
|
__DMB();
|
|
__ASM volatile("BKPT #01");
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \brief Default BusFault interrupt handler.
|
|
*/
|
|
void BusFault_Handler(void)
|
|
{
|
|
__ASM("nop");
|
|
__ASM("nop");
|
|
printf("\n\rBus Fault at address 0X%x\n\r", (int)StackUnwind());
|
|
|
|
__ISB();
|
|
__DMB();
|
|
__ASM volatile("BKPT #01");
|
|
}
|
|
|
|
/**
|
|
* \brief Default UsageFault interrupt handler.
|
|
*/
|
|
void UsageFault_Handler(void)
|
|
{
|
|
printf("\r\nUsage fault at address 0X%x", (int)StackUnwind());
|
|
|
|
__ISB();
|
|
__DMB();
|
|
__ASM volatile("BKPT #01");
|
|
}
|