@@ -25,6 +25,22 @@ extern int stdio_uart_inited;
25
25
extern serial_t stdio_uart ;
26
26
#endif
27
27
28
+ //Helper macro to get the current SP
29
+ #define GET_CURRENT_SP (sp ) \
30
+ { \
31
+ /*If in Handler mode we are always using MSP*/ \
32
+ if ( __get_IPSR () != 0U ) { \
33
+ sp = __get_MSP (); \
34
+ } else { \
35
+ /*Look into CONTROL.SPSEL value*/ \
36
+ if ((__get_CONTROL () & 2U ) == 0U ) { \
37
+ sp = __get_MSP ();/*Read MSP*/ \
38
+ } else { \
39
+ sp = __get_PSP ();/*Read PSP*/ \
40
+ } \
41
+ } \
42
+ }
43
+
28
44
/* Converts a uint32 to hex char string */
29
45
static void value_to_hex_str (uint32_t value , char * hex_str )
30
46
{
@@ -54,22 +70,6 @@ static void value_to_dec_str(uint32_t value, char *dec_str)
54
70
}
55
71
}
56
72
57
- //Helper function to get the current SP
58
- static unsigned int get_current_sp ()
59
- {
60
- //If in Handler mode we are always using MSP
61
- if ( __get_IPSR () != 0U ) {
62
- return __get_MSP ();
63
- } else {
64
- //Look into CONTROL.SPSEL value
65
- if ((__get_CONTROL () & 2U ) == 0U ) {
66
- return __get_PSP ();//Read PSP
67
- } else {
68
- return __get_MSP ();//Read MSP
69
- }
70
- }
71
- }
72
-
73
73
void mbed_error_init (void )
74
74
{
75
75
#if DEVICE_SERIAL && (MBED_CONF_ERROR_REPORT_INTERFACE == DEVICE_SERIAL )
@@ -106,7 +106,7 @@ and prints it in hex format.
106
106
*/
107
107
void mbed_error_print (char * fmtstr , uint32_t * values )
108
108
{
109
- #if DEVICE_SERIAL
109
+ #if DEVICE_SERIAL || DEVICE_ITM
110
110
int i = 0 ;
111
111
int idx = 0 ;
112
112
int vidx = 0 ;
@@ -119,8 +119,7 @@ void mbed_error_print(char *fmtstr, uint32_t *values)
119
119
while (fmtstr [i ] != '\0' ) {
120
120
if (fmtstr [i ]== '%' ) {
121
121
i ++ ;
122
- if (fmtstr [i ]== 'x' ) {
123
- memset (num_str , '0' , sizeof (num_str ));
122
+ if (fmtstr [i ]== 'x' || fmtstr [i ]== 'd' ) {
124
123
//print the number in hex format
125
124
value_to_hex_str (values [vidx ++ ],num_str );
126
125
for (idx = 7 ; idx >=0 ; idx -- ) {
@@ -131,7 +130,7 @@ void mbed_error_print(char *fmtstr, uint32_t *values)
131
130
memset (num_str , '0' , sizeof (num_str ));
132
131
//print the number in dec format
133
132
value_to_dec_str (values [vidx ++ ],num_str );
134
- idx = 7 ;
133
+ idx = 5 ; //Start from 5 as we dont have big decimal numbers
135
134
while (num_str [idx -- ]== '0' && idx > 0 );//Dont print zeros at front
136
135
for (idx ++ ;idx >=0 ; idx -- ) {
137
136
mbed_error_putc (num_str [idx ]);
@@ -146,9 +145,7 @@ void mbed_error_print(char *fmtstr, uint32_t *values)
146
145
}
147
146
str = NULL ;
148
147
} else {
149
- //print the % and char without formatting and keep going
150
- mbed_error_putc ('%' );
151
- mbed_error_putc (fmtstr [i ]);
148
+ //Do not handle any other % formatting and keep going
152
149
}
153
150
} else {
154
151
//handle carriage returns
@@ -182,67 +179,69 @@ void print_thread(osRtxThread_t *thread)
182
179
data [2 ]= thread -> stack_size ;
183
180
data [3 ]= (uint32_t )thread -> stack_mem ;
184
181
data [4 ]= thread -> sp ;
185
- mbed_error_print ("\nState: 0x%x EntryFn : 0x%x Stack Size: 0x%x Mem: 0x%x SP: 0x%x" , data );
182
+ mbed_error_print ("\nState: 0x%x Entry : 0x%x Stack Size: 0x%x Mem: 0x%x SP: 0x%x" , data );
186
183
}
187
184
#endif
188
185
186
+ /* Prints the error information */
189
187
void mbed_report_error (mbed_error_ctx * error_ctx , char * error_msg )
190
188
{
191
- int error_code = GET_MBED_ERROR_CODE (error_ctx -> error_status );
192
- int error_entity = GET_MBED_ERROR_MODULE (error_ctx -> error_status );
189
+ uint32_t error_vals [3 ] = {0 };
190
+ error_vals [0 ] = error_ctx -> error_status ;
191
+ error_vals [1 ] = GET_MBED_ERROR_CODE (error_ctx -> error_status );
192
+ error_vals [2 ] = GET_MBED_ERROR_MODULE (error_ctx -> error_status );
193
193
194
- mbed_error_print ("\n\n++ MbedOS Error Info ++\nError Status: 0x%x" , (uint32_t * )& error_ctx -> error_status );
195
- mbed_error_print ("\nError Code: %d" , (uint32_t * )& error_code );
196
- mbed_error_print ("\nError Entity: %d\nError Message: " , (uint32_t * )& error_entity );
194
+ mbed_error_print ("\n\n++ MbedOS Error Info ++\nError Status: 0x%x Code: %d Entity: %d\nError Message: " , error_vals );
197
195
198
- //Report error info based on error code, some errors require different info
199
- if (error_code == ERROR_CODE_HARDFAULT_EXCEPTION ||
200
- error_code == ERROR_CODE_MEMMANAGE_EXCEPTION ||
201
- error_code == ERROR_CODE_BUSFAULT_EXCEPTION ||
202
- error_code == ERROR_CODE_USAGEFAULT_EXCEPTION ) {
196
+ //Report error info based on error code, some errors require different
197
+ //error_vals[1] contains the error code
198
+ if (error_vals [1 ] == ERROR_CODE_HARDFAULT_EXCEPTION ||
199
+ error_vals [1 ] == ERROR_CODE_MEMMANAGE_EXCEPTION ||
200
+ error_vals [1 ] == ERROR_CODE_BUSFAULT_EXCEPTION ||
201
+ error_vals [1 ] == ERROR_CODE_USAGEFAULT_EXCEPTION ) {
203
202
mbed_error_print (error_msg , NULL );
204
- mbed_error_print ("\nError Location : 0x%x\n" , (uint32_t * )& error_ctx -> error_value );
203
+ mbed_error_print ("\nLocation : 0x%x\n" , (uint32_t * )& error_ctx -> error_value );
205
204
} else {
206
- switch (error_code ) {
205
+ switch (error_vals [ 1 ] ) {
207
206
//These are errors reported by kernel handled from mbed_rtx_handlers
208
207
case ERROR_CODE_RTOS_EVENT :
209
208
mbed_error_print ("Kernel Error: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
210
209
break ;
211
210
212
211
case ERROR_CODE_RTOS_THREAD_EVENT :
213
- mbed_error_print ("Thread Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
212
+ mbed_error_print ("Thread: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
214
213
break ;
215
214
216
215
case ERROR_CODE_RTOS_MUTEX_EVENT :
217
- mbed_error_print ("Mutex Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
216
+ mbed_error_print ("Mutex: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
218
217
break ;
219
218
220
219
case ERROR_CODE_RTOS_SEMAPHORE_EVENT :
221
- mbed_error_print ("Semaphore Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
220
+ mbed_error_print ("Semaphore: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
222
221
break ;
223
222
224
223
case ERROR_CODE_RTOS_MEMORY_POOL_EVENT :
225
- mbed_error_print ("MemoryPool Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
224
+ mbed_error_print ("MemoryPool: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
226
225
break ;
227
226
228
227
case ERROR_CODE_RTOS_EVENT_FLAGS_EVENT :
229
- mbed_error_print ("EventFlags Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
228
+ mbed_error_print ("EventFlags: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
230
229
break ;
231
230
232
231
case ERROR_CODE_RTOS_TIMER_EVENT :
233
- mbed_error_print ("Timer Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
232
+ mbed_error_print ("Timer: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
234
233
break ;
235
234
236
235
case ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT :
237
- mbed_error_print ("MessageQueue Error : 0x%x, " , (uint32_t * )& error_ctx -> error_value );
236
+ mbed_error_print ("MessageQueue: 0x%x, " , (uint32_t * )& error_ctx -> error_value );
238
237
break ;
239
238
240
239
default :
241
240
//Nothing to do here, just print the error info down
242
241
break ;
243
242
}
244
243
mbed_error_print (error_msg , NULL );
245
- mbed_error_print ("\nError Location : 0x%x" , (uint32_t * )& error_ctx -> error_address );
244
+ mbed_error_print ("\nLocation : 0x%x" , (uint32_t * )& error_ctx -> error_address );
246
245
#ifdef MBED_CONF_ERROR_FILENAME_CAPTURE_ENABLED
247
246
if (NULL != error_ctx -> error_filename ) {
248
247
//for string, we must pass address of a ptr which has the address of the string
@@ -259,12 +258,20 @@ void mbed_report_error(mbed_error_ctx *error_ctx, char *error_msg)
259
258
error_ctx -> thread_entry_address = (uint32_t )current_thread -> thread_addr ;
260
259
error_ctx -> thread_stack_size = current_thread -> stack_size ;
261
260
error_ctx -> thread_stack_mem = (uint32_t )current_thread -> stack_mem ;
262
- error_ctx -> thread_current_sp = get_current_sp ();
261
+ #ifdef TARGET_CORTEX_M
262
+ GET_CURRENT_SP (error_ctx -> thread_current_sp );
263
263
264
264
//Take advantage of the fact that the thread info in context struct is consecutively placed
265
- mbed_error_print ("\nError Value: 0x%x\nCurrent Thread: Id: 0x%x EntryFn : 0x%x StackSize: 0x%x StackMem: 0x%x SP: 0x%x " ,
265
+ mbed_error_print ("\nError Value: 0x%x\nCurrent Thread: Id: 0x%x Entry : 0x%x StackSize: 0x%x StackMem: 0x%x SP: 0x%x " ,
266
266
(uint32_t * )& error_ctx -> error_value );
267
- #endif
267
+ #else
268
+ //For Cortex-A targets we dont have support to capture the current SP
269
+ //Take advantage of the fact that the thread info in context struct is consecutively placed
270
+ mbed_error_print ("\nError Value: 0x%x\nCurrent Thread: Id: 0x%x Entry: 0x%x StackSize: 0x%x StackMem: 0x%x " ,
271
+ (uint32_t * )& error_ctx -> error_value );
272
+ #endif //TARGET_CORTEX_M
273
+
274
+ #endif //MBED_CONF_RTOS_PRESENT
268
275
}
269
276
270
277
mbed_error_print ("\n-- MbedOS Error Info --" , NULL );
0 commit comments