aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sidrane <david_s5@nscdg.com>2015-03-04 17:02:32 -1000
committerDavid Sidrane <david_s5@nscdg.com>2015-03-05 08:33:56 -1000
commit1694c8faccfb83875a9ec5b98e131e970c16865e (patch)
tree423d90d4e931dea493aa7dad38ec8957711bbfce
parentbaf9bd0346d7ee8dd236dc0ce0214a7c5543544a (diff)
downloadpx4-firmware-1694c8faccfb83875a9ec5b98e131e970c16865e.tar.gz
px4-firmware-1694c8faccfb83875a9ec5b98e131e970c16865e.tar.bz2
px4-firmware-1694c8faccfb83875a9ec5b98e131e970c16865e.zip
Reduced memory footprint with serialization and malloc
-rw-r--r--src/drivers/boards/px4fmu-v2/px4fmu2_init.c102
-rw-r--r--src/modules/systemlib/hardfault_log.h82
-rw-r--r--src/systemcmds/hardfault_log/hardfault_log.c519
3 files changed, 417 insertions, 286 deletions
diff --git a/src/drivers/boards/px4fmu-v2/px4fmu2_init.c b/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
index 98babbf05..52ee00a7d 100644
--- a/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
+++ b/src/drivers/boards/px4fmu-v2/px4fmu2_init.c
@@ -311,7 +311,8 @@ __EXPORT int nsh_archinitialize(void)
if (hadCrash == OK) {
- syslog(LOG_INFO, "[boot] There was a hard fault hit the SPACE BAR to halt the system!\n");
+ syslog(LOG_INFO, "[boot] There is a hard fault logged. Hold down the SPACE BAR," \
+ " while booting to halt the system!\n");
/* Yes. So add one to the boot count - this will be reset after a successful
* commit to SD
@@ -326,13 +327,13 @@ __EXPORT int nsh_archinitialize(void)
if (reboots > 2 || bytesWaiting != 0 ) {
- /* Since we can not commit the fault dump to disk. display it
+ /* Since we can not commit the fault dump to disk. Display it
* to the console.
*/
hardfault_write("boot", fileno(stdout), HARDFAULT_DISPLAY_FORMAT, false);
- syslog(LOG_INFO, "[boot] There were %d uncommitted Hard faults System halted%s\n",
+ syslog(LOG_INFO, "[boot] There were %d reboots with Hard fault that were not committed to disk - System halted %s\n",
reboots,
(bytesWaiting==0 ? "" : " Due to Key Press\n"));
@@ -344,7 +345,8 @@ __EXPORT int nsh_archinitialize(void)
/* Clear any key press that got us here */
static volatile bool dbgContinue = false;
- for (int c ='>'; !dbgContinue; c= getchar()) {
+ int c = '>';
+ while (!dbgContinue) {
switch(c) {
@@ -387,6 +389,9 @@ __EXPORT int nsh_archinitialize(void)
"Enter C - Clear the fault log\n" \
"Enter D - Dump fault log\n\n?>");
fflush(stdout);
+ if (!dbgContinue) {
+ c = getchar();
+ }
break;
} // outer switch
@@ -484,6 +489,13 @@ __EXPORT int nsh_archinitialize(void)
return OK;
}
+inline static void copy_reverse(stack_word_t *dest, stack_word_t *src, int size)
+{
+ while (size--) {
+ *dest++ = *src--;
+ }
+}
+
__EXPORT void board_crashdump(uint32_t currentsp, void *tcb, uint8_t *filename, int lineno)
{
/* We need a chunk of ram to save the complete contest in.
@@ -498,7 +510,7 @@ __EXPORT void board_crashdump(uint32_t currentsp, void *tcb, uint8_t *filename,
/* Zero out everything */
- memset(pdump,0,sizeof(fullcontext_s));
+ memset(pdump, 0, sizeof(fullcontext_s));
/* Save Info */
@@ -524,56 +536,63 @@ __EXPORT void board_crashdump(uint32_t currentsp, void *tcb, uint8_t *filename,
/* Save Context */
- /* If not NULL then we are in an interrupt context and the user context
- * is in current_regs else we are running in the users context
- */
#if CONFIG_TASK_NAME_SIZE > 0
- strncpy(pdump->context.proc.name, rtcb->name, CONFIG_TASK_NAME_SIZE);
+ strncpy(pdump->info.name, rtcb->name, CONFIG_TASK_NAME_SIZE);
#endif
- pdump->context.proc.pid = rtcb->pid;
+ pdump->info.pid = rtcb->pid;
- pdump->context.stack.current_sp = currentsp;
+
+ /* 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
+ * the users context
+ */
if (current_regs)
{
- pdump->info.stuff |= eRegs;
- memcpy(&pdump->context.proc.xcp.regs, (void*)current_regs, sizeof(pdump->context.proc.xcp.regs));
- currentsp = pdump->context.proc.xcp.regs[REG_R13];
- }
+ pdump->info.stacks.interrupt.sp = currentsp;
+ pdump->info.flags |= eRegs;
+ memcpy(pdump->info.regs, (void*)current_regs, sizeof(pdump->info.regs));
+ pdump->info.stacks.user.sp = pdump->info.regs[REG_R13];
+ currentsp = pdump->info.stacks.user.sp;
+ } else {
- pdump->context.stack.itopofstack = (uint32_t) &g_intstackbase;;
- pdump->context.stack.istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
+ /* users context */
+
+ pdump->info.stacks.user.sp = currentsp;
+ }
- if (pdump->context.proc.pid == 0) {
+ if (pdump->info.pid == 0) {
- pdump->context.stack.utopofstack = g_idle_topstack - 4;
- pdump->context.stack.ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
+ pdump->info.stacks.user.top = g_idle_topstack - 4;
+ pdump->info.stacks.user.size = CONFIG_IDLETHREAD_STACKSIZE;
} else {
- pdump->context.stack.utopofstack = (uint32_t) rtcb->adj_stack_ptr;
- pdump->context.stack.ustacksize = (uint32_t) rtcb->adj_stack_size;;
+ pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
+ pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;;
}
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
- pdump->context.stack.itopofstack = (uint32_t)&g_intstackbase;
- pdump->context.stack.istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
+ pdump->info.stacks.interrupt.top = (uint32_t)&g_intstackbase;
+ pdump->info.stacks.interrupt.size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
/* If the current stack pointer is within the interrupt stack then
* save the interrupt stack data centered about the interrupt stack pointer
*/
- if (pdump->context.stack.current_sp <= pdump->context.stack.itopofstack &&
- pdump->context.stack.current_sp > pdump->context.stack.itopofstack - pdump->context.stack.istacksize)
+ if (pdump->info.stacks.interrupt.sp <= pdump->info.stacks.interrupt.top &&
+ pdump->info.stacks.interrupt.sp > pdump->info.stacks.interrupt.top - pdump->info.stacks.interrupt.size)
{
- pdump->info.stuff |= eIntStack;
- memcpy(&pdump->istack, (void *)(pdump->context.stack.current_sp-sizeof(pdump->istack)/2),
- sizeof(pdump->istack));
+ pdump->info.flags |= eIntStack;
+ stack_word_t * ps = (stack_word_t *) pdump->info.stacks.interrupt.sp;
+ copy_reverse(pdump->istack, &ps[arraySize(pdump->istack)/2], arraySize(pdump->istack));
+ } else {
+ pdump->info.flags |= eInvalidIntStack;
}
#endif
@@ -581,30 +600,33 @@ __EXPORT void board_crashdump(uint32_t currentsp, void *tcb, uint8_t *filename,
/* If the saved context of the interrupted process's stack pointer lies within the
* allocated user stack memory then save the user stack centered about the user sp
*/
- if (currentsp <= pdump->context.stack.utopofstack &&
- currentsp > pdump->context.stack.utopofstack - pdump->context.stack.ustacksize)
+ if (currentsp <= pdump->info.stacks.user.top &&
+ currentsp > pdump->info.stacks.user.top - pdump->info.stacks.user.size)
{
- pdump->info.stuff |= eUserStack;
- memcpy(&pdump->ustack, (void *)(currentsp-sizeof(pdump->ustack)/2), sizeof(pdump->ustack));
+ pdump->info.flags |= eUserStack;
+ stack_word_t * ps = (stack_word_t *) pdump->info.stacks.user.sp;
+ copy_reverse(pdump->ustack, &ps[arraySize(pdump->ustack)/2], arraySize(pdump->ustack));
+ } else {
+ pdump->info.flags |= eInvalidUserStack;
}
/* Oh boy we have a real hot mess on our hands so save above and below the
* current sp
*/
- if ((pdump->info.stuff & eStackValid) == 0)
+ if ((pdump->info.flags & eStackValid) == 0)
{
- pdump->info.stuff |= eStackUnknown;
+ pdump->info.flags |= (eStackUnknown | eStackValid);
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* sp and above in istack */
- memcpy(&pdump->istack, (void *)pdump->context.stack.current_sp, sizeof(pdump->istack));
+ stack_word_t * ps = (stack_word_t *) pdump->info.stacks.interrupt.sp;
+ copy_reverse(pdump->istack, &ps[arraySize(pdump->istack)], arraySize(pdump->istack));
/* below in ustack */
- memcpy(&pdump->ustack, (void *)(pdump->context.stack.current_sp-sizeof(pdump->ustack)),
- sizeof(pdump->ustack));
+ ps = (stack_word_t *) pdump->info.stacks.user.sp;
+ copy_reverse(pdump->ustack, &ps[arraySize(pdump->ustack)], arraySize(pdump->ustack));
#else
/* save above and below in ustack */
- memcpy(&pdump->ustack, (void *)(pdump->context.stack.current_sp-sizeof(pdump->ustack)/2),
- sizeof(pdump->ustack)/2);
+ copy_reverse(pdump->ustack, &ps[arraySize(pdump->ustack)/2], arraySize(pdump->ustack));
#endif
}
diff --git a/src/modules/systemlib/hardfault_log.h b/src/modules/systemlib/hardfault_log.h
index 2161103a1..6983a5737 100644
--- a/src/modules/systemlib/hardfault_log.h
+++ b/src/modules/systemlib/hardfault_log.h
@@ -67,7 +67,7 @@
#else
# define BBSRAM_NUMBER_STACKS 2
#endif
-#define BBSRAM_FIXED_ELEMENTS_SIZE (sizeof(context_s)+sizeof(info_s))
+#define BBSRAM_FIXED_ELEMENTS_SIZE (sizeof(info_s))
#define BBSRAM_LEFTOVER (BBSRAM_REAMINING-BBSRAM_FIXED_ELEMENTS_SIZE)
#define CONFIG_ISTACK_SIZE (BBSRAM_LEFTOVER/BBSRAM_NUMBER_STACKS/sizeof(stack_word_t))
@@ -123,7 +123,7 @@
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
-{
+//{
#else
#define EXTERN extern
#endif
@@ -131,36 +131,19 @@ extern "C"
/* Used for stack frame storage */
typedef uint32_t stack_word_t;
-typedef struct {
- int pid; /* Process ID */
- struct xcptcontext xcp; /* Interrupt register save area */
-#if CONFIG_TASK_NAME_SIZE > 0
- char name[CONFIG_TASK_NAME_SIZE+1]; /* Task name (with NULL terminator) */
-#endif
-} process_t;
-
/* Stack related data */
+
typedef struct {
- uint32_t current_sp; /* The stack the up_assert is running on
- * it may be either the user stack for an assertion
- * failure or the interrupt stack in the case of a
- * hard fault
- */
- uint32_t utopofstack; /* Top of the user stack at the time of the
- * up_assert
- */
- uint32_t ustacksize; /* Size of the user stack at the time of the
- * up_assert
- */
+ uint32_t sp;
+ uint32_t top;
+ uint32_t size;
-#if CONFIG_ARCH_INTERRUPTSTACK > 3
+} _stack_s;
- uint32_t itopofstack; /* Top of the interrupt stack at the time of the
- * up_assert
- */
- uint32_t istacksize; /* Size of the interrupt stack at the time of the
- * up_assert
- */
+typedef struct {
+ _stack_s user;
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ _stack_s interrupt;
#endif
} stack_t;
@@ -249,30 +232,33 @@ typedef struct
/* Flags to identify what is in the dump */
typedef enum {
- eRegs = 0x01,
- eUserStack = 0x02,
- eIntStack = 0x04,
- eStackUnknown = 0x08,
- eStackValid = eUserStack | eIntStack,
-} stuff_t;
+ eRegs = 0x01,
+ eUserStack = 0x02,
+ eIntStack = 0x04,
+ eStackValid = eUserStack | eIntStack,
+ eStackUnknown = 0x08,
+ eInvalidUserStack = 0x20,
+ eInvalidIntStack = 0x40,
+} fault_flags_t;
typedef struct {
- stuff_t stuff; /* What is in the dump */
- uintptr_t current_regs; /* Used to validate the dump */
- int lineno; /* __LINE__ to up_assert */
- char filename[MAX_FILE_PATH_LENGTH]; /* Last MAX_FILE_PATH_LENGTH of chars in
- * __FILE__ to up_assert
- */
+ 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 */
+ stack_t stacks; /* Stack info */
+#if CONFIG_TASK_NAME_SIZE > 0
+ char name[CONFIG_TASK_NAME_SIZE+1]; /* Task name (with NULL
+ * terminator) */
+#endif
+ char filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in
+ * __FILE__ to up_assert */
} info_s;
-typedef struct { /* The Context data */
- stack_t stack;
- process_t proc;
-} context_s;
-
typedef struct {
- info_s info; /* Then info */
- context_s context; /* The Context data */
+ info_s info; /* The info */
#if CONFIG_ARCH_INTERRUPTSTACK > 3 /* The amount of stack data is compile time
* sized backed on what is left after the
* other BBSRAM files are defined
@@ -378,6 +364,6 @@ int hardfault_increment_reboot(char *caller, bool reset);
#if defined(__cplusplus)
extern "C"
-}
+//}
#endif
diff --git a/src/systemcmds/hardfault_log/hardfault_log.c b/src/systemcmds/hardfault_log/hardfault_log.c
index e8f37335b..959ea4a3a 100644
--- a/src/systemcmds/hardfault_log/hardfault_log.c
+++ b/src/systemcmds/hardfault_log/hardfault_log.c
@@ -38,11 +38,13 @@
#include <nuttx/config.h>
#include <nuttx/compiler.h>
+#include <nuttx/arch.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdint.h>
+#include <stddef.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
@@ -65,7 +67,7 @@ __EXPORT int hardfault_log_main(int argc, char *argv[]);
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
-
+#define OUT_BUFFER_LEN 200
/****************************************************************************
* Private Types
****************************************************************************/
@@ -119,26 +121,6 @@ static int genfault(int fault)
/* This is not going to happen */
break;
- case 2:
- printf("null %s\n",NULL);
- /* This is not going to happen */
- break;
-
- case 3:
- {
- char marker[20];
- strncpy(marker, "<-- ", sizeof(marker));
- printf("nill %s\n","");
- printf("nill fault==3 %s\n",(fault==3) ? "3" : "");
- printf("nill fault!=3 %s\n",(fault!=3) ? "3" : "");
- printf("0x%08x 0x%08x%s\n", fault, -fault, (fault==3) ? "" : marker);
- printf("0x%08x 0x%08x%s\n", fault, -fault, (fault!=3) ? "" : marker);
- printf("0x%08x 0x%08x%s\n", fault, -fault, fault==3 ? "" : marker);
- printf("0x%08x 0x%08x%s\n", fault, -fault, fault!=3 ? "" : marker);
- }
- /* This is not going to happen */
- break;
-
default:
break;
@@ -237,106 +219,154 @@ static int hardfault_get_desc(char *caller, struct bbsramd_s *desc, bool silent)
/****************************************************************************
* write_stack_detail
****************************************************************************/
-static void write_stack_detail(int size, uint32_t topaddr, uint32_t spaddr,
- uint32_t botaddr, char *sp_name, char *buffer, int max, int fd)
+static int write_stack_detail(bool inValid, _stack_s *si, char *sp_name,
+ char *buffer, int max, int fd)
{
int n = 0;
- n = snprintf(&buffer[n], max-n, " %s stack:\n",sp_name);
- n += snprintf(&buffer[n], max-n, " top: 0x%08x\n", topaddr);
- n += snprintf(&buffer[n], max-n, " sp: 0x%08x\n", spaddr);
- write(fd, buffer,n);
+ uint32_t sbot = si->top - si->size;
+ n = snprintf(&buffer[n], max-n, " %s stack: \n",sp_name);
+ n += snprintf(&buffer[n], max-n, " top: 0x%08x\n", si->top);
+ n += snprintf(&buffer[n], max-n, " sp: 0x%08x %s\n", si->sp, (inValid ? "Invalid" : "Valid"));
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
n = 0;
- n += snprintf(&buffer[n], max-n, " bottom: 0x%08x\n", botaddr);
- n += snprintf(&buffer[n], max-n, " size: 0x%08x\n", size);
- write(fd, buffer,n);
-#ifndef CONFIG_STACK_COLORATION
+ n += snprintf(&buffer[n], max-n, " bottom: 0x%08x\n", sbot);
+ n += snprintf(&buffer[n], max-n, " size: 0x%08x\n", si->size);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
+#ifdef CONFIG_STACK_COLORATION
FAR struct tcb_s tcb;
- tcb.stack_alloc_ptr = (void*) botaddr;
- tcb.adj_stack_size = size;
+ tcb.stack_alloc_ptr = (void*) sbot;
+ tcb.adj_stack_size = si->size;
n = snprintf(buffer, max, " used: %08x\n", up_check_tcbstack(&tcb));
- write(fd, buffer,n);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
#endif
+ return OK;
}
/****************************************************************************
* write_stack
****************************************************************************/
-static void write_stack(stack_word_t *swindow, int winsize, uint32_t wtopaddr,
+static int read_stack(int fd, stack_word_t *words, int num)
+{
+ int bytes = read(fd, (char *) words, sizeof(stack_word_t) * num);
+ if (bytes > 0) {
+ bytes /= sizeof(stack_word_t);
+ }
+ return bytes;
+}
+static int write_stack(bool inValid, int winsize, uint32_t wtopaddr,
uint32_t topaddr, uint32_t spaddr, uint32_t botaddr,
- char *sp_name, char *buffer, int max, int fd)
+ char *sp_name, char *buffer, int max, int infd, int outfd)
{
- char marker[30];
- for (int i = winsize; i >= 0; i--) {
- if (wtopaddr == topaddr) {
- strncpy(marker, "<-- ", sizeof(marker));
- strncat(marker, sp_name, sizeof(marker));
- strncat(marker, " top", sizeof(marker));
- } else if (wtopaddr == spaddr) {
- strncpy(marker, "<-- ", sizeof(marker));
- strncat(marker, sp_name, sizeof(marker));
- } else if (wtopaddr == botaddr) {
- strncpy(marker, "<-- ", sizeof(marker));
- strncat(marker, sp_name, sizeof(marker));
- strncat(marker, " bottom", sizeof(marker));
- } else {
- marker[0] = '\0';
- }
- int n = snprintf(buffer, max,"0x%08x 0x%08x%s\n", wtopaddr, swindow[i], marker);
- write(fd, buffer,n);
- wtopaddr--;
- }
+ char marker[30];
+ stack_word_t stack[32];
+ int ret = OK;
+
+ int n = snprintf(buffer, max,"%s memory region, stack pointer lies %s stack\n",
+ sp_name, (inValid ? "outside of" : "within" ));
+ if (n != write(outfd, buffer, n)) {
+
+ ret = -EIO;
+
+ } else {
+
+ while(winsize > 0 && ret == OK) {
+ int chunk = read_stack(infd, stack, arraySize(stack));
+ if (chunk <= 0 ) {
+ ret = -EIO;
+ } else {
+ winsize -= chunk;
+ for (int i = 0; i < chunk; i++) {
+ if (wtopaddr == topaddr) {
+ strncpy(marker, "<-- ", sizeof(marker));
+ strncat(marker, sp_name, sizeof(marker));
+ strncat(marker, " top", sizeof(marker));
+ } else if (wtopaddr == spaddr) {
+ strncpy(marker, "<-- ", sizeof(marker));
+ strncat(marker, sp_name, sizeof(marker));
+ } else if (wtopaddr == botaddr) {
+ strncpy(marker, "<-- ", sizeof(marker));
+ strncat(marker, sp_name, sizeof(marker));
+ strncat(marker, " bottom", sizeof(marker));
+ } else {
+ marker[0] = '\0';
+ }
+ n = snprintf(buffer, max,"0x%08x 0x%08x%s\n", wtopaddr, stack[i], marker);
+ if (n != write(outfd, buffer, n)) {
+ ret = -EIO;
+ }
+ wtopaddr--;
+ }
+ }
+ }
+ }
+ return ret;
}
/****************************************************************************
* write_registers
****************************************************************************/
-static void write_registers(fullcontext_s* fc, char *buffer, int max, int fd)
+static int write_registers(uint32_t regs[], char *buffer, int max, int fd)
{
int n = snprintf(buffer, max, " r0:0x%08x r1:0x%08x r2:0x%08x r3:0x%08x r4:0x%08x r5:0x%08x r6:0x%08x r7:0x%08x\n",
- fc->context.proc.xcp.regs[REG_R0], fc->context.proc.xcp.regs[REG_R1],
- fc->context.proc.xcp.regs[REG_R2], fc->context.proc.xcp.regs[REG_R3],
- fc->context.proc.xcp.regs[REG_R4], fc->context.proc.xcp.regs[REG_R5],
- fc->context.proc.xcp.regs[REG_R6], fc->context.proc.xcp.regs[REG_R7]);
+ regs[REG_R0], regs[REG_R1],
+ regs[REG_R2], regs[REG_R3],
+ regs[REG_R4], regs[REG_R5],
+ regs[REG_R6], regs[REG_R7]);
- write(fd, buffer,n);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
n = snprintf(buffer, max, " r8:0x%08x r9:0x%08x r10:0x%08x r11:0x%08x r12:0x%08x sp:0x%08x lr:0x%08x pc:0x%08x\n",
- fc->context.proc.xcp.regs[REG_R8], fc->context.proc.xcp.regs[REG_R9],
- fc->context.proc.xcp.regs[REG_R10], fc->context.proc.xcp.regs[REG_R11],
- fc->context.proc.xcp.regs[REG_R12], fc->context.proc.xcp.regs[REG_R13],
- fc->context.proc.xcp.regs[REG_R14], fc->context.proc.xcp.regs[REG_R15]);
+ regs[REG_R8], regs[REG_R9],
+ regs[REG_R10], regs[REG_R11],
+ regs[REG_R12], regs[REG_R13],
+ regs[REG_R14], regs[REG_R15]);
- write(fd, buffer,n);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
#ifdef CONFIG_ARMV7M_USEBASEPRI
n = snprintf(buffer, max, " xpsr:0x%08x basepri:0x%08x control:0x%08x\n",
- fc->context.proc.xcp.regs[REG_XPSR], fc->context.proc.xcp.regs[REG_BASEPRI],
+ regs[REG_XPSR], regs[REG_BASEPRI],
getcontrol());
#else
n = snprintf(buffer, max, " xpsr:0x%08x primask:0x%08x control:0x%08x\n",
- fc->context.proc.xcp.regs[REG_XPSR], fc->context.proc.xcp.regs[REG_PRIMASK],
+ regs[REG_XPSR], regs[REG_PRIMASK],
getcontrol());
#endif
- write(fd, buffer,n);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
#ifdef REG_EXC_RETURN
- n = snprintf(buffer, max, " exe return:0x%08x\n", fc->context.proc.xcp.regs[REG_EXC_RETURN]);
- write(fd, buffer,n);
+ n = snprintf(buffer, max, " exe return:0x%08x\n", regs[REG_EXC_RETURN]);
+ if (n != write(fd, buffer, n)) {
+ return -EIO;
+ }
#endif
+ return OK;
}
/****************************************************************************
* write_registers_info
****************************************************************************/
-static int write_registers_info(int fdout, fullcontext_s *fc, char *buffer,
- int sz)
+static int write_registers_info(int fdout, info_s *pi , char *buffer, int sz)
{
int ret = -ENOENT;
- if (fc->info.stuff & eRegs) {
- int n = snprintf(buffer, sz, " Processor registers: from 0x%08x\n", fc->info.current_regs);
- write(fdout, buffer,n);
- write_registers(fc, buffer, sz, fdout);
- ret = OK;
+ if (pi->flags & eRegs) {
+ ret = -EIO;
+ int n = snprintf(buffer, sz, " Processor registers: from 0x%08x\n", pi->current_regs);
+ if (n == write(fdout, buffer, n)) {
+ ret = write_registers(pi->regs, buffer, sz, fdout);
+ }
}
return ret;
}
@@ -344,18 +374,14 @@ static int write_registers_info(int fdout, fullcontext_s *fc, char *buffer,
/****************************************************************************
* write_interrupt_stack_info
****************************************************************************/
-static int write_interrupt_stack_info(int fdout, fullcontext_s *fc, char *buffer,
- unsigned int sz)
+static int write_interrupt_stack_info(int fdout, info_s *pi, char *buffer,
+ unsigned int sz)
{
int ret = -ENOENT;
- if (fc->info.stuff & eIntStack) {
- write_stack_detail(fc->context.stack.istacksize,
- fc->context.stack.itopofstack,
- fc->context.stack.current_sp,
- fc->context.stack.itopofstack - fc->context.stack.istacksize,
- "IRQ",
- buffer, sz, fdout);
- ret = OK;
+ if (pi->flags & eIntStack) {
+ ret = write_stack_detail((pi->flags & eInvalidIntStack) != 0,
+ &pi->stacks.interrupt, "IRQ",
+ buffer, sz, fdout);
}
return ret;
}
@@ -363,18 +389,13 @@ static int write_interrupt_stack_info(int fdout, fullcontext_s *fc, char *buffer
/****************************************************************************
* write_user_stack_info
****************************************************************************/
-static int write_user_stack_info(int fdout, fullcontext_s *fc, char *buffer,
- unsigned int sz)
+static int write_user_stack_info(int fdout, info_s *pi, char *buffer,
+ unsigned int sz)
{
int ret = -ENOENT;
- if (fc->info.stuff & eUserStack) {
- write_stack_detail(fc->context.stack.ustacksize,
- fc->context.stack.utopofstack,
- fc->context.proc.xcp.regs[REG_R13],
- fc->context.stack.utopofstack - fc->context.stack.ustacksize,
- "User",
- buffer, sz, fdout);
- ret = OK;
+ if (pi->flags & eUserStack) {
+ ret = write_stack_detail((pi->flags & eInvalidUserStack) != 0,
+ &pi->stacks.user, "User", buffer, sz, fdout);
}
return ret;
}
@@ -382,81 +403,97 @@ static int write_user_stack_info(int fdout, fullcontext_s *fc, char *buffer,
/****************************************************************************
* write_dump_info
****************************************************************************/
-static void write_dump_info(int fdout, fullcontext_s *fc, struct timespec *ts,
+static int write_dump_info(int fdout, info_s *info, struct bbsramd_s * desc,
char *buffer, unsigned int sz)
{
char fmtbuff[ TIME_FMT_LEN + 1];
- format_fault_time(HEADER_TIME_FMT, ts, fmtbuff, sizeof(fmtbuff));
+ format_fault_time(HEADER_TIME_FMT, &desc->lastwrite, fmtbuff, sizeof(fmtbuff));
- bool isFault = (fc->info.current_regs != 0 || fc->context.proc.pid == 0);
+ bool isFault = (info->current_regs != 0 || info->pid == 0);
int n;
n = snprintf(buffer, sz, "System fault Occurred on: %s\n", fmtbuff);
- write(fdout, buffer, n);
+
+ if (n != write(fdout, buffer, n)) {
+ return -EIO;
+ }
+
if (isFault) {
n = snprintf(buffer, sz, " Type:Hard Fault");
} else {
n = snprintf(buffer, sz, " Type:Assertion failed");
}
- write(fdout, buffer, n);
+ if (n != write(fdout, buffer, n)) {
+ return -EIO;
+ }
#ifdef CONFIG_TASK_NAME_SIZE
n = snprintf(buffer, sz, " in file:%s at line: %d running task: %s\n",
- fc->info.filename, fc->info.lineno, fc->context.proc.name);
+ info->filename, info->lineno, info->name);
#else
n = snprintf(buffer, sz, " in file:%s at line: %d \n",
- fc->info.filename, fc->info.lineno);
+ info->filename, info->lineno);
#endif
- write(fdout, buffer, n);
+ if (n != write(fdout, buffer, n)) {
+ return -EIO;
+ }
n = snprintf(buffer, sz, " FW git-hash: %s\n", FW_GIT);
- write(fdout, buffer, n);
+ if (n != write(fdout, buffer, n)) {
+ return -EIO;
+ }
n = snprintf(buffer, sz, " Build datetime: %s %s\n", __DATE__, __TIME__);
- write(fdout, buffer, n);
-
+ if (n != write(fdout, buffer, n)) {
+ return -EIO;
+ }
+ return OK;
}
/****************************************************************************
* write_dump_time
****************************************************************************/
-static void write_dump_time(char *caller, char *tag, int fdout,
+static int write_dump_time(char *caller, char *tag, int fdout,
struct timespec *ts, char *buffer, unsigned int sz)
{
+ int ret = OK;
char fmtbuff[ TIME_FMT_LEN + 1];
format_fault_time(HEADER_TIME_FMT, ts, fmtbuff, sizeof(fmtbuff));
int n = snprintf(buffer, sz, "[%s] -- %s %s Fault Log --\n",caller, fmtbuff, tag);
- write(fdout, buffer, n);
+ if (n != write(fdout, buffer, n)) {
+ ret = -EIO;
+ }
+ return ret;
}
/****************************************************************************
* write_dump_footer
****************************************************************************/
-static void write_dump_header(char * caller, int fdout, struct timespec *ts,
+static int write_dump_header(char * caller, int fdout, struct timespec *ts,
char *buffer, unsigned int sz)
{
- write_dump_time(caller, "Begin", fdout, ts, buffer, sz);
+ return write_dump_time(caller, "Begin", fdout, ts, buffer, sz);
}
/****************************************************************************
* write_dump_footer
****************************************************************************/
-static void write_dump_footer(char * caller, int fdout, struct timespec *ts,
- char *buffer, unsigned int sz)
+static int write_dump_footer(char * caller, int fdout, struct timespec *ts,
+ char *buffer, unsigned int sz)
{
- write_dump_time(caller, "END", fdout, ts, buffer, sz);
+ return write_dump_time(caller, "END", fdout, ts, buffer, sz);
}
/****************************************************************************
* write_intterupt_satck
****************************************************************************/
-static int write_intterupt_stack(int fdout, fullcontext_s *fc, char *buffer,
+static int write_intterupt_stack(int fdin, int fdout, info_s *pi, char *buffer,
unsigned int sz)
{
int ret = -ENOENT;
- if ((fc->info.stuff & eIntStack) != 0) {
- int winsize = arraySize(fc->istack);
- int wtopaddr = fc->context.stack.current_sp + winsize/2;
- write_stack(fc->istack, winsize, wtopaddr,
- fc->context.stack.itopofstack,
- fc->context.stack.current_sp,
- fc->context.stack.itopofstack - fc->context.stack.istacksize,
- "Interrupt sp", buffer, sz, fdout);
- ret = OK;
+ if ((pi->flags & eIntStack) != 0) {
+ lseek(fdin, offsetof(fullcontext_s, istack), SEEK_SET);
+ ret = write_stack((pi->flags & eInvalidIntStack) != 0,
+ CONFIG_ISTACK_SIZE,
+ pi->stacks.interrupt.sp + CONFIG_ISTACK_SIZE/2,
+ pi->stacks.interrupt.top,
+ pi->stacks.interrupt.sp,
+ pi->stacks.interrupt.top - pi->stacks.interrupt.size,
+ "Interrupt sp", buffer, sz, fdin, fdout);
}
return ret;
@@ -466,19 +503,19 @@ static int write_intterupt_stack(int fdout, fullcontext_s *fc, char *buffer,
/****************************************************************************
* write_user_stack
****************************************************************************/
-static int write_user_stack(int fdout, fullcontext_s *fc, char *buffer,
+static int write_user_stack(int fdin, int fdout, info_s *pi, char *buffer,
unsigned int sz)
{
int ret = -ENOENT;
- if ((fc->info.stuff & eUserStack) != 0) {
- int winsize = arraySize(fc->ustack);
- int wtopaddr = fc->context.proc.xcp.regs[REG_R13] + winsize/2;
- write_stack(fc->ustack, winsize, wtopaddr,
- fc->context.stack.utopofstack,
- fc->context.proc.xcp.regs[REG_R13],
- fc->context.stack.utopofstack - fc->context.stack.ustacksize,
- "User sp", buffer, sz, fdout);
- ret = OK;
+ if ((pi->flags & eUserStack) != 0) {
+ lseek(fdin,offsetof(fullcontext_s, ustack), SEEK_SET);
+ ret = write_stack((pi->flags & eInvalidUserStack) != 0,
+ CONFIG_USTACK_SIZE,
+ pi->stacks.user.sp + CONFIG_USTACK_SIZE/2,
+ pi->stacks.user.top,
+ pi->stacks.user.sp,
+ pi->stacks.user.top - pi->stacks.user.size,
+ "User sp", buffer, sz, fdin, fdout);
}
return ret;
@@ -494,7 +531,9 @@ static int hardfault_commit(char *caller)
struct bbsramd_s desc;
char path[LOG_PATH_LEN+1];
ret = hardfault_get_desc(caller, &desc, false);
+
if (ret >= 0) {
+
int fd = ret;
state = (desc.lastwrite.tv_sec || desc.lastwrite.tv_nsec) ? OK : 1;
int rv = close(fd);
@@ -502,30 +541,109 @@ static int hardfault_commit(char *caller)
identify(caller);
syslog(LOG_INFO, "Failed to Close Fault Log (%d)\n",rv);
} else {
+
if (state != OK) {
identify(caller);
syslog(LOG_INFO, "Nothing to save\n",path);
ret = -ENOENT;
} else {
- ret = format_fault_file_name(&desc.lastwrite, path, arraySize(path));
- if (ret == OK) {
- int fdout = open(path, O_RDWR | O_CREAT);
- if (fdout > 0) {
- identify(caller);
- syslog(LOG_INFO, "Saving Fault Log file %s\n",path);
- ret = hardfault_write(caller, fdout, HARDFAULT_FILE_FORMAT, true);
- identify(caller);
- syslog(LOG_INFO, "Done saving Fault Log file\n");
- close(fdout);
- }
-
- }
+ ret = format_fault_file_name(&desc.lastwrite, path, arraySize(path));
+ if (ret == OK) {
+ int fdout = open(path, O_RDWR | O_CREAT);
+ if (fdout > 0) {
+ identify(caller);
+ syslog(LOG_INFO, "Saving Fault Log file %s\n",path);
+ ret = hardfault_write(caller, fdout, HARDFAULT_FILE_FORMAT, true);
+ identify(caller);
+ syslog(LOG_INFO, "Done saving Fault Log file\n");
+ close(fdout);
+ }
+ }
}
}
}
return ret;
}
+
+/****************************************************************************
+ * hardfault_dowrite
+ ****************************************************************************/
+static int hardfault_dowrite(char * caller, int infd, int outfd,
+ struct bbsramd_s *desc, int format)
+{
+ int ret = -ENOMEM;
+ char *line = zalloc(OUT_BUFFER_LEN);
+ if (line) {
+ char *info = zalloc(sizeof(info_s));
+ if (info) {
+ lseek(infd, offsetof(fullcontext_s, info), SEEK_SET);
+ ret = read(infd, info, sizeof(info_s));
+ if (ret < 0) {
+ identify(caller);
+ syslog(LOG_INFO, "Failed to read Fault Log file [%s] (%d)\n", HARDFAULT_PATH, ret);
+ ret = -EIO;
+ } else {
+ info_s *pinfo = (info_s *) info;
+ ret = write_dump_header(caller, outfd, &desc->lastwrite, line, OUT_BUFFER_LEN);
+ if (ret == OK) {
+
+ switch(format) {
+ case HARDFAULT_DISPLAY_FORMAT:
+ ret = write_intterupt_stack(infd, outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_user_stack(infd, outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_dump_info(outfd, pinfo, desc, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_registers_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_interrupt_stack_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_user_stack_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case HARDFAULT_FILE_FORMAT:
+ ret = write_dump_info(outfd, pinfo, desc, line, OUT_BUFFER_LEN);
+ if (ret == OK) {
+ ret = write_registers_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_interrupt_stack_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_user_stack_info(outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_intterupt_stack(infd, outfd, pinfo, line, OUT_BUFFER_LEN);
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_user_stack(infd, outfd, pinfo, line, OUT_BUFFER_LEN);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ }
+ if (ret == OK || ret == -ENOENT) {
+ ret = write_dump_footer(caller, outfd, &desc->lastwrite, line, OUT_BUFFER_LEN);
+ }
+ }
+ free(info);
+ }
+ free(line);
+ }
+ return ret;
+}
+
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -602,75 +720,80 @@ __EXPORT int hardfault_increment_reboot(char *caller, bool reset)
identify(caller);
syslog(LOG_INFO, "Failed to open Fault reboot count file [%s] (%d)\n", HARDFAULT_REBOOT_PATH, ret);
} else {
+
+ ret = OK;
if (!reset) {
- read(fd, &count, sizeof(count));
- lseek(fd, 0, SEEK_SET);
- count++;
+ if (read(fd, &count, sizeof(count)) != sizeof(count)) {
+ ret = -EIO;
+ close(fd);
+ } else {
+ lseek(fd, 0, SEEK_SET);
+ count++;
+ }
+ }
+
+ if (ret == OK) {
+ ret = write(fd, &count, sizeof(count));
+ if (ret != sizeof(count)) {
+ ret = -EIO;
+ } else {
+ ret = close(fd);
+ if (ret == OK) {
+ ret = count;
+ }
+ }
}
- ret = write(fd, &count, sizeof(count));
- close(fd);
- ret = count;
}
return ret;
}
/****************************************************************************
* hardfault_write
****************************************************************************/
-fullcontext_s dump;
__EXPORT int hardfault_write(char *caller, int fd, int format, bool rearm)
{
- char line[200];
- memset(&dump,0,sizeof(dump));
struct bbsramd_s desc;
+
+ switch(format) {
+
+ case HARDFAULT_FILE_FORMAT:
+ case HARDFAULT_DISPLAY_FORMAT:
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
int ret = hardfault_get_desc(caller, &desc, false);
if (ret >= 0) {
int hffd = ret;
- ret = read(hffd, (char *)&dump, sizeof(dump));
+
+
+ int rv = hardfault_dowrite(caller, hffd, fd, &desc, format);
+
+ ret = close(hffd);
if (ret < 0) {
identify(caller);
- syslog(LOG_INFO, "Failed to read Fault Log file [%s] (%d)\n", HARDFAULT_PATH, ret);
- } else {
- ret = close(hffd);
- if (ret < 0) {
- identify(caller);
- syslog(LOG_INFO, "Failed to Close Fault Log (%d)\n", ret);
+ syslog(LOG_INFO, "Failed to Close Fault Log (%d)\n", ret);
- } else {
-
- switch(format) {
- case HARDFAULT_DISPLAY_FORMAT:
- write_dump_header(caller, fd, &desc.lastwrite,line, arraySize(line));
- write_intterupt_stack(fd, &dump, line, arraySize(line));
- write_user_stack(fd, &dump, line, arraySize(line));
- write_dump_info(fd, &dump, &desc.lastwrite, line, arraySize(line));
- write_registers_info(fd, &dump, line, arraySize(line));
- write_interrupt_stack_info(fd, &dump, line, arraySize(line));
- write_user_stack_info(fd, &dump, line, arraySize(line));
- break;
-
- case HARDFAULT_FILE_FORMAT:
- write_dump_header(caller, fd, &desc.lastwrite,line, arraySize(line));
- write_dump_info(fd, &dump, &desc.lastwrite, line, arraySize(line));
- write_registers_info(fd, &dump, line, arraySize(line));
- write_interrupt_stack_info(fd, &dump, line, arraySize(line));
- write_user_stack_info(fd, &dump,line, arraySize(line));
- write_intterupt_stack(fd, &dump,line, arraySize(line));
- write_user_stack(fd, &dump, line, arraySize(line));
- break;
-
- default:
- return -EINVAL;
- break;
- }
+ }
- write_dump_footer(caller, fd, &desc.lastwrite,line, arraySize(line));
+ if (rv == OK && rearm) {
+ ret = hardfault_rearm(caller);
+ if (ret < 0) {
+ identify(caller);
+ syslog(LOG_INFO, "Failed to re-arm Fault Log (%d)\n", ret);
+ }
+ }
- if (rearm) {
- ret = hardfault_rearm(caller);
+ if (ret == OK) {
+ ret = rv;
+ }
- }
- }
+ if (ret != OK)
+ {
+ identify(caller);
+ syslog(LOG_INFO, "Failed to Write Fault Log (%d)\n", ret);
}
}
return ret;