Skip to content

Commit ea47342

Browse files
author
Cruz Monrreal
authored
Merge pull request #7214 from SenRamakri/sen_ErrorOptimAndConfig
Error handling configuration updates and Optimization for exception handling
2 parents 335fd58 + baa44eb commit ea47342

File tree

8 files changed

+257
-364
lines changed

8 files changed

+257
-364
lines changed

TESTS/mbed_platform/error_handling/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,12 @@ void test_error_context_capture()
132132
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->thread_addr, error_ctx.thread_entry_address);
133133
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->stack_size, error_ctx.thread_stack_size);
134134
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->stack_mem, error_ctx.thread_stack_mem);
135-
#ifdef MBED_CONF_ERROR_FILENAME_CAPTURE_ENABLED
135+
#if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED
136136
TEST_ASSERT_EQUAL_STRING(MBED_FILENAME, error_ctx.error_filename);
137137
#endif
138138
}
139139

140-
#ifndef MBED_CONF_ERROR_HIST_DISABLED
140+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
141141
/** Test error logging functionality
142142
*/
143143
void test_error_logging()
@@ -261,7 +261,7 @@ void test_error_hook()
261261
TEST_ASSERT(sem_status > 0);
262262
}
263263

264-
#ifdef MBED_TEST_SIM_BLOCKDEVICE
264+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED && defined(MBED_TEST_SIM_BLOCKDEVICE)
265265

266266
// test configuration
267267
#ifndef MBED_TEST_FILESYSTEM
@@ -351,12 +351,12 @@ Case cases[] = {
351351
Case("Test error context capture", test_error_context_capture),
352352
#endif //MBED_CONF_RTOS_PRESENT
353353
Case("Test error hook", test_error_hook),
354-
#ifndef MBED_CONF_ERROR_HIST_DISABLED
354+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
355355
Case("Test error logging", test_error_logging),
356356
#if MBED_CONF_RTOS_PRESENT
357357
Case("Test error handling multi-threaded", test_error_logging_multithread),
358358
#endif //MBED_CONF_RTOS_PRESENT
359-
#ifdef MBED_TEST_SIM_BLOCKDEVICE
359+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED && defined(MBED_TEST_SIM_BLOCKDEVICE)
360360
Case("Test error save log", test_save_error_log),
361361
#endif //MBED_TEST_SIM_BLOCKDEVICE
362362
#endif //MBED_CONF_ERROR_HIST_DISABLED

platform/mbed_error.c

Lines changed: 124 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#define GET_CURRENT_SP(sp) \
3434
{ \
3535
/*If in Handler mode we are always using MSP*/ \
36-
if( __get_IPSR() != 0U ) { \
36+
if ( __get_IPSR() != 0U ) { \
3737
sp = __get_MSP(); \
3838
} else { \
3939
/*Look into CONTROL.SPSEL value*/ \
@@ -95,7 +95,7 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign
9595
mbed_error_ctx current_error_ctx;
9696

9797
//Error status should always be < 0
98-
if(error_status >= 0) {
98+
if (error_status >= 0) {
9999
//This is a weird situation, someone called mbed_error with invalid error code.
100100
//We will still handle the situation but change the error code to ERROR_INVALID_ARGUMENT, atleast the context will have info on who called it
101101
error_status = MBED_ERROR_INVALID_ARGUMENT;
@@ -132,29 +132,29 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign
132132

133133
#endif //MBED_CONF_RTOS_PRESENT
134134

135-
#ifdef MBED_CONF_ERROR_FILENAME_CAPTURE_ENABLED
135+
#ifdef MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED
136136
//Capture filename/linenumber if provided
137137
//Index for tracking error_filename
138-
memset(&current_error_ctx.error_filename, 0, MBED_CONF_MAX_ERROR_FILENAME_LEN);
139-
strncpy(current_error_ctx.error_filename, filename, MBED_CONF_MAX_ERROR_FILENAME_LEN);
138+
memset(&current_error_ctx.error_filename, 0, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
139+
strncpy(current_error_ctx.error_filename, filename, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
140140
current_error_ctx.error_line_number = line_number;
141141
#endif
142142

143143
//Capture the fist system error and store it
144-
if(error_count == 1) { //first error
144+
if (error_count == 1) { //first error
145145
memcpy(&first_error_ctx, &current_error_ctx, sizeof(mbed_error_ctx));
146146
}
147147

148148
//copy this error to last error
149149
memcpy(&last_error_ctx, &current_error_ctx, sizeof(mbed_error_ctx));
150150

151-
#ifndef MBED_CONF_ERROR_HIST_DISABLED
151+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
152152
//Log the error with error log
153153
mbed_error_hist_put(&current_error_ctx);
154154
#endif
155155

156156
//Call the error hook if available
157-
if(error_hook != NULL) {
157+
if (error_hook != NULL) {
158158
error_hook(&last_error_ctx);
159159
}
160160

@@ -190,11 +190,11 @@ mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *e
190190
return handle_error(error_status, error_value, filename, line_number);
191191
}
192192

193-
//Sets a fatal error
193+
//Sets a fatal error, this function is marked WEAK to be able to override this for some tests
194194
WEAK mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
195195
{
196196
//set the error reported and then halt the system
197-
if( MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number) )
197+
if ( MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number))
198198
return MBED_ERROR_FAILED_OPERATION;
199199

200200
//On fatal errors print the error context/report
@@ -208,7 +208,7 @@ WEAK mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char
208208
mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in)
209209
{
210210
//register the new hook/callback
211-
if( error_hook_in != NULL ) {
211+
if ( error_hook_in != NULL ) {
212212
error_hook = error_hook_in;
213213
return MBED_SUCCESS;
214214
}
@@ -236,17 +236,17 @@ mbed_error_status_t mbed_make_error(mbed_error_type_t error_type, mbed_module_ty
236236
switch(error_type)
237237
{
238238
case MBED_ERROR_TYPE_POSIX:
239-
if(error_code >= MBED_POSIX_ERROR_BASE && error_code <= MBED_SYSTEM_ERROR_BASE)
239+
if (error_code >= MBED_POSIX_ERROR_BASE && error_code <= MBED_SYSTEM_ERROR_BASE)
240240
return -error_code;
241241
break;
242242

243243
case MBED_ERROR_TYPE_SYSTEM:
244-
if(error_code >= MBED_SYSTEM_ERROR_BASE && error_code <= MBED_CUSTOM_ERROR_BASE)
244+
if (error_code >= MBED_SYSTEM_ERROR_BASE && error_code <= MBED_CUSTOM_ERROR_BASE)
245245
return MAKE_MBED_ERROR(MBED_ERROR_TYPE_SYSTEM, entity, error_code);
246246
break;
247247

248248
case MBED_ERROR_TYPE_CUSTOM:
249-
if(error_code >= MBED_CUSTOM_ERROR_BASE)
249+
if (error_code >= MBED_CUSTOM_ERROR_BASE)
250250
return MAKE_MBED_ERROR(MBED_ERROR_TYPE_CUSTOM, entity, error_code);
251251
break;
252252

@@ -273,15 +273,117 @@ mbed_error_status_t mbed_clear_all_errors(void)
273273
memset(&last_error_ctx, sizeof(mbed_error_ctx), 0);
274274
//reset error count to 0
275275
error_count = 0;
276-
#ifndef MBED_CONF_ERROR_HIST_DISABLED
276+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
277277
status = mbed_error_hist_reset();
278278
#endif
279279
core_util_critical_section_exit();
280280

281281
return status;
282282
}
283283

284-
#ifndef MBED_CONF_ERROR_HIST_DISABLED
284+
#if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
285+
/* Prints info of a thread(using osRtxThread_t struct)*/
286+
static void print_thread(osRtxThread_t *thread)
287+
{
288+
mbed_error_printf("\nState: 0x%08X Entry: 0x%08X Stack Size: 0x%08X Mem: 0x%08X SP: 0x%08X", thread->state, thread->thread_addr, thread->stack_size, (uint32_t)thread->stack_mem, thread->sp);
289+
}
290+
291+
/* Prints thread info from a list */
292+
static void print_threads_info(osRtxThread_t *threads)
293+
{
294+
while (threads != NULL) {
295+
print_thread( threads );
296+
threads = threads->thread_next;
297+
}
298+
}
299+
#endif
300+
301+
static void print_error_report(mbed_error_ctx *ctx, const char *error_msg)
302+
{
303+
uint32_t error_code = MBED_GET_ERROR_CODE(ctx->error_status);
304+
uint32_t error_module = MBED_GET_ERROR_MODULE(ctx->error_status);
305+
306+
mbed_error_printf("\n\n++ MbedOS Error Info ++\nError Status: 0x%X Code: %d Module: %d\nError Message: ", ctx->error_status, error_code, error_module);
307+
308+
switch (error_code) {
309+
//These are errors reported by kernel handled from mbed_rtx_handlers
310+
case MBED_ERROR_CODE_RTOS_EVENT:
311+
mbed_error_printf("Kernel Error: 0x%X, ", ctx->error_value);
312+
break;
313+
314+
case MBED_ERROR_CODE_RTOS_THREAD_EVENT:
315+
mbed_error_printf("Thread: 0x%X, ", ctx->error_value);
316+
break;
317+
318+
case MBED_ERROR_CODE_RTOS_MUTEX_EVENT:
319+
mbed_error_printf("Mutex: 0x%X, ", ctx->error_value);
320+
break;
321+
322+
case MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT:
323+
mbed_error_printf("Semaphore: 0x%X, ", ctx->error_value);
324+
break;
325+
326+
case MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT:
327+
mbed_error_printf("MemoryPool: 0x%X, ", ctx->error_value);
328+
break;
329+
330+
case MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT:
331+
mbed_error_printf("EventFlags: 0x%X, ", ctx->error_value);
332+
break;
333+
334+
case MBED_ERROR_CODE_RTOS_TIMER_EVENT:
335+
mbed_error_printf("Timer: 0x%X, ", ctx->error_value);
336+
break;
337+
338+
case MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT:
339+
mbed_error_printf("MessageQueue: 0x%X, ", ctx->error_value);
340+
break;
341+
342+
default:
343+
//Nothing to do here, just print the error info down
344+
break;
345+
}
346+
mbed_error_printf(error_msg);
347+
mbed_error_printf("\nLocation: 0x%X", ctx->error_address);
348+
349+
#if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED && !defined(NDEBUG)
350+
if ((NULL != ctx->error_filename[0]) && (ctx->error_line_number != 0)) {
351+
//for string, we must pass address of a ptr which has the address of the string
352+
mbed_error_printf("\nFile:%s+%d", ctx->error_filename, ctx->error_line_number);
353+
}
354+
#endif
355+
356+
mbed_error_printf("\nError Value: 0x%X", ctx->error_value);
357+
#ifdef TARGET_CORTEX_M
358+
mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X SP: 0x%X ",
359+
ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem, ctx->thread_current_sp);
360+
#else
361+
//For Cortex-A targets we dont have support to capture the current SP
362+
mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X ",
363+
ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem);
364+
#endif //TARGET_CORTEX_M
365+
366+
#if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
367+
mbed_error_printf("\nNext:");
368+
print_thread(osRtxInfo.thread.run.next);
369+
370+
mbed_error_printf("\nWait:");
371+
osRtxThread_t *threads = (osRtxThread_t *)&osRtxInfo.thread.wait_list;
372+
print_threads_info(threads);
373+
374+
mbed_error_printf("\nDelay:");
375+
threads = (osRtxThread_t *)&osRtxInfo.thread.delay_list;
376+
print_threads_info(threads);
377+
378+
mbed_error_printf("\nIdle:");
379+
threads = (osRtxThread_t *)&osRtxInfo.thread.idle;
380+
print_threads_info(threads);
381+
#endif
382+
383+
mbed_error_printf("\n-- MbedOS Error Info --\n");
384+
}
385+
386+
#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
285387
//Retrieve the error context from error log at the specified index
286388
mbed_error_status_t mbed_get_error_hist_info (int index, mbed_error_ctx *error_info)
287389
{
@@ -302,19 +404,19 @@ mbed_error_status_t mbed_save_error_hist(const char *path)
302404
FILE *error_log_file = NULL;
303405

304406
//Ensure path is valid
305-
if(path==NULL) {
407+
if (path==NULL) {
306408
ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT);
307409
goto exit;
308410
}
309411

310412
//Open the file for saving the error log info
311-
if((error_log_file = fopen( path, "w" ) ) == NULL){
413+
if ((error_log_file = fopen( path, "w" )) == NULL){
312414
ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OPEN_FAILED);
313415
goto exit;
314416
}
315417

316418
//First store the first and last errors
317-
if(fprintf(error_log_file, "\nFirst Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
419+
if (fprintf(error_log_file, "\nFirst Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
318420
(unsigned int)first_error_ctx.error_status,
319421
(unsigned int)first_error_ctx.thread_id,
320422
(unsigned int)first_error_ctx.error_address,
@@ -323,7 +425,7 @@ mbed_error_status_t mbed_save_error_hist(const char *path)
323425
goto exit;
324426
}
325427

326-
if(fprintf(error_log_file, "\nLast Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
428+
if (fprintf(error_log_file, "\nLast Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
327429
(unsigned int)last_error_ctx.error_status,
328430
(unsigned int)last_error_ctx.thread_id,
329431
(unsigned int)last_error_ctx.error_address,
@@ -333,10 +435,10 @@ mbed_error_status_t mbed_save_error_hist(const char *path)
333435
}
334436

335437
//Update with error log info
336-
while(--log_count >= 0) {
438+
while (--log_count >= 0) {
337439
mbed_error_hist_get(log_count, &ctx);
338440
//first line of file will be error log count
339-
if(fprintf(error_log_file, "\n%d: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
441+
if (fprintf(error_log_file, "\n%d: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
340442
log_count,
341443
(unsigned int)ctx.error_status,
342444
(unsigned int)ctx.thread_id,
@@ -352,83 +454,5 @@ mbed_error_status_t mbed_save_error_hist(const char *path)
352454

353455
return ret;
354456
}
355-
356-
static void print_error_report(mbed_error_ctx *ctx, const char *error_msg)
357-
{
358-
uint32_t error_code = MBED_GET_ERROR_CODE(ctx->error_status);
359-
uint32_t error_module = MBED_GET_ERROR_MODULE(ctx->error_status);
360-
361-
mbed_error_printf("\n\n++ MbedOS Error Info ++\nError Status: 0x%x Code: %d Module: %d\nError Message: ", ctx->error_status, error_code, error_module);
362-
363-
//Report error info based on error code, some errors require different
364-
//error_vals[1] contains the error code
365-
if(error_code == MBED_ERROR_CODE_HARDFAULT_EXCEPTION ||
366-
error_code == MBED_ERROR_CODE_MEMMANAGE_EXCEPTION ||
367-
error_code == MBED_ERROR_CODE_BUSFAULT_EXCEPTION ||
368-
error_code == MBED_ERROR_CODE_USAGEFAULT_EXCEPTION ) {
369-
mbed_error_printf(error_msg);
370-
mbed_error_printf("\nLocation: 0x%x\n", ctx->error_value);
371-
} else {
372-
switch (error_code) {
373-
//These are errors reported by kernel handled from mbed_rtx_handlers
374-
case MBED_ERROR_CODE_RTOS_EVENT:
375-
mbed_error_printf("Kernel Error: 0x%x, ", ctx->error_value);
376-
break;
377-
378-
case MBED_ERROR_CODE_RTOS_THREAD_EVENT:
379-
mbed_error_printf("Thread: 0x%x, ", ctx->error_value);
380-
break;
381-
382-
case MBED_ERROR_CODE_RTOS_MUTEX_EVENT:
383-
mbed_error_printf("Mutex: 0x%x, ", ctx->error_value);
384-
break;
385-
386-
case MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT:
387-
mbed_error_printf("Semaphore: 0x%x, ", ctx->error_value);
388-
break;
389-
390-
case MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT:
391-
mbed_error_printf("MemoryPool: 0x%x, ", ctx->error_value);
392-
break;
393-
394-
case MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT:
395-
mbed_error_printf("EventFlags: 0x%x, ", ctx->error_value);
396-
break;
397-
398-
case MBED_ERROR_CODE_RTOS_TIMER_EVENT:
399-
mbed_error_printf("Timer: 0x%x, ", ctx->error_value);
400-
break;
401-
402-
case MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT:
403-
mbed_error_printf("MessageQueue: 0x%x, ", ctx->error_value);
404-
break;
405-
406-
default:
407-
//Nothing to do here, just print the error info down
408-
break;
409-
}
410-
mbed_error_printf(error_msg, NULL);
411-
mbed_error_printf("\nLocation: 0x%x", ctx->error_address);
412-
#if defined(MBED_CONF_ERROR_FILENAME_CAPTURE_ENABLED) && !defined(NDEBUG)
413-
if(NULL != ctx->error_filename) {
414-
//for string, we must pass address of a ptr which has the address of the string
415-
mbed_error_printf("\nFile:%s+%d", ctx->error_filename, ctx->error_line_number);
416-
}
417-
#endif
418-
419-
#ifdef TARGET_CORTEX_M
420-
mbed_error_printf("\nError Value: 0x%x\nCurrent Thread: Id: 0x%x Entry: 0x%x StackSize: 0x%x StackMem: 0x%x SP: 0x%x ",
421-
ctx->error_value, ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem, ctx->thread_current_sp);
422-
#else
423-
//For Cortex-A targets we dont have support to capture the current SP
424-
mbed_error_printf("\nError Value: 0x%x\nCurrent Thread: Id: 0x%x Entry: 0x%x StackSize: 0x%x StackMem: 0x%x ",
425-
ctx->error_value, ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem);
426-
#endif //TARGET_CORTEX_M
427-
}
428-
429-
mbed_error_printf("\n-- MbedOS Error Info --\n");
430-
}
431-
432-
433457
#endif
434458

0 commit comments

Comments
 (0)