RTC auf true

Committer:
kevman
Date:
Wed Nov 28 15:10:15 2018 +0000
Revision:
0:38ceb79fef03
RTC modified

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2006-2013 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 0:38ceb79fef03 5 * you may not use this file except in compliance with the License.
kevman 0:38ceb79fef03 6 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 7 *
kevman 0:38ceb79fef03 8 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 9 *
kevman 0:38ceb79fef03 10 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 11 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 0:38ceb79fef03 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 13 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 14 * limitations under the License.
kevman 0:38ceb79fef03 15 */
kevman 0:38ceb79fef03 16 #include <stdlib.h>
kevman 0:38ceb79fef03 17 #include <stdarg.h>
kevman 0:38ceb79fef03 18 #include <string.h>
kevman 0:38ceb79fef03 19 #include "device.h"
kevman 0:38ceb79fef03 20 #include "platform/mbed_critical.h"
kevman 0:38ceb79fef03 21 #include "platform/mbed_error.h"
kevman 0:38ceb79fef03 22 #include "platform/mbed_error_hist.h"
kevman 0:38ceb79fef03 23 #include "platform/mbed_interface.h"
kevman 0:38ceb79fef03 24 #ifdef MBED_CONF_RTOS_PRESENT
kevman 0:38ceb79fef03 25 #include "rtx_os.h"
kevman 0:38ceb79fef03 26 #endif
kevman 0:38ceb79fef03 27
kevman 0:38ceb79fef03 28 #if DEVICE_STDIO_MESSAGES
kevman 0:38ceb79fef03 29 #include <stdio.h>
kevman 0:38ceb79fef03 30 #endif
kevman 0:38ceb79fef03 31
kevman 0:38ceb79fef03 32 //Helper macro to get the current SP
kevman 0:38ceb79fef03 33 #define GET_CURRENT_SP(sp) \
kevman 0:38ceb79fef03 34 { \
kevman 0:38ceb79fef03 35 /*If in Handler mode we are always using MSP*/ \
kevman 0:38ceb79fef03 36 if ( __get_IPSR() != 0U ) { \
kevman 0:38ceb79fef03 37 sp = __get_MSP(); \
kevman 0:38ceb79fef03 38 } else { \
kevman 0:38ceb79fef03 39 /*Look into CONTROL.SPSEL value*/ \
kevman 0:38ceb79fef03 40 if ((__get_CONTROL() & 2U) == 0U) { \
kevman 0:38ceb79fef03 41 sp = __get_MSP();/*Read MSP*/ \
kevman 0:38ceb79fef03 42 } else { \
kevman 0:38ceb79fef03 43 sp = __get_PSP();/*Read PSP*/ \
kevman 0:38ceb79fef03 44 } \
kevman 0:38ceb79fef03 45 } \
kevman 0:38ceb79fef03 46 }
kevman 0:38ceb79fef03 47
kevman 0:38ceb79fef03 48 #ifndef NDEBUG
kevman 0:38ceb79fef03 49 #define ERROR_REPORT(ctx, error_msg) print_error_report(ctx, error_msg)
kevman 0:38ceb79fef03 50 #else
kevman 0:38ceb79fef03 51 #define ERROR_REPORT(ctx, error_msg) ((void) 0)
kevman 0:38ceb79fef03 52 #endif
kevman 0:38ceb79fef03 53
kevman 0:38ceb79fef03 54 static uint8_t error_in_progress = 0;
kevman 0:38ceb79fef03 55 static int error_count = 0;
kevman 0:38ceb79fef03 56 static mbed_error_ctx first_error_ctx = {0};
kevman 0:38ceb79fef03 57 static mbed_error_ctx last_error_ctx = {0};
kevman 0:38ceb79fef03 58 static mbed_error_hook_t error_hook = NULL;
kevman 0:38ceb79fef03 59 static void print_error_report(mbed_error_ctx *ctx, const char *);
kevman 0:38ceb79fef03 60 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);
kevman 0:38ceb79fef03 61
kevman 0:38ceb79fef03 62 //Helper function to halt the system
kevman 0:38ceb79fef03 63 static void mbed_halt_system(void)
kevman 0:38ceb79fef03 64 {
kevman 0:38ceb79fef03 65 //If not in ISR context exit, otherwise spin on WFI
kevman 0:38ceb79fef03 66 if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
kevman 0:38ceb79fef03 67 for (;;) {
kevman 0:38ceb79fef03 68 __WFI();
kevman 0:38ceb79fef03 69 }
kevman 0:38ceb79fef03 70 } else {
kevman 0:38ceb79fef03 71 //exit eventually calls mbed_die
kevman 0:38ceb79fef03 72 exit(1);
kevman 0:38ceb79fef03 73 }
kevman 0:38ceb79fef03 74 }
kevman 0:38ceb79fef03 75
kevman 0:38ceb79fef03 76 WEAK void error(const char *format, ...)
kevman 0:38ceb79fef03 77 {
kevman 0:38ceb79fef03 78
kevman 0:38ceb79fef03 79 // Prevent recursion if error is called again
kevman 0:38ceb79fef03 80 if (error_in_progress) {
kevman 0:38ceb79fef03 81 return;
kevman 0:38ceb79fef03 82 }
kevman 0:38ceb79fef03 83
kevman 0:38ceb79fef03 84 //Call handle_error/print_error_report permanently setting error_in_progress flag
kevman 0:38ceb79fef03 85 handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR());
kevman 0:38ceb79fef03 86 ERROR_REPORT(&last_error_ctx, "Fatal Run-time error");
kevman 0:38ceb79fef03 87 error_in_progress = 1;
kevman 0:38ceb79fef03 88
kevman 0:38ceb79fef03 89 #ifndef NDEBUG
kevman 0:38ceb79fef03 90 va_list arg;
kevman 0:38ceb79fef03 91 va_start(arg, format);
kevman 0:38ceb79fef03 92 mbed_error_vfprintf(format, arg);
kevman 0:38ceb79fef03 93 va_end(arg);
kevman 0:38ceb79fef03 94 #endif
kevman 0:38ceb79fef03 95 exit(1);
kevman 0:38ceb79fef03 96 }
kevman 0:38ceb79fef03 97
kevman 0:38ceb79fef03 98 //Set an error status with the error handling system
kevman 0:38ceb79fef03 99 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)
kevman 0:38ceb79fef03 100 {
kevman 0:38ceb79fef03 101 mbed_error_ctx current_error_ctx;
kevman 0:38ceb79fef03 102
kevman 0:38ceb79fef03 103 //Error status should always be < 0
kevman 0:38ceb79fef03 104 if (error_status >= 0) {
kevman 0:38ceb79fef03 105 //This is a weird situation, someone called mbed_error with invalid error code.
kevman 0:38ceb79fef03 106 //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
kevman 0:38ceb79fef03 107 error_status = MBED_ERROR_INVALID_ARGUMENT;
kevman 0:38ceb79fef03 108 }
kevman 0:38ceb79fef03 109
kevman 0:38ceb79fef03 110 //Prevent corruption by holding out other callers
kevman 0:38ceb79fef03 111 //and we also need this until we remove the "error" call completely
kevman 0:38ceb79fef03 112 while (error_in_progress == 1);
kevman 0:38ceb79fef03 113
kevman 0:38ceb79fef03 114 //Use critsect here, as we don't want inadvertant modification of this global variable
kevman 0:38ceb79fef03 115 core_util_critical_section_enter();
kevman 0:38ceb79fef03 116 error_in_progress = 1;
kevman 0:38ceb79fef03 117 core_util_critical_section_exit();
kevman 0:38ceb79fef03 118
kevman 0:38ceb79fef03 119 //Increment error count
kevman 0:38ceb79fef03 120 error_count++;
kevman 0:38ceb79fef03 121
kevman 0:38ceb79fef03 122 //Clear the context capturing buffer
kevman 0:38ceb79fef03 123 memset(&current_error_ctx, 0, sizeof(mbed_error_ctx));
kevman 0:38ceb79fef03 124 //Capture error information
kevman 0:38ceb79fef03 125 current_error_ctx.error_status = error_status;
kevman 0:38ceb79fef03 126 current_error_ctx.error_address = (uint32_t)caller;
kevman 0:38ceb79fef03 127 current_error_ctx.error_value = error_value;
kevman 0:38ceb79fef03 128 #ifdef MBED_CONF_RTOS_PRESENT
kevman 0:38ceb79fef03 129 //Capture thread info
kevman 0:38ceb79fef03 130 osRtxThread_t *current_thread = osRtxInfo.thread.run.curr;
kevman 0:38ceb79fef03 131 current_error_ctx.thread_id = (uint32_t)current_thread;
kevman 0:38ceb79fef03 132 current_error_ctx.thread_entry_address = (uint32_t)current_thread->thread_addr;
kevman 0:38ceb79fef03 133 current_error_ctx.thread_stack_size = current_thread->stack_size;
kevman 0:38ceb79fef03 134 current_error_ctx.thread_stack_mem = (uint32_t)current_thread->stack_mem;
kevman 0:38ceb79fef03 135 #ifdef TARGET_CORTEX_M
kevman 0:38ceb79fef03 136 GET_CURRENT_SP(current_error_ctx.thread_current_sp);
kevman 0:38ceb79fef03 137 #endif //TARGET_CORTEX_M
kevman 0:38ceb79fef03 138
kevman 0:38ceb79fef03 139 #endif //MBED_CONF_RTOS_PRESENT
kevman 0:38ceb79fef03 140
kevman 0:38ceb79fef03 141 #if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED
kevman 0:38ceb79fef03 142 //Capture filename/linenumber if provided
kevman 0:38ceb79fef03 143 //Index for tracking error_filename
kevman 0:38ceb79fef03 144 memset(&current_error_ctx.error_filename, 0, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
kevman 0:38ceb79fef03 145 strncpy(current_error_ctx.error_filename, filename, MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN);
kevman 0:38ceb79fef03 146 current_error_ctx.error_line_number = line_number;
kevman 0:38ceb79fef03 147 #endif
kevman 0:38ceb79fef03 148
kevman 0:38ceb79fef03 149 //Capture the fist system error and store it
kevman 0:38ceb79fef03 150 if (error_count == 1) { //first error
kevman 0:38ceb79fef03 151 memcpy(&first_error_ctx, &current_error_ctx, sizeof(mbed_error_ctx));
kevman 0:38ceb79fef03 152 }
kevman 0:38ceb79fef03 153
kevman 0:38ceb79fef03 154 //copy this error to last error
kevman 0:38ceb79fef03 155 memcpy(&last_error_ctx, &current_error_ctx, sizeof(mbed_error_ctx));
kevman 0:38ceb79fef03 156
kevman 0:38ceb79fef03 157 #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
kevman 0:38ceb79fef03 158 //Log the error with error log
kevman 0:38ceb79fef03 159 mbed_error_hist_put(&current_error_ctx);
kevman 0:38ceb79fef03 160 #endif
kevman 0:38ceb79fef03 161
kevman 0:38ceb79fef03 162 //Call the error hook if available
kevman 0:38ceb79fef03 163 if (error_hook != NULL) {
kevman 0:38ceb79fef03 164 error_hook(&last_error_ctx);
kevman 0:38ceb79fef03 165 }
kevman 0:38ceb79fef03 166
kevman 0:38ceb79fef03 167 error_in_progress = 0;
kevman 0:38ceb79fef03 168
kevman 0:38ceb79fef03 169 return MBED_SUCCESS;
kevman 0:38ceb79fef03 170 }
kevman 0:38ceb79fef03 171
kevman 0:38ceb79fef03 172 //Return the first error
kevman 0:38ceb79fef03 173 mbed_error_status_t mbed_get_first_error(void)
kevman 0:38ceb79fef03 174 {
kevman 0:38ceb79fef03 175 //return the first error recorded
kevman 0:38ceb79fef03 176 return first_error_ctx.error_status;
kevman 0:38ceb79fef03 177 }
kevman 0:38ceb79fef03 178
kevman 0:38ceb79fef03 179 //Return the last error
kevman 0:38ceb79fef03 180 mbed_error_status_t mbed_get_last_error(void)
kevman 0:38ceb79fef03 181 {
kevman 0:38ceb79fef03 182 //return the last error recorded
kevman 0:38ceb79fef03 183 return last_error_ctx.error_status;
kevman 0:38ceb79fef03 184 }
kevman 0:38ceb79fef03 185
kevman 0:38ceb79fef03 186 //Gets the current error count
kevman 0:38ceb79fef03 187 int mbed_get_error_count(void)
kevman 0:38ceb79fef03 188 {
kevman 0:38ceb79fef03 189 //return the current error count
kevman 0:38ceb79fef03 190 return error_count;
kevman 0:38ceb79fef03 191 }
kevman 0:38ceb79fef03 192
kevman 0:38ceb79fef03 193 //Sets a fatal error
kevman 0:38ceb79fef03 194 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)
kevman 0:38ceb79fef03 195 {
kevman 0:38ceb79fef03 196 return handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR());
kevman 0:38ceb79fef03 197 }
kevman 0:38ceb79fef03 198
kevman 0:38ceb79fef03 199 //Sets a fatal error, this function is marked WEAK to be able to override this for some tests
kevman 0:38ceb79fef03 200 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)
kevman 0:38ceb79fef03 201 {
kevman 0:38ceb79fef03 202 //set the error reported and then halt the system
kevman 0:38ceb79fef03 203 if (MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR())) {
kevman 0:38ceb79fef03 204 return MBED_ERROR_FAILED_OPERATION;
kevman 0:38ceb79fef03 205 }
kevman 0:38ceb79fef03 206
kevman 0:38ceb79fef03 207 //On fatal errors print the error context/report
kevman 0:38ceb79fef03 208 ERROR_REPORT(&last_error_ctx, error_msg);
kevman 0:38ceb79fef03 209 mbed_halt_system();
kevman 0:38ceb79fef03 210
kevman 0:38ceb79fef03 211 return MBED_ERROR_FAILED_OPERATION;
kevman 0:38ceb79fef03 212 }
kevman 0:38ceb79fef03 213
kevman 0:38ceb79fef03 214 //Register an application defined callback with error handling
kevman 0:38ceb79fef03 215 mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in)
kevman 0:38ceb79fef03 216 {
kevman 0:38ceb79fef03 217 //register the new hook/callback
kevman 0:38ceb79fef03 218 if (error_hook_in != NULL) {
kevman 0:38ceb79fef03 219 error_hook = error_hook_in;
kevman 0:38ceb79fef03 220 return MBED_SUCCESS;
kevman 0:38ceb79fef03 221 }
kevman 0:38ceb79fef03 222
kevman 0:38ceb79fef03 223 return MBED_ERROR_INVALID_ARGUMENT;
kevman 0:38ceb79fef03 224 }
kevman 0:38ceb79fef03 225
kevman 0:38ceb79fef03 226 //Retrieve the first error context from error log
kevman 0:38ceb79fef03 227 mbed_error_status_t mbed_get_first_error_info(mbed_error_ctx *error_info)
kevman 0:38ceb79fef03 228 {
kevman 0:38ceb79fef03 229 memcpy(error_info, &first_error_ctx, sizeof(first_error_ctx));
kevman 0:38ceb79fef03 230 return MBED_SUCCESS;
kevman 0:38ceb79fef03 231 }
kevman 0:38ceb79fef03 232
kevman 0:38ceb79fef03 233 //Retrieve the last error context from error log
kevman 0:38ceb79fef03 234 mbed_error_status_t mbed_get_last_error_info(mbed_error_ctx *error_info)
kevman 0:38ceb79fef03 235 {
kevman 0:38ceb79fef03 236 memcpy(error_info, &last_error_ctx, sizeof(mbed_error_ctx));
kevman 0:38ceb79fef03 237 return MBED_SUCCESS;
kevman 0:38ceb79fef03 238 }
kevman 0:38ceb79fef03 239
kevman 0:38ceb79fef03 240 //Makes an mbed_error_status_t value
kevman 0:38ceb79fef03 241 mbed_error_status_t mbed_make_error(mbed_error_type_t error_type, mbed_module_type_t entity, mbed_error_code_t error_code)
kevman 0:38ceb79fef03 242 {
kevman 0:38ceb79fef03 243 switch (error_type) {
kevman 0:38ceb79fef03 244 case MBED_ERROR_TYPE_POSIX:
kevman 0:38ceb79fef03 245 if (error_code >= MBED_POSIX_ERROR_BASE && error_code <= MBED_SYSTEM_ERROR_BASE) {
kevman 0:38ceb79fef03 246 return -error_code;
kevman 0:38ceb79fef03 247 }
kevman 0:38ceb79fef03 248 break;
kevman 0:38ceb79fef03 249
kevman 0:38ceb79fef03 250 case MBED_ERROR_TYPE_SYSTEM:
kevman 0:38ceb79fef03 251 if (error_code >= MBED_SYSTEM_ERROR_BASE && error_code <= MBED_CUSTOM_ERROR_BASE) {
kevman 0:38ceb79fef03 252 return MAKE_MBED_ERROR(MBED_ERROR_TYPE_SYSTEM, entity, error_code);
kevman 0:38ceb79fef03 253 }
kevman 0:38ceb79fef03 254 break;
kevman 0:38ceb79fef03 255
kevman 0:38ceb79fef03 256 case MBED_ERROR_TYPE_CUSTOM:
kevman 0:38ceb79fef03 257 if (error_code >= MBED_CUSTOM_ERROR_BASE) {
kevman 0:38ceb79fef03 258 return MAKE_MBED_ERROR(MBED_ERROR_TYPE_CUSTOM, entity, error_code);
kevman 0:38ceb79fef03 259 }
kevman 0:38ceb79fef03 260 break;
kevman 0:38ceb79fef03 261
kevman 0:38ceb79fef03 262 default:
kevman 0:38ceb79fef03 263 break;
kevman 0:38ceb79fef03 264 }
kevman 0:38ceb79fef03 265
kevman 0:38ceb79fef03 266 //If we are passed incorrect values return a generic system error
kevman 0:38ceb79fef03 267 return MAKE_MBED_ERROR(MBED_ERROR_TYPE_SYSTEM, MBED_MODULE_UNKNOWN, MBED_ERROR_CODE_UNKNOWN);
kevman 0:38ceb79fef03 268 }
kevman 0:38ceb79fef03 269
kevman 0:38ceb79fef03 270 /**
kevman 0:38ceb79fef03 271 * Clears all the last error, error count and all entries in the error log.
kevman 0:38ceb79fef03 272 * @return 0 or MBED_SUCCESS on success.
kevman 0:38ceb79fef03 273 *
kevman 0:38ceb79fef03 274 */
kevman 0:38ceb79fef03 275 mbed_error_status_t mbed_clear_all_errors(void)
kevman 0:38ceb79fef03 276 {
kevman 0:38ceb79fef03 277 mbed_error_status_t status = MBED_SUCCESS;
kevman 0:38ceb79fef03 278
kevman 0:38ceb79fef03 279 //Make sure we dont multiple clients resetting
kevman 0:38ceb79fef03 280 core_util_critical_section_enter();
kevman 0:38ceb79fef03 281 //Clear the error and context capturing buffer
kevman 0:38ceb79fef03 282 memset(&last_error_ctx, 0, sizeof(mbed_error_ctx));
kevman 0:38ceb79fef03 283 //reset error count to 0
kevman 0:38ceb79fef03 284 error_count = 0;
kevman 0:38ceb79fef03 285 #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
kevman 0:38ceb79fef03 286 status = mbed_error_hist_reset();
kevman 0:38ceb79fef03 287 #endif
kevman 0:38ceb79fef03 288 core_util_critical_section_exit();
kevman 0:38ceb79fef03 289
kevman 0:38ceb79fef03 290 return status;
kevman 0:38ceb79fef03 291 }
kevman 0:38ceb79fef03 292
kevman 0:38ceb79fef03 293 #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
kevman 0:38ceb79fef03 294 /* Prints info of a thread(using osRtxThread_t struct)*/
kevman 0:38ceb79fef03 295 static void print_thread(osRtxThread_t *thread)
kevman 0:38ceb79fef03 296 {
kevman 0:38ceb79fef03 297 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);
kevman 0:38ceb79fef03 298 }
kevman 0:38ceb79fef03 299
kevman 0:38ceb79fef03 300 /* Prints thread info from a list */
kevman 0:38ceb79fef03 301 static void print_threads_info(osRtxThread_t *threads)
kevman 0:38ceb79fef03 302 {
kevman 0:38ceb79fef03 303 while (threads != NULL) {
kevman 0:38ceb79fef03 304 print_thread(threads);
kevman 0:38ceb79fef03 305 threads = threads->thread_next;
kevman 0:38ceb79fef03 306 }
kevman 0:38ceb79fef03 307 }
kevman 0:38ceb79fef03 308 #endif
kevman 0:38ceb79fef03 309
kevman 0:38ceb79fef03 310 #ifndef NDEBUG
kevman 0:38ceb79fef03 311 static void print_error_report(mbed_error_ctx *ctx, const char *error_msg)
kevman 0:38ceb79fef03 312 {
kevman 0:38ceb79fef03 313 uint32_t error_code = MBED_GET_ERROR_CODE(ctx->error_status);
kevman 0:38ceb79fef03 314 uint32_t error_module = MBED_GET_ERROR_MODULE(ctx->error_status);
kevman 0:38ceb79fef03 315
kevman 0:38ceb79fef03 316 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);
kevman 0:38ceb79fef03 317
kevman 0:38ceb79fef03 318 switch (error_code) {
kevman 0:38ceb79fef03 319 //These are errors reported by kernel handled from mbed_rtx_handlers
kevman 0:38ceb79fef03 320 case MBED_ERROR_CODE_RTOS_EVENT:
kevman 0:38ceb79fef03 321 mbed_error_printf("Kernel Error: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 322 break;
kevman 0:38ceb79fef03 323
kevman 0:38ceb79fef03 324 case MBED_ERROR_CODE_RTOS_THREAD_EVENT:
kevman 0:38ceb79fef03 325 mbed_error_printf("Thread: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 326 break;
kevman 0:38ceb79fef03 327
kevman 0:38ceb79fef03 328 case MBED_ERROR_CODE_RTOS_MUTEX_EVENT:
kevman 0:38ceb79fef03 329 mbed_error_printf("Mutex: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 330 break;
kevman 0:38ceb79fef03 331
kevman 0:38ceb79fef03 332 case MBED_ERROR_CODE_RTOS_SEMAPHORE_EVENT:
kevman 0:38ceb79fef03 333 mbed_error_printf("Semaphore: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 334 break;
kevman 0:38ceb79fef03 335
kevman 0:38ceb79fef03 336 case MBED_ERROR_CODE_RTOS_MEMORY_POOL_EVENT:
kevman 0:38ceb79fef03 337 mbed_error_printf("MemoryPool: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 338 break;
kevman 0:38ceb79fef03 339
kevman 0:38ceb79fef03 340 case MBED_ERROR_CODE_RTOS_EVENT_FLAGS_EVENT:
kevman 0:38ceb79fef03 341 mbed_error_printf("EventFlags: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 342 break;
kevman 0:38ceb79fef03 343
kevman 0:38ceb79fef03 344 case MBED_ERROR_CODE_RTOS_TIMER_EVENT:
kevman 0:38ceb79fef03 345 mbed_error_printf("Timer: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 346 break;
kevman 0:38ceb79fef03 347
kevman 0:38ceb79fef03 348 case MBED_ERROR_CODE_RTOS_MESSAGE_QUEUE_EVENT:
kevman 0:38ceb79fef03 349 mbed_error_printf("MessageQueue: 0x%X, ", ctx->error_value);
kevman 0:38ceb79fef03 350 break;
kevman 0:38ceb79fef03 351
kevman 0:38ceb79fef03 352 default:
kevman 0:38ceb79fef03 353 //Nothing to do here, just print the error info down
kevman 0:38ceb79fef03 354 break;
kevman 0:38ceb79fef03 355 }
kevman 0:38ceb79fef03 356 mbed_error_printf(error_msg);
kevman 0:38ceb79fef03 357 mbed_error_printf("\nLocation: 0x%X", ctx->error_address);
kevman 0:38ceb79fef03 358
kevman 0:38ceb79fef03 359 #if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED && !defined(NDEBUG)
kevman 0:38ceb79fef03 360 if ((NULL != ctx->error_filename[0]) && (ctx->error_line_number != 0)) {
kevman 0:38ceb79fef03 361 //for string, we must pass address of a ptr which has the address of the string
kevman 0:38ceb79fef03 362 mbed_error_printf("\nFile:%s+%d", ctx->error_filename, ctx->error_line_number);
kevman 0:38ceb79fef03 363 }
kevman 0:38ceb79fef03 364 #endif
kevman 0:38ceb79fef03 365
kevman 0:38ceb79fef03 366 mbed_error_printf("\nError Value: 0x%X", ctx->error_value);
kevman 0:38ceb79fef03 367 #ifdef TARGET_CORTEX_M
kevman 0:38ceb79fef03 368 mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X SP: 0x%X ",
kevman 0:38ceb79fef03 369 ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem, ctx->thread_current_sp);
kevman 0:38ceb79fef03 370 #else
kevman 0:38ceb79fef03 371 //For Cortex-A targets we dont have support to capture the current SP
kevman 0:38ceb79fef03 372 mbed_error_printf("\nCurrent Thread: Id: 0x%X Entry: 0x%X StackSize: 0x%X StackMem: 0x%X ",
kevman 0:38ceb79fef03 373 ctx->thread_id, ctx->thread_entry_address, ctx->thread_stack_size, ctx->thread_stack_mem);
kevman 0:38ceb79fef03 374 #endif //TARGET_CORTEX_M
kevman 0:38ceb79fef03 375
kevman 0:38ceb79fef03 376 #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT)
kevman 0:38ceb79fef03 377 mbed_error_printf("\nNext:");
kevman 0:38ceb79fef03 378 print_thread(osRtxInfo.thread.run.next);
kevman 0:38ceb79fef03 379
kevman 0:38ceb79fef03 380 mbed_error_printf("\nWait:");
kevman 0:38ceb79fef03 381 osRtxThread_t *threads = (osRtxThread_t *)&osRtxInfo.thread.wait_list;
kevman 0:38ceb79fef03 382 print_threads_info(threads);
kevman 0:38ceb79fef03 383
kevman 0:38ceb79fef03 384 mbed_error_printf("\nDelay:");
kevman 0:38ceb79fef03 385 threads = (osRtxThread_t *)&osRtxInfo.thread.delay_list;
kevman 0:38ceb79fef03 386 print_threads_info(threads);
kevman 0:38ceb79fef03 387
kevman 0:38ceb79fef03 388 mbed_error_printf("\nIdle:");
kevman 0:38ceb79fef03 389 threads = (osRtxThread_t *)&osRtxInfo.thread.idle;
kevman 0:38ceb79fef03 390 print_threads_info(threads);
kevman 0:38ceb79fef03 391 #endif
kevman 0:38ceb79fef03 392 mbed_error_printf(MBED_CONF_PLATFORM_ERROR_DECODE_HTTP_URL_STR, ctx->error_status);
kevman 0:38ceb79fef03 393 mbed_error_printf("\n-- MbedOS Error Info --\n");
kevman 0:38ceb79fef03 394 }
kevman 0:38ceb79fef03 395 #endif //ifndef NDEBUG
kevman 0:38ceb79fef03 396
kevman 0:38ceb79fef03 397 #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED
kevman 0:38ceb79fef03 398 //Retrieve the error context from error log at the specified index
kevman 0:38ceb79fef03 399 mbed_error_status_t mbed_get_error_hist_info(int index, mbed_error_ctx *error_info)
kevman 0:38ceb79fef03 400 {
kevman 0:38ceb79fef03 401 return mbed_error_hist_get(index, error_info);
kevman 0:38ceb79fef03 402 }
kevman 0:38ceb79fef03 403
kevman 0:38ceb79fef03 404 //Retrieve the error log count
kevman 0:38ceb79fef03 405 int mbed_get_error_hist_count(void)
kevman 0:38ceb79fef03 406 {
kevman 0:38ceb79fef03 407 return mbed_error_hist_get_count();
kevman 0:38ceb79fef03 408 }
kevman 0:38ceb79fef03 409
kevman 0:38ceb79fef03 410 mbed_error_status_t mbed_save_error_hist(const char *path)
kevman 0:38ceb79fef03 411 {
kevman 0:38ceb79fef03 412 mbed_error_status_t ret = MBED_SUCCESS;
kevman 0:38ceb79fef03 413 mbed_error_ctx ctx = {0};
kevman 0:38ceb79fef03 414 int log_count = mbed_error_hist_get_count();
kevman 0:38ceb79fef03 415 FILE *error_log_file = NULL;
kevman 0:38ceb79fef03 416
kevman 0:38ceb79fef03 417 //Ensure path is valid
kevman 0:38ceb79fef03 418 if (path == NULL) {
kevman 0:38ceb79fef03 419 ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT);
kevman 0:38ceb79fef03 420 goto exit;
kevman 0:38ceb79fef03 421 }
kevman 0:38ceb79fef03 422
kevman 0:38ceb79fef03 423 //Open the file for saving the error log info
kevman 0:38ceb79fef03 424 if ((error_log_file = fopen(path, "w")) == NULL) {
kevman 0:38ceb79fef03 425 ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OPEN_FAILED);
kevman 0:38ceb79fef03 426 goto exit;
kevman 0:38ceb79fef03 427 }
kevman 0:38ceb79fef03 428
kevman 0:38ceb79fef03 429 //First store the first and last errors
kevman 0:38ceb79fef03 430 if (fprintf(error_log_file, "\nFirst Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
kevman 0:38ceb79fef03 431 (unsigned int)first_error_ctx.error_status,
kevman 0:38ceb79fef03 432 (unsigned int)first_error_ctx.thread_id,
kevman 0:38ceb79fef03 433 (unsigned int)first_error_ctx.error_address,
kevman 0:38ceb79fef03 434 (unsigned int)first_error_ctx.error_value) <= 0) {
kevman 0:38ceb79fef03 435 ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
kevman 0:38ceb79fef03 436 goto exit;
kevman 0:38ceb79fef03 437 }
kevman 0:38ceb79fef03 438
kevman 0:38ceb79fef03 439 if (fprintf(error_log_file, "\nLast Error: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
kevman 0:38ceb79fef03 440 (unsigned int)last_error_ctx.error_status,
kevman 0:38ceb79fef03 441 (unsigned int)last_error_ctx.thread_id,
kevman 0:38ceb79fef03 442 (unsigned int)last_error_ctx.error_address,
kevman 0:38ceb79fef03 443 (unsigned int)last_error_ctx.error_value) <= 0) {
kevman 0:38ceb79fef03 444 ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
kevman 0:38ceb79fef03 445 goto exit;
kevman 0:38ceb79fef03 446 }
kevman 0:38ceb79fef03 447
kevman 0:38ceb79fef03 448 //Update with error log info
kevman 0:38ceb79fef03 449 while (--log_count >= 0) {
kevman 0:38ceb79fef03 450 mbed_error_hist_get(log_count, &ctx);
kevman 0:38ceb79fef03 451 //first line of file will be error log count
kevman 0:38ceb79fef03 452 if (fprintf(error_log_file, "\n%d: Status:0x%x ThreadId:0x%x Address:0x%x Value:0x%x\n",
kevman 0:38ceb79fef03 453 log_count,
kevman 0:38ceb79fef03 454 (unsigned int)ctx.error_status,
kevman 0:38ceb79fef03 455 (unsigned int)ctx.thread_id,
kevman 0:38ceb79fef03 456 (unsigned int)ctx.error_address,
kevman 0:38ceb79fef03 457 (unsigned int)ctx.error_value) <= 0) {
kevman 0:38ceb79fef03 458 ret = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED);
kevman 0:38ceb79fef03 459 goto exit;
kevman 0:38ceb79fef03 460 }
kevman 0:38ceb79fef03 461 }
kevman 0:38ceb79fef03 462
kevman 0:38ceb79fef03 463 exit:
kevman 0:38ceb79fef03 464 fclose(error_log_file);
kevman 0:38ceb79fef03 465
kevman 0:38ceb79fef03 466 return ret;
kevman 0:38ceb79fef03 467 }
kevman 0:38ceb79fef03 468 #endif
kevman 0:38ceb79fef03 469