Skip to content

Commit b6a7a08

Browse files
committed
Streamline crash data access
Use correctly-typed external definition for the crash data region, and eliminate unnecessary pointer indirection. Results in a small ROM saving even with crash capture disabled, as there was a pointer for the fault context store in either case. The pointer isn't needed, as the context store location is fixed according to the configuration flag.
1 parent 03ce919 commit b6a7a08

File tree

8 files changed

+112
-64
lines changed

8 files changed

+112
-64
lines changed

TESTS/mbed_platform/crash_reporting/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static mbed_error_ctx saved_error_ctx = {0};
3636
void mbed_error_reboot_callback(mbed_error_ctx *error_context)
3737
{
3838

39-
TEST_ASSERT_EQUAL_UINT((uint32_t)error_context, ERROR_CONTEXT_LOCATION);
39+
TEST_ASSERT_EQUAL_PTR(error_context, &MBED_CRASH_DATA);
4040
memcpy(&saved_error_ctx, error_context, sizeof(mbed_error_ctx));
4141
mbed_reset_reboot_error_info();
4242

platform/source/TARGET_CORTEX_M/mbed_fault_handler.h renamed to platform/internal/mbed_fault_handler.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818
#ifndef MBED_FAULT_HANDLER_H
1919
#define MBED_FAULT_HANDLER_H
2020

21+
#include "mbed_toolchain.h"
22+
#include "mbed_error.h"
23+
2124
#ifdef __cplusplus
2225
extern "C" {
2326
#endif
2427

2528
//Fault context struct
29+
#ifdef TARGET_CORTEX_M
2630
//WARNING: DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES in except.S files.
2731
//Offset of these registers are used by fault handler in except.S
2832
typedef struct {
@@ -48,13 +52,44 @@ typedef struct {
4852
uint32_t EXC_RETURN;
4953
uint32_t CONTROL;
5054
} mbed_fault_context_t;
55+
#elif defined TARGET_CORTEX_A
56+
// This is not currently used, but would be a plausible implementation
57+
typedef struct {
58+
uint32_t R0_reg;
59+
uint32_t R1_reg;
60+
uint32_t R2_reg;
61+
uint32_t R3_reg;
62+
uint32_t R4_reg;
63+
uint32_t R5_reg;
64+
uint32_t R6_reg;
65+
uint32_t R7_reg;
66+
uint32_t R8_reg;
67+
uint32_t R9_reg;
68+
uint32_t R10_reg;
69+
uint32_t R11_reg;
70+
uint32_t R12_reg;
71+
uint32_t SP_reg;
72+
uint32_t LR_reg;
73+
uint32_t PC_reg;
74+
uint32_t CPSR;
75+
uint32_t SP_usr;
76+
uint32_t LR_usr;
77+
} mbed_fault_context_t;
78+
#else
79+
// Dummy for mbed_crash_data_t
80+
typedef struct {
81+
} mbed_fault_context_t;
82+
#endif
83+
5184

5285
//Fault type definitions
86+
#ifdef TARGET_CORTEX_M
5387
//WARNING: DO NOT CHANGE THESE VALUES WITHOUT MAKING CORRESPONDING CHANGES in except.S files.
5488
#define HARD_FAULT_EXCEPTION (0x10) //Keep some gap between values for any future insertion/expansion
5589
#define MEMMANAGE_FAULT_EXCEPTION (0x20)
5690
#define BUS_FAULT_EXCEPTION (0x30)
5791
#define USAGE_FAULT_EXCEPTION (0x40)
92+
#endif
5893

5994
//This is a handler function called from Fault handler to print the error information out.
6095
//This runs in fault context and uses special functions(defined in mbed_fault_handler.c) to print the information without using C-lib support.
@@ -65,7 +100,7 @@ MBED_NORETURN void mbed_fault_handler(uint32_t fault_type, const mbed_fault_cont
65100
* @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.
66101
* @return 0 or MBED_SUCCESS on success.
67102
* MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer
68-
* MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by teh system
103+
* MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system
69104
*
70105
*/
71106
mbed_error_status_t mbed_get_reboot_fault_context(mbed_fault_context_t *fault_context);

platform/source/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ Fault_Handler\
6969
PROC
7070
EXPORT Fault_Handler
7171
#if (DOMAIN_NS == 1)
72+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
73+
#define mbed_fault_context |Image$$RW_m_crash_data$$ZI$$Base|
74+
#endif
7275
IMPORT mbed_fault_context
7376
IMPORT mbed_fault_handler
7477

@@ -82,7 +85,6 @@ Fault_Handler\
8285

8386
Fault_Handler_Continue
8487
LDR R7,=mbed_fault_context
85-
LDR R7,[R7]
8688
LDMIA R6!,{R0-R3}
8789
STMIA R7!,{R0-R3} ; Capture R0..R3
8890
POP {R0-R3}
@@ -110,8 +112,7 @@ Fault_Handler_Continue2
110112
MRS R6,CONTROL
111113
STMIA R7!,{R0,R1,R5,R6} ; Capture PSP,MSP,EXC_RETURN,CONTROL
112114
MOV R0,R12
113-
MOVS R1,R7
114-
SUBS R1,#21*4
115+
LDR R1,=mbed_fault_context
115116
BL mbed_fault_handler ; mbed_fault_handler does not return
116117
#else
117118
B .

platform/source/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ UsageFault_Handler:
104104

105105
Fault_Handler:
106106
#if (DOMAIN_NS == 1)
107+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
108+
#define mbed_fault_context __CRASH_DATA_RAM_START__
109+
#endif
110+
107111
MOV R12,R3
108112
PUSH {R4-R7}
109113
ADD R6,SP,#16
@@ -114,7 +118,6 @@ Fault_Handler:
114118

115119
Fault_Handler_Continue:
116120
LDR R7,=mbed_fault_context
117-
LDR R7,[R7]
118121
LDMIA R6!,{R0-R3}
119122
STMIA R7!,{R0-R3} // Capture R0..R3
120123
POP {R0-R3}
@@ -143,8 +146,7 @@ Fault_Handler_Continue2:
143146
MRS R6,CONTROL
144147
STMIA R7!,{R0,R1,R5,R6} // Capture PSP,MSP,EXC_RETURN,CONTROL
145148
MOV R0,R12
146-
MOV R1,R7
147-
SUBS R1,R1,#21*4
149+
LDR R1,=mbed_fault_context
148150
BL mbed_fault_handler // mbed_fault_handler does not return
149151
#else
150152
B .

platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ UsageFault_Handler
6363
Fault_Handler
6464
EXPORT Fault_Handler
6565
#if (DOMAIN_NS == 1)
66+
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
67+
#define mbed_fault_context __CRASH_DATA_RAM_START__
68+
#endif
6669
IMPORT mbed_fault_context
6770
IMPORT mbed_fault_handler
6871

@@ -76,7 +79,6 @@ Fault_Handler
7679

7780
Fault_Handler_Continue
7881
LDR R7,=mbed_fault_context
79-
LDR R7,[R7]
8082
LDMIA R6!,{R0-R3}
8183
STMIA R7!,{R0-R3} ; Capture R0..R3
8284
POP {R0-R3}
@@ -104,8 +106,7 @@ Fault_Handler_Continue2
104106
MRS R6,CONTROL
105107
STMIA R7!,{R0,R1,R5,R6} ; Capture PSP,MSP,EXC_RETURN,CONTROL
106108
MOV R0,R12
107-
MOVS R1,R7
108-
SUBS R1,#21*4
109+
LDR R1,=mbed_fault_context
109110
BL mbed_fault_handler ; mbed_fault_handler does not return
110111
#else
111112
B .

platform/source/TARGET_CORTEX_M/mbed_fault_handler.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@
3434
void print_context_info(void);
3535

3636
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
37-
//Global for populating the context in exception handler
38-
mbed_fault_context_t *const mbed_fault_context = (mbed_fault_context_t *)(FAULT_CONTEXT_LOCATION);
37+
#define mbed_fault_context MBED_CRASH_DATA.fault.context
3938
#else
40-
mbed_fault_context_t fault_context;
41-
mbed_fault_context_t *const mbed_fault_context = &fault_context;
39+
mbed_fault_context_t mbed_fault_context;
4240
#endif
4341

4442
extern bool mbed_error_in_progress;
@@ -94,16 +92,16 @@ MBED_NOINLINE void print_context_info(void)
9492
{
9593
//Context Regs
9694
for (int i = 0; i < 13; i++) {
97-
mbed_error_printf("\nR%-4d: %08" PRIX32, i, ((uint32_t *)(mbed_fault_context))[i]);
95+
mbed_error_printf("\nR%-4d: %08" PRIX32, i, (&mbed_fault_context.R0_reg)[i]);
9896
}
9997

10098
mbed_error_printf("\nSP : %08" PRIX32
10199
"\nLR : %08" PRIX32
102100
"\nPC : %08" PRIX32
103101
"\nxPSR : %08" PRIX32
104102
"\nPSP : %08" PRIX32
105-
"\nMSP : %08" PRIX32, mbed_fault_context->SP_reg, mbed_fault_context->LR_reg, mbed_fault_context->PC_reg,
106-
mbed_fault_context->xPSR, mbed_fault_context->PSP, mbed_fault_context->MSP);
103+
"\nMSP : %08" PRIX32, mbed_fault_context.SP_reg, mbed_fault_context.LR_reg, mbed_fault_context.PC_reg,
104+
mbed_fault_context.xPSR, mbed_fault_context.PSP, mbed_fault_context.MSP);
107105

108106
//Capture CPUID to get core/cpu info
109107
mbed_error_printf("\nCPUID: %08" PRIX32, SCB->CPUID);
@@ -129,12 +127,12 @@ MBED_NOINLINE void print_context_info(void)
129127
#endif
130128

131129
//Print Mode
132-
if (mbed_fault_context->EXC_RETURN & 0x8) {
130+
if (mbed_fault_context.EXC_RETURN & 0x8) {
133131
mbed_error_printf("\nMode : Thread");
134132
//Print Priv level in Thread mode - We capture CONTROL reg which reflects the privilege.
135133
//Note that the CONTROL register captured still reflects the privilege status of the
136134
//thread mode eventhough we are in Handler mode by the time we capture it.
137-
if (mbed_fault_context->CONTROL & 0x1) {
135+
if (mbed_fault_context.CONTROL & 0x1) {
138136
mbed_error_printf("\nPriv : User");
139137
} else {
140138
mbed_error_printf("\nPriv : Privileged");
@@ -144,7 +142,7 @@ MBED_NOINLINE void print_context_info(void)
144142
mbed_error_printf("\nPriv : Privileged");
145143
}
146144
//Print Return Stack
147-
if (mbed_fault_context->EXC_RETURN & 0x4) {
145+
if (mbed_fault_context.EXC_RETURN & 0x4) {
148146
mbed_error_printf("\nStack: PSP");
149147
} else {
150148
mbed_error_printf("\nStack: MSP");
@@ -158,7 +156,7 @@ mbed_error_status_t mbed_get_reboot_fault_context(mbed_fault_context_t *fault_co
158156
if (fault_context == NULL) {
159157
return MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT);
160158
}
161-
memcpy(fault_context, mbed_fault_context, sizeof(mbed_fault_context_t));
159+
*fault_context = mbed_fault_context;
162160
status = MBED_SUCCESS;
163161
#endif
164162
return status;

platform/source/mbed_crash_data_offsets.h

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#ifndef MBED_CRASH_DATA_INFO_H
1818
#define MBED_CRASH_DATA_INFO_H
1919

20+
#include "platform/internal/mbed_fault_handler.h"
21+
#include "platform/mbed_error.h"
22+
2023
#ifdef __cplusplus
2124
extern "C" {
2225
#endif
@@ -25,25 +28,28 @@ extern "C" {
2528
/** \ingroup mbed-os-internal */
2629
/** \addtogroup platform-internal-api */
2730
/** @{*/
31+
// Any changes here must be reflected in except.S if they affect the fault handler.
32+
// The fault context is first to keep it simple for the assembler.
33+
typedef struct mbed_crash_data {
34+
union {
35+
mbed_fault_context_t context;
36+
int pad[32];
37+
} fault;
38+
union {
39+
mbed_error_ctx context;
40+
int pad[32];
41+
} error;
42+
} mbed_crash_data_t;
43+
2844
#if defined(__ARMCC_VERSION)
29-
extern uint32_t Image$$RW_m_crash_data$$ZI$$Base[];
30-
extern uint32_t Image$$RW_m_crash_data$$ZI$$Size;
31-
#define __CRASH_DATA_RAM_START__ Image$$RW_m_crash_data$$ZI$$Base
45+
#define MBED_CRASH_DATA Image$$RW_m_crash_data$$ZI$$Base
3246
#elif defined(__ICCARM__)
33-
extern uint32_t __CRASH_DATA_RAM_START__[];
34-
extern uint32_t __CRASH_DATA_RAM_END__[];
47+
#define MBED_CRASH_DATA __CRASH_DATA_RAM_START__
3548
#elif defined(__GNUC__)
36-
extern uint32_t __CRASH_DATA_RAM_START__[];
37-
extern uint32_t __CRASH_DATA_RAM_END__[];
38-
#endif /* defined(__CC_ARM) */
49+
#define MBED_CRASH_DATA __CRASH_DATA_RAM_START__
50+
#endif
3951

40-
/* Offset definitions for context capture */
41-
#define FAULT_CONTEXT_OFFSET (0x0)
42-
#define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context
43-
#define ERROR_CONTEXT_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE)
44-
#define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context
45-
#define FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET)
46-
#define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET)
52+
extern mbed_crash_data_t MBED_CRASH_DATA;
4753
/**@}*/
4854
#endif
4955

0 commit comments

Comments
 (0)