当前位置:网站首页>SEGGER 的硬件异常 分析
SEGGER 的硬件异常 分析
2022-07-29 07:12:00 【Car12】
SEGGER 异常分析源码文件如下
1.HardFaultHandler.S
内部使用了串口打印的功能所以在使用SEGGER时需要初始化串口1,也可以屏蔽该部分代码
;
;----------------------------------------------------------------------
;File : HardFaultHandler.S
;Purpose : HardFault exception handler for IAR, Keil and GNU assembler.
; Evaluates used stack (MSP, PSP) and passes appropiate stack
; pointer to the HardFaultHandler "C"-routine.
;------------- END-OF-HEADER ------------------------------------------
;
;/********************************************************************* ;* ;* Forward declarations of segments used ;* ;********************************************************************** ;*/
AREA OSKERNEL, CODE, READONLY, ALIGN=2
PRESERVE8
EXPORT HardFault_Handler
IMPORT HardFaultHandler
THUMB
;/********************************************************************* ;* ;* Global functions ;* ;********************************************************************** ;*/
;/********************************************************************* ;* ;* HardFault_Handler() ;* ;* Function description ;* Evaluates the used stack (MSP, PSP) and passes the appropiate ;* stack pointer to the HardFaultHandler "C"-routine. ;* ;* Notes ;* (1) Ensure that HardFault_Handler is part of the exception table ;*/
HardFault_Handler
;// This version is for Cortex M3, Cortex M4 and Cortex M4F
tst LR, #4 ;// Check EXC_RETURN in Link register bit 2.
ite EQ
mrseq R0, MSP ;// Stacking was using MSP.
mrsne R0, PSP ;// Stacking was using PSP.
b HardFaultHandler ;// Stack pointer passed through R0.
END
;/****** End Of File *************************************************/
2.SEGGER_HardFaultHandler.c
/********************************************************************* * SEGGER Microcontroller GmbH & Co. KG * * The Embedded Experts * ********************************************************************** * * * (c) 1995 - 2017 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: segger.com Support: [email protected] * * * ********************************************************************** * * * embOS * Real time operating system for microcontrollers * * * * Please note: * * * * Knowledge of this file may under no circumstances * * be used to write a similar product or a real-time * * operating system for in-house use. * * * * Thank you for your fairness ! * * * ********************************************************************** * * * OS version: 4.32 * * * ********************************************************************** ---------------------------------------------------------------------- File : SEGGER_HardFaultHandler.c Purpose : Generic SEGGER HardFault handler for Cortex-M Literature: [1] Analyzing HardFaults on Cortex-M CPUs (https://www.segger.com/downloads/appnotes/AN00016_AnalyzingHardFaultsOnCortexM.pdf) Additional information: This HardFault handler enables user-friendly analysis of hard faults in debug configurations. If a release configuration requires a HardFault handler, a specific HardFault handler should be included instead, which for example issues a reset or lits an error LED. -------- END-OF-HEADER --------------------------------------------- */
#include "stdint.h"
#include "string.h"
#include "stm32f1xx_hal.h"
/********************************************************************* * * Defines * ********************************************************************** */
#define SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u)) // System Handler Control and State Register
#define NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u)) // Memory Management Fault Status Register
#define NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u)) // Bus Fault Status Register
#define NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au)) // Usage Fault Status Register
#define NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu)) // Hard Fault Status Register
#define NVIC_DFSR (*(volatile unsigned int*) (0xE000ED30u)) // Debug Fault Status Register
#define NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u)) // Bus Fault Manage Address Register
#define NVIC_AFSR (*(volatile unsigned int*) (0xE000ED3Cu)) // Auxiliary Fault Status Register
#ifndef DEBUG // Should be overwritten by project settings
#define DEBUG (1) // in debug builds
#endif
#define ERR_INFO "\r\nEnter HardFault_Handler, System Halt.\r\n"
/********************************************************************* * * Prototypes * ********************************************************************** */
#ifdef __cplusplus
extern "C" {
#endif
void HardFaultHandler(unsigned int* pStack);
#ifdef __cplusplus
}
#endif
/********************************************************************* * * Static data * ********************************************************************** */
#if DEBUG
static volatile unsigned int _Continue; // Set this variable to 1 to run further
static struct {
struct {
volatile unsigned int r0; // Register R0
volatile unsigned int r1; // Register R1
volatile unsigned int r2; // Register R2
volatile unsigned int r3; // Register R3
volatile unsigned int r12; // Register R12
volatile unsigned int lr; // Link register
volatile unsigned int pc; // Program counter
union {
volatile unsigned int byte;
struct {
unsigned int IPSR : 8; // Interrupt Program Status register (IPSR)
unsigned int EPSR : 19; // Execution Program Status register (EPSR)
unsigned int APSR : 5; // Application Program Status register (APSR)
} bits;
} psr; // Program status register.
} SavedRegs;
union {
volatile unsigned int byte;
struct {
unsigned int MEMFAULTACT : 1; // Read as 1 if memory management fault is active
unsigned int BUSFAULTACT : 1; // Read as 1 if bus fault exception is active
unsigned int UnusedBits1 : 1;
unsigned int USGFAULTACT : 1; // Read as 1 if usage fault exception is active
unsigned int UnusedBits2 : 3;
unsigned int SVCALLACT : 1; // Read as 1 if SVC exception is active
unsigned int MONITORACT : 1; // Read as 1 if debug monitor exception is active
unsigned int UnusedBits3 : 1;
unsigned int PENDSVACT : 1; // Read as 1 if PendSV exception is active
unsigned int SYSTICKACT : 1; // Read as 1 if SYSTICK exception is active
unsigned int USGFAULTPENDED : 1; // Usage fault pended; usage fault started but was replaced by a higher-priority exception
unsigned int MEMFAULTPENDED : 1; // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
unsigned int BUSFAULTPENDED : 1; // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
unsigned int SVCALLPENDED : 1; // SVC pended; SVC was started but was replaced by a higher-priority exception
unsigned int MEMFAULTENA : 1; // Memory management fault handler enable
unsigned int BUSFAULTENA : 1; // Bus fault handler enable
unsigned int USGFAULTENA : 1; // Usage fault handler enable
} bits;
} syshndctrl; // System Handler Control and State Register (0xE000ED24)
union {
volatile unsigned char byte;
struct {
unsigned char IACCVIOL : 1; // Instruction access violation
unsigned char DACCVIOL : 1; // Data access violation
unsigned char UnusedBits : 1;
unsigned char MUNSTKERR : 1; // Unstacking error
unsigned char MSTKERR : 1; // Stacking error
unsigned char UnusedBits2 : 2;
unsigned char MMARVALID : 1; // Indicates the MMAR is valid
} bits;
} mfsr; // Memory Management Fault Status Register (0xE000ED28)
union {
volatile unsigned int byte;
struct {
unsigned int IBUSERR : 1; // Instruction access violation
unsigned int PRECISERR : 1; // Precise data access violation
unsigned int IMPREISERR : 1; // Imprecise data access violation
unsigned int UNSTKERR : 1; // Unstacking error
unsigned int STKERR : 1; // Stacking error
unsigned int UnusedBits : 2;
unsigned int BFARVALID : 1; // Indicates BFAR is valid
} bits;
} bfsr; // Bus Fault Status Register (0xE000ED29)
volatile unsigned int bfar; // Bus Fault Manage Address Register (0xE000ED38)
union {
volatile unsigned short byte;
struct {
unsigned short UNDEFINSTR : 1; // Attempts to execute an undefined instruction
unsigned short INVSTATE : 1; // Attempts to switch to an invalid state (e.g., ARM)
unsigned short INVPC : 1; // Attempts to do an exception with a bad value in the EXC_RETURN number
unsigned short NOCP : 1; // Attempts to execute a coprocessor instruction
unsigned short UnusedBits : 4;
unsigned short UNALIGNED : 1; // Indicates that an unaligned access fault has taken place
unsigned short DIVBYZERO : 1; // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
} bits;
} ufsr; // Usage Fault Status Register (0xE000ED2A)
union {
volatile unsigned int byte;
struct {
unsigned int UnusedBits : 1;
unsigned int VECTBL : 1; // Indicates hard fault is caused by failed vector fetch
unsigned int UnusedBits2 : 28;
unsigned int FORCED : 1; // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
unsigned int DEBUGEVT : 1; // Indicates hard fault is triggered by debug event
} bits;
} hfsr; // Hard Fault Status Register (0xE000ED2C)
union {
volatile unsigned int byte;
struct {
unsigned int HALTED : 1; // Halt requested in NVIC
unsigned int BKPT : 1; // BKPT instruction executed
unsigned int DWTTRAP : 1; // DWT match occurred
unsigned int VCATCH : 1; // Vector fetch occurred
unsigned int EXTERNAL : 1; // EDBGRQ signal asserted
} bits;
} dfsr; // Debug Fault Status Register (0xE000ED30)
volatile unsigned int afsr; // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
} HardFaultRegs;
#endif
/********************************************************************* * * Global functions * ********************************************************************** */
/********************************************************************* * * HardFaultHandler() * * Function description * C part of the hard fault handler which is called by the assembler * function HardFault_Handler */
void HardFaultHandler(unsigned int* pStack) {
//
// In case we received a hard fault because of a breakpoint instruction, we return.
// This may happen when using semihosting for printf outputs and no debugger is connected,
// i.e. when running a "Debug" configuration in release mode.
//
if (NVIC_HFSR & (1u << 31)) {
NVIC_HFSR |= (1u << 31); // Reset Hard Fault status
*(pStack + 6u) += 2u; // PC is located on stack at SP + 24 bytes. Increment PC by 2 to skip break instruction.
return; // Return to interrupted application
}
#if DEBUG
//
// Read NVIC registers
//
HardFaultRegs.syshndctrl.byte = SYSHND_CTRL; // System Handler Control and State Register
HardFaultRegs.mfsr.byte = NVIC_MFSR; // Memory Fault Status Register
HardFaultRegs.bfsr.byte = NVIC_BFSR; // Bus Fault Status Register
HardFaultRegs.bfar = NVIC_BFAR; // Bus Fault Manage Address Register
HardFaultRegs.ufsr.byte = NVIC_UFSR; // Usage Fault Status Register
HardFaultRegs.hfsr.byte = NVIC_HFSR; // Hard Fault Status Register
HardFaultRegs.dfsr.byte = NVIC_DFSR; // Debug Fault Status Register
HardFaultRegs.afsr = NVIC_AFSR; // Auxiliary Fault Status Register
#if 1 //打开串口输出日志功能
{
const char *pError = ERR_INFO;
uint8_t i;
for (i = 0; i < strlen(ERR_INFO); i++)
{
USART1->DR = pError[i];
/* 等待发送结束 */
while((USART1->SR & USART_SR_TC) == 0);
}
}
#endif
//
// Halt execution
// If NVIC registers indicate readable memory, change the variable value to != 0 to continue execution.
//
_Continue = 0u;
while (_Continue == 0u) {
}
//
// Read saved registers from the stack.
//
HardFaultRegs.SavedRegs.r0 = pStack[0]; // Register R0
HardFaultRegs.SavedRegs.r1 = pStack[1]; // Register R1
HardFaultRegs.SavedRegs.r2 = pStack[2]; // Register R2
HardFaultRegs.SavedRegs.r3 = pStack[3]; // Register R3
HardFaultRegs.SavedRegs.r12 = pStack[4]; // Register R12
HardFaultRegs.SavedRegs.lr = pStack[5]; // Link register LR
HardFaultRegs.SavedRegs.pc = pStack[6]; // Program counter PC
HardFaultRegs.SavedRegs.psr.byte = pStack[7]; // Program status word PSR
//
// Halt execution
// To step out of the HardFaultHandler, change the variable value to != 0.
//
_Continue = 0u;
while (_Continue == 0u) {
}
#else
//
// If this module is included in a release configuration, simply stay in the HardFault handler
//
(void)pStack;
do {
} while (1);
#endif
}
/*************************** End of file ****************************/
3.使用方法
将这两个文件添加到工程中
屏蔽原来的 HardFault_Handler 函数
3. 启动调试
4. 全速运行程序,等待程序进入 HardFault_Handler 异常
5. 在 Watch1 窗口添加变量_Continue
修改_Continue 为非0 值 单步运行 F11,就会在异常返回后进入程序出错的地方
这里发现指针异常
边栏推荐
- Error 1045 (28000) access denied for user 'root' @ 'localhost' solution
- 对Vintage分析的一些学习理解
- PAT甲级 1154 顶点着色
- Homebrew brew update 长时间没反应(或卡在 Updating Homebrew...)
- MySQL - multi table query
- Cvpr2021 | multi view stereo matching based on self supervised learning (cvpr2021)
- Tp6 use protobuf
- halcon的安装以及在vs2017中测试,vs2017中dll的配置
- WPF nested layout case
- logback日志级别简介说明
猜你喜欢
halcon的安装以及在vs2017中测试,vs2017中dll的配置
Paper reading (62):pointer networks
[OpenGL] use of shaders
WPF simple login page completion case
Interface test actual project 03: execute test cases
JS day 4 process control (if statement and switch statement)
Round avatar of user list and follow small blocks
在线问题反馈模块实战(十七):实现excel模板在线下载功能
09 bloom filter
1-后台项目搭建
随机推荐
请问flink支持sqlServer数据库么?获取sqlServer数据库的变化
Kubernetes (V) -- deploy kubernetes dashboard
@RequestMapping 用法详解
LevelFilter简介说明
log4j Layout简介说明
亚马逊云助手小程序来啦!
Interface test actual project 03: execute test cases
Cvpr2021 | multi view stereo matching based on self supervised learning (cvpr2021)
Scala higher order (10): exception handling in Scala
BeanUtils.setProperty()
Use vscode to configure Mysql to realize connection, query, and other functions
美智光电IPO被终止:年营收9.26亿 何享健为实控人
Tp6 use protobuf
7-2 计算正五边形的面积和周长 (25分)
Introduction to log4j layout
I'd like to ask, my flick job writes data in the way of upsert Kafka, but I'm more careful in MySQL
cdc source能读完MySqlSnapshotSplit 就退出嘛
Job 7.28 file IO and standard IO
JS break and continue and return keywords
Unity sends a post request to the golang server for parsing and returning