Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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