From 7f91e41f67ad0a91fbf779fcf2cbc8c1d3cf5a71 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Wed, 2 Sep 2020 13:33:50 -0700 Subject: [PATCH] hardfault_log:Add Fault Status registers --- .../nuttx/src/px4/common/board_crashdump.c | 11 ++++++ src/lib/systemlib/hardfault_log.h | 18 ++++++++-- src/systemcmds/hardfault_log/hardfault_log.c | 34 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/platforms/nuttx/src/px4/common/board_crashdump.c b/platforms/nuttx/src/px4/common/board_crashdump.c index 2d00c90bed..3ba4da017a 100644 --- a/platforms/nuttx/src/px4/common/board_crashdump.c +++ b/platforms/nuttx/src/px4/common/board_crashdump.c @@ -53,6 +53,7 @@ #include "up_internal.h" #include +#include "nvic.h" #if defined(CONFIG_STM32F7_BBSRAM) && defined(CONFIG_STM32F7_SAVE_CRASHDUMP) # define HAS_BBSRAM CONFIG_STM32F7_BBSRAM @@ -287,6 +288,16 @@ __EXPORT void board_crashdump(uintptr_t currentsp, FAR void *tcb, FAR const uint pdump->info.pid = rtcb->pid; + pdump->info.fault_regs.cfsr = getreg32(NVIC_CFAULTS); + pdump->info.fault_regs.hfsr = getreg32(NVIC_HFAULTS); + pdump->info.fault_regs.dfsr = getreg32(NVIC_DFAULTS); + pdump->info.fault_regs.mmfsr = getreg32(NVIC_MEMMANAGE_ADDR); + pdump->info.fault_regs.bfsr = getreg32(NVIC_BFAULT_ADDR); + pdump->info.fault_regs.afsr = getreg32(NVIC_AFAULTS); +#if defined(CONFIG_ARCH_CORTEXM7) + pdump->info.fault_regs.abfsr = getreg32(NVIC_ABFSR); +#endif + pdump->info.flags |= eFaultRegPresent; /* If current_regs is not NULL then we are in an interrupt context * and the user context is in current_regs else we are running in diff --git a/src/lib/systemlib/hardfault_log.h b/src/lib/systemlib/hardfault_log.h index 1c5df3fa82..380732b498 100644 --- a/src/lib/systemlib/hardfault_log.h +++ b/src/lib/systemlib/hardfault_log.h @@ -229,17 +229,31 @@ typedef enum { eRegsPresent = 0x01, eUserStackPresent = 0x02, eIntStackPresent = 0x04, + eFaultRegPresent = 0x08, eInvalidUserStackPtr = 0x20, eInvalidIntStackPrt = 0x40, } fault_flags_t; +typedef struct { + uint32_t cfsr; /* 0x0d28 Configurable fault status register */ + uint32_t hfsr; /* 0x0d2c Hard fault status register */ + uint32_t dfsr; /* 0x0d30 Debug fault status register */ + uint32_t mmfsr; /* 0x0d34 Mem manage address register */ + uint32_t bfsr; /* 0x0d38 Bus fault address register */ + uint32_t afsr; /* 0x0d3c Auxiliary fault status register */ +#if defined(CONFIG_ARCH_CORTEXM7) + uint32_t abfsr; /* 0x0fa8 Auxiliary Bus Fault Status Register */ +#endif + +} fault_regs_s; + typedef struct { fault_flags_t flags; /* What is in the dump */ uintptr_t current_regs; /* Used to validate the dump */ int lineno; /* __LINE__ to up_assert */ int pid; /* Process ID */ - uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save - * area */ + uint32_t regs[XCPTCONTEXT_REGS]; /* Interrupt register save area */ + fault_regs_s fault_regs; /* NVIC status */ stack_t stacks; /* Stack info */ #if CONFIG_TASK_NAME_SIZE > 0 char name[CONFIG_TASK_NAME_SIZE + 1]; /* Task name (with NULL diff --git a/src/systemcmds/hardfault_log/hardfault_log.c b/src/systemcmds/hardfault_log/hardfault_log.c index 3eee294087..b20eca6a73 100644 --- a/src/systemcmds/hardfault_log/hardfault_log.c +++ b/src/systemcmds/hardfault_log/hardfault_log.c @@ -392,6 +392,31 @@ static int write_registers(uint32_t regs[], char *buffer, int max, int fd) return OK; } +/**************************************************************************** + * write_registers + ****************************************************************************/ +static int write_fault_registers(fault_regs_s *fault_regs, char *buffer, int max, int fd) +{ +#if defined(CONFIG_ARCH_CORTEXM7) + const char fmt[] = " cfsr:0x%08x hfsr:0x%08x dfsr:0x%08x mmfsr:0x%08x bfsr:0x%08x afsr:0x%08x abfsr:0x%08x \n"; +#else + const char fmt[] = " cfsr:0x%08x hfsr:0x%08x dfsr:0x%08x mmfsr:0x%08x bfsr:0x%08x afsr:0x%08x\n"; +#endif + int n = snprintf(buffer, max, fmt, + fault_regs->cfsr, fault_regs->hfsr, fault_regs->dfsr, +#if defined(CONFIG_ARCH_CORTEXM7) + fault_regs->mmfsr, fault_regs->bfsr, fault_regs->afsr, fault_regs->abfsr); +#else + fault_regs->mmfsr, fault_regs->bfsr, fault_regs->afsr); +#endif + + if (n != write(fd, buffer, n)) { + return -EIO; + } + + return OK; +} + /**************************************************************************** * write_registers_info ****************************************************************************/ @@ -408,6 +433,15 @@ static int write_registers_info(int fdout, info_s *pi, char *buffer, int sz) } } + if (pi->flags & eFaultRegPresent) { + ret = -EIO; + int n = snprintf(buffer, sz, " Fault status registers: from NVIC\n"); + + if (n == write(fdout, buffer, n)) { + ret = write_fault_registers(&pi->fault_regs, buffer, sz, fdout); + } + } + return ret; }