Skip to content

Commit 6181394

Browse files
committed
Error and fault handling changes for crash reporting
1 parent d643034 commit 6181394

File tree

10 files changed

+345
-29
lines changed

10 files changed

+345
-29
lines changed

cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ Fault_Handler PROC
8080

8181
Fault_Handler_Continue
8282
MOV R12,R3
83-
LDR R1,=mbed_fault_context
83+
LDR R3,=mbed_fault_context
84+
LDR R1,[R3]
8485
LDR R2,[R0] ; Capture R0
8586
STR R2,[R1]
8687
ADDS R1,#4

cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ Fault_Handler:
113113

114114
Fault_Handler_Continue:
115115
MOV R12,R3
116-
LDR R1,=mbed_fault_context
116+
LDR R3,=mbed_fault_context
117+
LDR R1,[R3]
117118
LDR R2,[R0] // Capture R0
118119
STR R2,[R1]
119120
ADDS R1,#4

cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ Fault_Handler
7575

7676
Fault_Handler_Continue
7777
MOV R12,R3
78-
LDR R1,=mbed_fault_context
78+
LDR R3,=mbed_fault_context
79+
LDR R1,[R3]
7980
LDR R2,[R0] ; Capture R0
8081
STR R2,[R1]
8182
ADDS R1,#4

cmsis/TARGET_CORTEX_M/mbed_fault_handler.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,23 @@
2020
#include <inttypes.h>
2121

2222
#include "device.h"
23-
#include "platform/mbed_error.h"
24-
#include "platform/mbed_interface.h"
23+
#include "mbed_error.h"
24+
#include "mbed_interface.h"
25+
#include "mbed_crash_data_offsets.h"
2526

2627
#ifndef MBED_FAULT_HANDLER_DISABLED
2728
#include "mbed_fault_handler.h"
2829

2930
//Functions Prototypes
3031
void print_context_info(void);
3132

32-
//Global for populating the context in exception handler
33-
mbed_fault_context_t mbed_fault_context;
33+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
34+
//Global for populating the context in exception handler
35+
mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)((uint32_t)FAULT_CONTEXT_LOCATION);
36+
#else
37+
mbed_fault_context_t fault_context;
38+
mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)&fault_context;
39+
#endif
3440

3541
//This is a handler function called from Fault handler to print the error information out.
3642
//This runs in fault context and uses special functions(defined in mbed_rtx_fault_handler.c) to print the information without using C-lib support.
@@ -69,24 +75,24 @@ void mbed_fault_handler (uint32_t fault_type, void *mbed_fault_context_in)
6975
mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n");
7076

7177
//Now call mbed_error, to log the error and halt the system
72-
mbed_error( faultStatus, "Fault exception", mbed_fault_context.PC_reg, NULL, 0 );
78+
mbed_error( faultStatus, "Fault exception", mbed_fault_context->PC_reg, NULL, 0 );
7379

7480
}
7581

7682
MBED_NOINLINE void print_context_info(void)
7783
{
7884
//Context Regs
7985
for(int i=0;i<13;i++) {
80-
mbed_error_printf("\nR%-4d: %08" PRIX32, i, ((uint32_t *)&mbed_fault_context)[i]);
86+
mbed_error_printf("\nR%-4d: %08" PRIX32, i, ((uint32_t *)(mbed_fault_context))[i]);
8187
}
8288

8389
mbed_error_printf("\nSP : %08" PRIX32
8490
"\nLR : %08" PRIX32
8591
"\nPC : %08" PRIX32
8692
"\nxPSR : %08" PRIX32
8793
"\nPSP : %08" PRIX32
88-
"\nMSP : %08" PRIX32, mbed_fault_context.SP_reg, mbed_fault_context.LR_reg, mbed_fault_context.PC_reg,
89-
mbed_fault_context.xPSR, mbed_fault_context.PSP, mbed_fault_context.MSP );
94+
"\nMSP : %08" PRIX32, mbed_fault_context->SP_reg, mbed_fault_context->LR_reg, mbed_fault_context->PC_reg,
95+
mbed_fault_context->xPSR, mbed_fault_context->PSP, mbed_fault_context->MSP );
9096

9197
//Capture CPUID to get core/cpu info
9298
mbed_error_printf("\nCPUID: %08" PRIX32, SCB->CPUID);
@@ -112,12 +118,12 @@ MBED_NOINLINE void print_context_info(void)
112118
#endif
113119

114120
//Print Mode
115-
if (mbed_fault_context.EXC_RETURN & 0x8) {
121+
if (mbed_fault_context->EXC_RETURN & 0x8) {
116122
mbed_error_printf("\nMode : Thread");
117123
//Print Priv level in Thread mode - We capture CONTROL reg which reflects the privilege.
118124
//Note that the CONTROL register captured still reflects the privilege status of the
119125
//thread mode eventhough we are in Handler mode by the time we capture it.
120-
if(mbed_fault_context.CONTROL & 0x1) {
126+
if(mbed_fault_context->CONTROL & 0x1) {
121127
mbed_error_printf("\nPriv : User");
122128
} else {
123129
mbed_error_printf("\nPriv : Privileged");
@@ -127,11 +133,23 @@ MBED_NOINLINE void print_context_info(void)
127133
mbed_error_printf("\nPriv : Privileged");
128134
}
129135
//Print Return Stack
130-
if (mbed_fault_context.EXC_RETURN & 0x4) {
136+
if (mbed_fault_context->EXC_RETURN & 0x4) {
131137
mbed_error_printf("\nStack: PSP");
132138
} else {
133139
mbed_error_printf("\nStack: MSP");
134140
}
135141
}
136142

143+
mbed_error_status_t mbed_get_reboot_fault_context (mbed_fault_context_t *fault_context)
144+
{
145+
mbed_error_status_t status = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_ITEM_NOT_FOUND);
146+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
147+
if(fault_context == NULL)
148+
return MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT);
149+
memcpy(fault_context, mbed_fault_context, sizeof(mbed_fault_context_t));
150+
status = MBED_SUCCESS;
151+
#endif
152+
return status;
153+
}
154+
137155
#endif //MBED_FAULT_HANDLER_SUPPORT

cmsis/TARGET_CORTEX_M/mbed_fault_handler.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
*/
1616

1717
#ifndef MBED_FAULT_HANDLER_H
18-
#define MBED_FAULT_HANDLER_H
18+
#define MBED_FAULT_HANDLER_H
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
1923

2024
//Fault context struct
2125
//WARNING: DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES in except.S files.
@@ -55,4 +59,18 @@ typedef struct {
5559
//This runs in fault context and uses special functions(defined in mbed_fault_handler.c) to print the information without using C-lib support.
5660
void mbed_fault_handler (uint32_t fault_type, void *mbed_fault_context_in);
5761

62+
/**
63+
* Call this function to retrieve the fault context after a fatal exception which triggered a system reboot. The function retrieves the fault context stored in crash-report ram area which is preserved over reboot.
64+
* @param fault_context Pointer to mbed_fault_context_t struct allocated by the caller. This is the mbed_fault_context_t info captured as part of the fatal exception which triggered the reboot.
65+
* @return 0 or MBED_SUCCESS on success.
66+
* MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer
67+
* MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by teh system
68+
*
69+
*/
70+
mbed_error_status_t mbed_get_reboot_fault_context (mbed_fault_context_t *fault_context);
71+
72+
#ifdef __cplusplus
73+
}
74+
#endif
75+
5876
#endif

platform/mbed_crash_data_offsets.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2013 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifndef MBED_CRASH_DATA_INFO_H
17+
#define MBED_CRASH_DATA_INFO_H
18+
19+
#include "platform/mbed_retarget.h"
20+
#include "platform/mbed_toolchain.h"
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
27+
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
28+
extern uint32_t Image$$RW_m_crash_data$$ZI$$Base[];
29+
extern uint32_t Image$$RW_m_crash_data$$ZI$$Size;
30+
#define __CRASH_DATA_RAM_START__ Image$$RW_m_crash_data$$ZI$$Base
31+
#define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size
32+
#elif defined(__ICCARM__)
33+
extern uint32_t __CRASH_DATA_RAM_START__[];
34+
extern uint32_t __CRASH_DATA_RAM_END__[];
35+
#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__)
36+
#elif defined(__GNUC__)
37+
extern uint32_t __CRASH_DATA_RAM_START__[];
38+
extern uint32_t __CRASH_DATA_RAM_END__[];
39+
#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__)
40+
#endif /* defined(__CC_ARM) */
41+
42+
/* Offset definitions for context capture */
43+
#define FAULT_CONTEXT_OFFSET (0x0)
44+
#define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context
45+
#define ERROR_CONTEXT_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE)
46+
#define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context
47+
#define FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET)
48+
#define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET)
49+
#endif
50+
51+
#ifdef __cplusplus
52+
}
53+
#endif
54+
55+
#endif
56+
57+
58+

0 commit comments

Comments
 (0)