Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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