123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include "device.h"
- #include "platform/mbed_critical.h"
- #include "platform/mbed_error.h"
- #include "platform/mbed_error_hist.h"
- #include "platform/mbed_interface.h"
- #ifdef MBED_CONF_RTOS_PRESENT
- #include "rtx_os.h"
- #endif
- #if DEVICE_STDIO_MESSAGES
- #include <stdio.h>
- #endif
- #define GET_CURRENT_SP(sp) \
- { \
- \
- if ( __get_IPSR() != 0U ) { \
- sp = __get_MSP(); \
- } else { \
- \
- if ((__get_CONTROL() & 2U) == 0U) { \
- sp = __get_MSP(); \
- } else { \
- sp = __get_PSP(); \
- } \
- } \
- }
- #ifndef NDEBUG
- #define ERROR_REPORT(ctx, error_msg) print_error_report(ctx, error_msg)
- #else
- #define ERROR_REPORT(ctx, error_msg) ((void) 0)
- #endif
- static uint8_t error_in_progress = 0;
- static int error_count = 0;
- static mbed_error_ctx first_error_ctx = {0};
- static mbed_error_ctx last_error_ctx = {0};
- static mbed_error_hook_t error_hook = NULL;
- static void print_error_report(mbed_error_ctx *ctx, const char *);
- static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller);
- static void mbed_halt_system(void)
- {
-
- if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
- for (;;) {
- __WFI();
- }
- } else {
-
- exit(1);
- }
- }
- WEAK void error(const char *format, ...)
- {
-
- if (error_in_progress) {
- return;
- }
-
- handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR());
- ERROR_REPORT(&last_error_ctx, "Fatal Run-time error");
- error_in_progress = 1;
- #ifndef NDEBUG
- va_list arg;
- va_start(arg, format);
- mbed_error_vfprintf(format, arg);
- va_end(arg);
- #endif
- exit(1);
- }
- static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller)
- {
- mbed_error_ctx current_error_ctx;
-
- if (error_status >= 0) {
-
-
- error_status = MBED_ERROR_INVALID_ARGUMENT;
- }
-
-
- while (error_in_progress == 1);
-
- core_util_critical_section_enter();
- error_in_progress = 1;
- core_util_critical_section_exit();
-
- error_count++;
-
- memset(¤t_error_ctx, sizeof(mbed_error_ctx), 0);
-
- current_error_ctx.error_status = error_status;
- current_error_ctx.error_address = (uint32_t)caller;
- current_error_ctx.error_value = error_value;
- #ifdef MBED_CONF_RTOS_PRESENT
-
- osRtxThread_t *current_thread = osRtxInfo.thread.run.curr;
- current_error_ctx.thread_id = (uint32_t)current_thread;
- current_error_ctx.thread_entry_address = (uint32_t)current_thread->thread_addr;
- current_error_ctx.thread_stack_size = current_thread->stack_size;
- current_error_ctx.thread_stack_mem = (uint32_t)current_thread->stack_mem;
- #ifdef TARGET_CORTEX_M
- GET_CURRENT_SP(current_error_ctx.thread_current_sp);
- #endif
- #endif
- #if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED
-
-
- memset(¤t_error_ctx.error_filename, 0, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
- strncpy(current_error_ctx.error_filename, filename, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
- current_error_ctx.error_line_number = line_number;
- #endif
-
- if (error_count == 1) {
- memcpy(&first_error_ctx, ¤t_error_ctx, sizeof(mbed_error_ctx));
- }
-
- memcpy(&last_error_ctx, ¤t_error_ctx, sizeof(mbed_error_ctx));
- #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
-
- mbed_error_hist_put(¤t_error_ctx);
- #endif
-
- if (error_hook != NULL) {
- error_hook(&last_error_ctx);
- }
- error_in_progress = 0;
- return MBED_SUCCESS;
- }
- mbed_error_status_t mbed_get_first_error(void)
- {
-
- return first_error_ctx.error_status;
- }
- mbed_error_status_t mbed_get_last_error(void)
- {
-
- return last_error_ctx.error_status;
- }
- int mbed_get_error_count(void)
- {
-
- return error_count;
- }
- mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
- {
- return handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR());
- }
- 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)
- {
-
- if (MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR())) {
- return MBED_ERROR_FAILED_OPERATION;
- }
-
- ERROR_REPORT(&last_error_ctx, error_msg);
- mbed_halt_system();
- return MBED_ERROR_FAILED_OPERATION;
- }
- mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in)
- {
-
- if (error_hook_in != NULL) {
- error_hook = error_hook_in;
- return MBED_SUCCESS;
- }
- return MBED_ERROR_INVALID_ARGUMENT;
- }
- mbed_error_status_t mbed_get_first_error_info(mbed_error_ctx *error_info)
- {
- memcpy(error_info, &first_error_ctx, sizeof(first_error_ctx));
- return MBED_SUCCESS;
- }
- mbed_error_status_t mbed_get_last_error_info(mbed_error_ctx *error_info)
- {
- memcpy(error_info, &last_error_ctx, sizeof(mbed_error_ctx));
- return MBED_SUCCESS;
- }
- mbed_error_status_t mbed_make_error(mbed_error_type_t error_type, mbed_module_type_t entity, mbed_error_code_t error_code)
- {
- switch (error_type) {
- case MBED_ERROR_TYPE_POSIX:
- if (error_code >= MBED_POSIX_ERROR_BASE && error_code <= MBED_SYSTEM_ERROR_BASE) {
- return -error_code;
- }
- break;
- case MBED_ERROR_TYPE_SYSTEM:
- if (error_code >= MBED_SYSTEM_ERROR_BASE && error_code <= MBED_CUSTOM_ERROR_BASE) {
- return MAKE_MBED_ERROR(MBED_ERROR_TYPE_SYSTEM, entity, error_code);
- }
- break;
- case MBED_ERROR_TYPE_CUSTOM:
- if (error_code >= MBED_CUSTOM_ERROR_BASE) {
- return MAKE_MBED_ERROR(MBED_ERROR_TYPE_CUSTOM, entity, error_code);
- }
- break;
- default:
- break;
- }
-
- return MAKE_MBED_ERROR(MBED_ERROR_TYPE_SYSTEM, MBED_MODULE_UNKNOWN, MBED_ERROR_CODE_UNKNOWN);
- }
- mbed_error_status_t mbed_clear_all_errors(void)
- {
- mbed_error_status_t status = MBED_SUCCESS;
-
- core_util_critical_section_enter();
-
- memset(&last_error_ctx, sizeof(mbed_error_ctx), 0);
-
- error_count = 0;
- #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
- status = mbed_error_hist_reset();
- #endif
- core_util_critical_section_exit();
- return status;
- }
- #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
- static void print_thread(osRtxThread_t *thread)
- {
- 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);
- }
- static void print_threads_info(osRtxThread_t *threads)
- {
- while (threads != NULL) {
- print_thread(threads);
- threads = threads->thread_next;
- }
- }
- #endif
- #ifndef NDEBUG
- static void print_error_report(mbed_error_ctx *ctx, const char *error_msg)
- {
- uint32_t error_code = MBED_GET_ERROR_CODE(ctx->error_status);
- uint32_t error_module = MBED_GET_ERROR_MODULE(ctx->error_status);
- 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);
- switch (error_code) {
-
- case MBED_ERROR_CODE_RTOS_EVENT:
- mbed_error_printf("Kernel Error: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_THREAD_EVENT:
- mbed_error_printf("Thread: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_MUTEX_EVENT:
- mbed_error_printf("Mutex: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT:
- mbed_error_printf("Semaphore: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT:
- mbed_error_printf("MemoryPool: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT:
- mbed_error_printf("EventFlags: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_TIMER_EVENT:
- mbed_error_printf("Timer: 0x%X, ", ctx->error_value);
- break;
- case MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT:
- mbed_error_printf("MessageQueue: 0x%X, ", ctx->error_value);
- break;
- default:
-
- break;
- }
- mbed_error_printf(error_msg);
- mbed_error_printf("\nLocation: 0x%X", ctx->error_address);
- #if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED && !defined(NDEBUG)
- if ((NULL != ctx->error_filename[0]) && (ctx->error_line_number != 0)) {
-
- mbed_error_printf("\nFile:%s+%d", ctx->error_filename, ctx->error_line_number);
- }
- #endif
- mbed_error_printf("\nError Value: 0x%X", ctx->error_value);
- #ifdef TARGET_CORTEX_M
- mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X SP: 0x%X ",
- ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem, ctx->thread_current_sp);
- #else
-
- mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X ",
- ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem);
- #endif
- #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
- mbed_error_printf("\nNext:");
- print_thread(osRtxInfo.thread.run.next);
- mbed_error_printf("\nWait:");
- osRtxThread_t *threads = (osRtxThread_t *)&osRtxInfo.thread.wait_list;
- print_threads_info(threads);
- mbed_error_printf("\nDelay:");
- threads = (osRtxThread_t *)&osRtxInfo.thread.delay_list;
- print_threads_info(threads);
- mbed_error_printf("\nIdle:");
- threads = (osRtxThread_t *)&osRtxInfo.thread.idle;
- print_threads_info(threads);
- #endif
- mbed_error_printf("\n-- MbedOS Error Info --\n");
- }
- #endif
- #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
- mbed_error_status_t mbed_get_error_hist_info(int index, mbed_error_ctx *error_info)
- {
- return mbed_error_hist_get(index, error_info);
- }
- int mbed_get_error_hist_count(void)
- {
- return mbed_error_hist_get_count();
- }
- mbed_error_status_t mbed_save_error_hist(const char *path)
- {
- mbed_error_status_t ret = MBED_SUCCESS;
- mbed_error_ctx ctx = {0};
- int log_count = mbed_error_hist_get_count();
- FILE *error_log_file = NULL;
-
- if (path == NULL) {
- ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT);
- goto exit;
- }
-
- if ((error_log_file = fopen(path, "w")) == NULL) {
- ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OPEN_FAILED);
- goto exit;
- }
-
- if (fprintf(error_log_file, "\nFirst Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
- (unsigned int)first_error_ctx.error_status,
- (unsigned int)first_error_ctx.thread_id,
- (unsigned int)first_error_ctx.error_address,
- (unsigned int)first_error_ctx.error_value) <= 0) {
- ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
- goto exit;
- }
- if (fprintf(error_log_file, "\nLast Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
- (unsigned int)last_error_ctx.error_status,
- (unsigned int)last_error_ctx.thread_id,
- (unsigned int)last_error_ctx.error_address,
- (unsigned int)last_error_ctx.error_value) <= 0) {
- ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
- goto exit;
- }
-
- while (--log_count >= 0) {
- mbed_error_hist_get(log_count, &ctx);
-
- if (fprintf(error_log_file, "\n%d: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
- log_count,
- (unsigned int)ctx.error_status,
- (unsigned int)ctx.thread_id,
- (unsigned int)ctx.error_address,
- (unsigned int)ctx.error_value) <= 0) {
- ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
- goto exit;
- }
- }
- exit:
- fclose(error_log_file);
- return ret;
- }
- #endif
|