From 6181394e3768e1b656e67c35815247cab23e0aa1 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Mon, 12 Nov 2018 19:37:54 -0600 Subject: [PATCH 1/9] Error and fault handling changes for crash reporting --- cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S | 3 +- cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S | 3 +- cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S | 3 +- cmsis/TARGET_CORTEX_M/mbed_fault_handler.c | 40 +++-- cmsis/TARGET_CORTEX_M/mbed_fault_handler.h | 20 ++- platform/mbed_crash_data_offsets.h | 58 +++++++ platform/mbed_error.c | 172 +++++++++++++++++-- platform/mbed_error.h | 57 ++++++ platform/mbed_lib.json | 16 ++ rtos/TARGET_CORTEX/mbed_boot.c | 2 + 10 files changed, 345 insertions(+), 29 deletions(-) create mode 100644 platform/mbed_crash_data_offsets.h diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S index 9eaf7e8aff..b0a4997737 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/except.S @@ -80,7 +80,8 @@ Fault_Handler PROC Fault_Handler_Continue MOV R12,R3 - LDR R1,=mbed_fault_context + LDR R3,=mbed_fault_context + LDR R1,[R3] LDR R2,[R0] ; Capture R0 STR R2,[R1] ADDS R1,#4 diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S index fdd3844896..74a2c8bc43 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/except.S @@ -113,7 +113,8 @@ Fault_Handler: Fault_Handler_Continue: MOV R12,R3 - LDR R1,=mbed_fault_context + LDR R3,=mbed_fault_context + LDR R1,[R3] LDR R2,[R0] // Capture R0 STR R2,[R1] ADDS R1,#4 diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S index e6cf1ba6fb..64936c220f 100644 --- a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_IAR/except.S @@ -75,7 +75,8 @@ Fault_Handler Fault_Handler_Continue MOV R12,R3 - LDR R1,=mbed_fault_context + LDR R3,=mbed_fault_context + LDR R1,[R3] LDR R2,[R0] ; Capture R0 STR R2,[R1] ADDS R1,#4 diff --git a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c index c56ad0d45f..abd5611658 100644 --- a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c +++ b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c @@ -20,8 +20,9 @@ #include #include "device.h" -#include "platform/mbed_error.h" -#include "platform/mbed_interface.h" +#include "mbed_error.h" +#include "mbed_interface.h" +#include "mbed_crash_data_offsets.h" #ifndef MBED_FAULT_HANDLER_DISABLED #include "mbed_fault_handler.h" @@ -29,8 +30,13 @@ //Functions Prototypes void print_context_info(void); -//Global for populating the context in exception handler -mbed_fault_context_t mbed_fault_context; +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + //Global for populating the context in exception handler + mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)((uint32_t)FAULT_CONTEXT_LOCATION); +#else + mbed_fault_context_t fault_context; + mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)&fault_context; +#endif //This is a handler function called from Fault handler to print the error information out. //This runs in fault context and uses special functions(defined in mbed_rtx_fault_handler.c) to print the information without using C-lib support. @@ -69,7 +75,7 @@ void mbed_fault_handler (uint32_t fault_type, void *mbed_fault_context_in) mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n"); //Now call mbed_error, to log the error and halt the system - mbed_error( faultStatus, "Fault exception", mbed_fault_context.PC_reg, NULL, 0 ); + mbed_error( faultStatus, "Fault exception", mbed_fault_context->PC_reg, NULL, 0 ); } @@ -77,7 +83,7 @@ MBED_NOINLINE void print_context_info(void) { //Context Regs for(int i=0;i<13;i++) { - mbed_error_printf("\nR%-4d: %08" PRIX32, i, ((uint32_t *)&mbed_fault_context)[i]); + mbed_error_printf("\nR%-4d: %08" PRIX32, i, ((uint32_t *)(mbed_fault_context))[i]); } mbed_error_printf("\nSP : %08" PRIX32 @@ -85,8 +91,8 @@ MBED_NOINLINE void print_context_info(void) "\nPC : %08" PRIX32 "\nxPSR : %08" PRIX32 "\nPSP : %08" PRIX32 - "\nMSP : %08" PRIX32, mbed_fault_context.SP_reg, mbed_fault_context.LR_reg, mbed_fault_context.PC_reg, - mbed_fault_context.xPSR, mbed_fault_context.PSP, mbed_fault_context.MSP ); + "\nMSP : %08" PRIX32, mbed_fault_context->SP_reg, mbed_fault_context->LR_reg, mbed_fault_context->PC_reg, + mbed_fault_context->xPSR, mbed_fault_context->PSP, mbed_fault_context->MSP ); //Capture CPUID to get core/cpu info mbed_error_printf("\nCPUID: %08" PRIX32, SCB->CPUID); @@ -112,12 +118,12 @@ MBED_NOINLINE void print_context_info(void) #endif //Print Mode - if (mbed_fault_context.EXC_RETURN & 0x8) { + if (mbed_fault_context->EXC_RETURN & 0x8) { mbed_error_printf("\nMode : Thread"); //Print Priv level in Thread mode - We capture CONTROL reg which reflects the privilege. //Note that the CONTROL register captured still reflects the privilege status of the //thread mode eventhough we are in Handler mode by the time we capture it. - if(mbed_fault_context.CONTROL & 0x1) { + if(mbed_fault_context->CONTROL & 0x1) { mbed_error_printf("\nPriv : User"); } else { mbed_error_printf("\nPriv : Privileged"); @@ -127,11 +133,23 @@ MBED_NOINLINE void print_context_info(void) mbed_error_printf("\nPriv : Privileged"); } //Print Return Stack - if (mbed_fault_context.EXC_RETURN & 0x4) { + if (mbed_fault_context->EXC_RETURN & 0x4) { mbed_error_printf("\nStack: PSP"); } else { mbed_error_printf("\nStack: MSP"); } } +mbed_error_status_t mbed_get_reboot_fault_context (mbed_fault_context_t *fault_context) +{ + mbed_error_status_t status = MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_ITEM_NOT_FOUND); +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + if(fault_context == NULL) + return MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT); + memcpy(fault_context, mbed_fault_context, sizeof(mbed_fault_context_t)); + status = MBED_SUCCESS; +#endif + return status; +} + #endif //MBED_FAULT_HANDLER_SUPPORT diff --git a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.h b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.h index bcc3ded135..e55a57ddca 100644 --- a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.h +++ b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.h @@ -15,7 +15,11 @@ */ #ifndef MBED_FAULT_HANDLER_H -#define MBED_FAULT_HANDLER_H +#define MBED_FAULT_HANDLER_H + +#ifdef __cplusplus +extern "C" { +#endif //Fault context struct //WARNING: DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES in except.S files. @@ -55,4 +59,18 @@ typedef struct { //This runs in fault context and uses special functions(defined in mbed_fault_handler.c) to print the information without using C-lib support. void mbed_fault_handler (uint32_t fault_type, void *mbed_fault_context_in); +/** + * Call this function to retrieve the fault context after a fatal exception which triggered a system reboot. The function retrieves the fault context stored in crash-report ram area which is preserved over reboot. + * @param fault_context Pointer to mbed_fault_context_t struct allocated by the caller. This is the mbed_fault_context_t info captured as part of the fatal exception which triggered the reboot. + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer + * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by teh system + * + */ +mbed_error_status_t mbed_get_reboot_fault_context (mbed_fault_context_t *fault_context); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/platform/mbed_crash_data_offsets.h b/platform/mbed_crash_data_offsets.h new file mode 100644 index 0000000000..f2df59fe13 --- /dev/null +++ b/platform/mbed_crash_data_offsets.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_CRASH_DATA_INFO_H +#define MBED_CRASH_DATA_INFO_H + +#include "platform/mbed_retarget.h" +#include "platform/mbed_toolchain.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + extern uint32_t Image$$RW_m_crash_data$$ZI$$Base[]; + extern uint32_t Image$$RW_m_crash_data$$ZI$$Size; + #define __CRASH_DATA_RAM_START__ Image$$RW_m_crash_data$$ZI$$Base + #define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size + #elif defined(__ICCARM__) + extern uint32_t __CRASH_DATA_RAM_START__[]; + extern uint32_t __CRASH_DATA_RAM_END__[]; + #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) + #elif defined(__GNUC__) + extern uint32_t __CRASH_DATA_RAM_START__[]; + extern uint32_t __CRASH_DATA_RAM_END__[]; + #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) + #endif /* defined(__CC_ARM) */ + + /* Offset definitions for context capture */ + #define FAULT_CONTEXT_OFFSET (0x0) + #define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context + #define ERROR_CONTEXT_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE) + #define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context + #define FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET) + #define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET) +#endif + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/platform/mbed_error.c b/platform/mbed_error.c index efd5ef5fba..de4064a9a9 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -17,10 +17,13 @@ #include #include #include "device.h" +#include "platform/mbed_crash_data_offsets.h" +#include "platform/mbed_retarget.h" #include "platform/mbed_critical.h" #include "platform/mbed_error.h" #include "platform/mbed_error_hist.h" #include "platform/mbed_interface.h" +#include "platform/mbed_power_mgmt.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtx_os.h" #endif @@ -34,8 +37,8 @@ #include #ifndef NDEBUG -#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) print_error_report(ctx, error_msg, error_filename, error_line) -static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line); +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line, print_thread_info) print_error_report(ctx, error_msg, error_filename, error_line, print_thread_info) +static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line, bool print_thread_info); #else #define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0) #endif @@ -44,10 +47,46 @@ static core_util_atomic_flag error_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; static core_util_atomic_flag halt_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; static int error_count = 0; static mbed_error_ctx first_error_ctx = {0}; + +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + //Global for populating the context in exception handler + static mbed_error_ctx *report_error_ctx=(mbed_error_ctx *)((uint32_t)ERROR_CONTEXT_LOCATION); + static bool is_reboot_error_valid = false; +#endif + static mbed_error_ctx last_error_ctx = {0}; static mbed_error_hook_t error_hook = NULL; 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); +//Helper function to calculate CRC +//NOTE: It would have been better to use MbedCRC implementation. But +//MbedCRC uses table based calculation and we dont want to keep that table memory +//used up for this purpose. Also we cannot force bitwise calculation in MbedCRC +//and it also requires a new wrapper to be called from C implementation. Since +//we dont have many uses cases to create a C wrapper for MbedCRC and the data +//we calculate CRC on in this context is very less we will use a local +//implementation here. +static unsigned int compute_crc32(unsigned char *data, int datalen) +{ + const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */ + unsigned int crc = 0; /* CRC value is 32bit */ + + for( ;datalen>=0; datalen-- ) { + unsigned char b = *data; + crc ^= (unsigned int )(b << 24); /* move byte into upper 8bit */ + for (int i = 0; i < 8; i++) { + /* is MSB 1 */ + if ((crc & 0x80000000) != 0) { + crc = (unsigned int)((crc << 1) ^ polynomial); + } else { + crc <<= 1; + } + } + } + + return crc; +} + //Helper function to halt the system static MBED_NORETURN void mbed_halt_system(void) { @@ -75,7 +114,7 @@ WEAK MBED_NORETURN void error(const char *format, ...) // Prevent recursion if error is called again during store+print attempt if (!core_util_atomic_flag_test_and_set(&error_in_progress)) { handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR()); - ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0); + ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0, true); #ifndef NDEBUG va_list arg; @@ -152,6 +191,44 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign return MBED_SUCCESS; } +WEAK void mbed_error_reboot_callback(mbed_error_ctx *error_context) { + //Dont do anything here, let application override this if required. +} + +//Initialize Error handling system and report any errors detected on rebooted +mbed_error_status_t mbed_error_initialize(void) +{ +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + uint32_t crc_val = 0; + crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + //Read report_error_ctx and check if CRC is correct for report_error_ctx + if((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) { + is_reboot_error_valid = true; +#if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) + //Report the error info + mbed_error_printf("\n== Your last reboot was triggered by an error, below is the error information =="); + ERROR_REPORT( report_error_ctx, "System rebooted due to fatal error", MBED_FILENAME, __LINE__, false ); +#endif + //Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling + mbed_error_reboot_callback(report_error_ctx); + + //Enforce max-reboot only if auto reboot is enabled +#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED + if( report_error_ctx->error_reboot_count > MBED_CONF_PLATFORM_ERROR_REBOOT_MAX ) { + //We have rebooted more than enough, hold the system here. + mbed_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); + mbed_halt_system(); + } +#endif + report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error + crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + report_error_ctx->crc_error_ctx = crc_val; + } +#endif + + return MBED_SUCCESS; +} + //Return the first error mbed_error_status_t mbed_get_first_error(void) { @@ -188,17 +265,40 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat (void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR()); //On fatal errors print the error context/report - ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number); + ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number, true); } + +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + uint32_t crc_val = 0; + crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + //Read report_error_ctx and check if CRC is correct for report_error_ctx + if(report_error_ctx->crc_error_ctx == crc_val) { + uint32_t current_reboot_count = report_error_ctx->error_reboot_count; + last_error_ctx.error_reboot_count = current_reboot_count + 1; + } else { + last_error_ctx.error_reboot_count = 1; + } + last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error + //Update the struct with crc + last_error_ctx.crc_error_ctx = compute_crc32( (unsigned char *)&last_error_ctx, ((uint32_t)&(last_error_ctx.crc_error_ctx) - (uint32_t)&last_error_ctx) ); + memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx)); + //We need not call delete_mbed_crc(crc_obj) here as we are going to reset the system anyway, and calling delete while handling a fatal error may cause nested exception +#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED + system_reset();//do a system reset to get the system rebooted + while(1); +#endif +#endif mbed_halt_system(); + + return MBED_ERROR_FAILED_OPERATION; } //Register an application defined callback with error handling mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in) { //register the new hook/callback - if (error_hook_in != NULL) { + if (error_hook_in != NULL) { error_hook = error_hook_in; return MBED_SUCCESS; } @@ -206,6 +306,48 @@ mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in) return MBED_ERROR_INVALID_ARGUMENT; } +//Reset the reboot error context +mbed_error_status_t mbed_reset_reboot_error_info() +{ +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + memset(report_error_ctx, 0, sizeof(mbed_error_ctx) ); +#endif + return MBED_SUCCESS; +} + +//Reset the reboot error context +mbed_error_status_t mbed_reset_reboot_count() +{ +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + if(is_reboot_error_valid) { + uint32_t crc_val = 0; + report_error_ctx->error_reboot_count = 0;//Set reboot count to 0 + //Update CRC + crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + report_error_ctx->crc_error_ctx = crc_val; + return MBED_SUCCESS; + } +#endif + return MBED_ERROR_ITEM_NOT_FOUND; +} + +//Retrieve the reboot error context +mbed_error_status_t mbed_get_reboot_error_info(mbed_error_ctx *error_info) +{ + mbed_error_status_t status = MBED_ERROR_ITEM_NOT_FOUND; +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + if (is_reboot_error_valid) { + if(error_info != NULL) { + memcpy(error_info, report_error_ctx, sizeof(mbed_error_ctx)); + status = MBED_SUCCESS; + } else { + status = MBED_ERROR_INVALID_ARGUMENT; + } + } +#endif + return status; +} + //Retrieve the first error context from error log mbed_error_status_t mbed_get_first_error_info(mbed_error_ctx *error_info) { @@ -296,7 +438,7 @@ static void print_threads_info(const osRtxThread_t *threads) #endif #ifndef NDEBUG -static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, const char *error_filename, int error_line) +static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, const char *error_filename, int error_line, bool print_thread_info) { int error_code = MBED_GET_ERROR_CODE(ctx->error_status); int error_module = MBED_GET_ERROR_MODULE(ctx->error_status); @@ -369,17 +511,19 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, #endif #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT) - mbed_error_printf("\nNext:"); - print_thread(osRtxInfo.thread.run.next); + if(print_thread_info == true) { + mbed_error_printf("\nNext:"); + print_thread(osRtxInfo.thread.run.next); - mbed_error_printf("\nReady:"); - print_threads_info(osRtxInfo.thread.ready.thread_list); + mbed_error_printf("\nReady:"); + print_threads_info(osRtxInfo.thread.ready.thread_list); - mbed_error_printf("\nWait:"); - print_threads_info(osRtxInfo.thread.wait_list); + mbed_error_printf("\nWait:"); + print_threads_info(osRtxInfo.thread.wait_list); - mbed_error_printf("\nDelay:"); - print_threads_info(osRtxInfo.thread.delay_list); + mbed_error_printf("\nDelay:"); + print_threads_info(osRtxInfo.thread.delay_list); + } #endif mbed_error_printf(MBED_CONF_PLATFORM_ERROR_DECODE_HTTP_URL_STR, ctx->error_status); mbed_error_printf("\n-- MbedOS Error Info --\n"); diff --git a/platform/mbed_error.h b/platform/mbed_error.h index d301c001df..4a10343626 100644 --- a/platform/mbed_error.h +++ b/platform/mbed_error.h @@ -827,6 +827,11 @@ typedef struct _mbed_error_ctx { char error_filename[MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN]; uint32_t error_line_number; #endif +#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED + int32_t error_reboot_count;//everytime we write this struct we increment this value by 1, irrespective of time between reboots. Note that the data itself might change, but everytime we reboot due to error we update this count by 1 + int32_t is_error_processed;//once this error is processed set this value to 1 + uint32_t crc_error_ctx;//crc_error_ctx should always be the last member in this struct +#endif } mbed_error_ctx; /** To generate a fatal compile-time error, you can use the pre-processor #error directive. @@ -928,6 +933,58 @@ MBED_NORETURN void error(const char *format, ...) MBED_PRINTF(1, 2); */ typedef void (*mbed_error_hook_t)(const mbed_error_ctx *error_ctx); + +/** + * Callback function for reporting error context during boot up. When MbedOS error handling system detects a fatal error + * it will auto-reboot the system(if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled) after capturing the + * error info in special crash data RAM region. Once rebooted, MbedOS initialization routines will call this function with a pointer to + * the captured mbed_error_ctx structure. If application implementation needs to receive this callback, mbed_error_reboot_callback + * function should be overriden with custom implementation. By default it's defined as a WEAK function in mbed_error.c. + * Note that this callback will be invoked before the system starts executing main() function. So the implementation of + * the callback should be aware any resource limitations/availability of resources which are yet to be initialized by application main(). + * + * @param error_ctx Error context structure associated with this error. + * @return void + * + */ +void mbed_error_reboot_callback(mbed_error_ctx *error_context); + +/** + * Initialize error handling system, this is called by the mbed-os boot sequence. This is not required to be called by Application unless the boot sequence is overridden by the system implementation. + * NOTE: This function also prints the error report to serial terminal if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED is enabled. + * If MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled and if the current reboot count exceeds MBED_CONF_PLATFORM_ERROR_REBOOT_MAX the system will halt when this function is called, + * and in such cases the caller will not get the control back. Also note that calling this function may trigger mbed_error_reboot_callback() if application side overides mbed_error_reboot_callback(). + * @return MBED_SUCCESS on success. + * + */ + +mbed_error_status_t mbed_error_initialize(void); + +/** + * Call this function to retrieve the error context after a fatal error which triggered a system reboot. The function retrieves the error context stored in crash-report ram area which is preserved over reboot. + * @param error_info Pointer to mbed_error_ctx struct allocated by the caller. This is the mbed_error_ctx info captured as part of the fatal error which triggered the reboot. + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer + * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system + * + */ +mbed_error_status_t mbed_get_reboot_error_info(mbed_error_ctx *error_info); + +/** + * Calling this function resets the current reboot context captured by the system(stored in special crash data RAM region). + * @return MBED_SUCCESS on success. + * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system + */ +mbed_error_status_t mbed_reset_reboot_error_info(void); + +/** + * Calling this function resets the current reboot count stored as part of error context captured in special crash data RAM region. + * The function will also update the CRC value stored as part of error context accordingly. + * @return MBED_SUCCESS on success. + * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system + */ +mbed_error_status_t mbed_reset_reboot_count(void); + /** * Call this function to set a system error/warning. This function will log the error status with the context info and return to caller. * diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index cc423415fd..1531c48818 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -109,6 +109,22 @@ "cthunk_count_max": { "help": "The maximum CThunk objects used at the same time. This must be greater than 0 and less 256", "value": 8 + }, + "crash-capture-enabled": { + "help": "Enables crash context capture when the system enters a fatal error/crash.", + "value": false + }, + "reboot-crash-report-enabled": { + "help": "Enables crash context capture when the system enters a fatal error/crash.", + "value": false + }, + "error-reboot-max": { + "help": "Maximum number of auto reboots permitted when an error happens.", + "value": 0 + }, + "fatal-error-auto-reboot-enabled": { + "help": "Setting this to true enables auto-reboot on a fatal error.", + "value": false } }, "target_overrides": { diff --git a/rtos/TARGET_CORTEX/mbed_boot.c b/rtos/TARGET_CORTEX/mbed_boot.c index f09ff9345a..7ae4efb0af 100644 --- a/rtos/TARGET_CORTEX/mbed_boot.c +++ b/rtos/TARGET_CORTEX/mbed_boot.c @@ -75,6 +75,7 @@ #include "cmsis.h" #include "mbed_toolchain.h" #include "mbed_boot.h" +#include "mbed_error.h" int main(void); static void mbed_cpy_nvic(void); @@ -94,6 +95,7 @@ void mbed_start(void) { mbed_toolchain_init(); mbed_main(); + mbed_error_initialize(); main(); } From ef8c1c3cb6b7a6063205cc4e787bdc5c4ca2c858 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Mon, 12 Nov 2018 22:14:26 -0600 Subject: [PATCH 2/9] Linker script modifications for crash data region --- .../TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct | 9 ++++++-- .../TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld | 13 ++++++++++++ .../device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf | 7 ++++++- .../TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct | 9 ++++++-- .../TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld | 13 ++++++++++++ .../device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf | 7 ++++++- .../device/TOOLCHAIN_ARM_STD/nRF52840.sct | 10 +++++++-- .../device/TOOLCHAIN_GCC_ARM/NRF52840.ld | 21 +++++++++++++++++-- .../device/TOOLCHAIN_IAR/nRF52840.icf | 8 +++++-- .../device/TOOLCHAIN_ARM_MICRO/M487.sct | 16 ++++++++++++-- .../device/TOOLCHAIN_ARM_STD/M487.sct | 16 ++++++++++++-- .../device/TOOLCHAIN_GCC_ARM/M487.ld | 13 ++++++++++++ .../TARGET_M480/device/TOOLCHAIN_IAR/M487.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32f411re.sct | 14 ++++++++++++- .../device/TOOLCHAIN_ARM_STD/stm32f411re.sct | 14 ++++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32f411xe.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32f429xx.sct | 16 ++++++++++++-- .../device/TOOLCHAIN_ARM_STD/stm32f429xx.sct | 11 +++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld | 15 ++++++++++++- .../TOOLCHAIN_IAR/stm32f429xx_flash.icf | 9 +++++++- .../device/TOOLCHAIN_ARM_STD/stm32f437xx.sct | 14 ++++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F437xx.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32f437xx.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32f439xx.sct | 14 ++++++++++++- .../device/TOOLCHAIN_ARM_STD/stm32f439xx.sct | 14 ++++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld | 14 +++++++++++++ .../TOOLCHAIN_IAR/stm32f439xx_flash.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32f746xg.sct | 14 ++++++++++++- .../device/TOOLCHAIN_ARM_STD/stm32f746xg.sct | 14 ++++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F746xG.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32f746xg.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32f767xi.sct | 14 ++++++++++++- .../device/TOOLCHAIN_ARM_STD/stm32f767xi.sct | 14 ++++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32F767xI.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32f767xi.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32l475xx.sct | 11 +++++++++- .../device/TOOLCHAIN_ARM_STD/stm32l475xx.sct | 13 ++++++++++-- .../device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32l475xx.icf | 9 +++++++- .../TOOLCHAIN_ARM_MICRO/stm32l476xx.sct | 13 +++++++++++- .../device/TOOLCHAIN_ARM_STD/stm32l476xx.sct | 13 +++++++++++- .../device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld | 14 +++++++++++++ .../device/TOOLCHAIN_IAR/stm32l476xx.icf | 9 +++++++- 44 files changed, 496 insertions(+), 43 deletions(-) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct index 5129e25305..0651acc58f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct @@ -72,8 +72,11 @@ #define m_interrupts_ram_start 0x1FFF0000 #define m_interrupts_ram_size __ram_vector_table_size__ -#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) -#define m_data_size (0x00010000 - m_interrupts_ram_size) +#define m_crash_report_ram_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_crash_report_ram_size (0x100) + +#define m_data_start (m_crash_report_ram_start + m_crash_report_ram_size) +#define m_data_size (0x00010000 - (m_interrupts_ram_size+m_crash_report_ram_size)) #define m_data_2_start 0x20000000 #define m_data_2_size 0x00030000 @@ -110,6 +113,8 @@ LR_IROM1 m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; lo VECTOR_RAM m_interrupts_start EMPTY 0 { } #endif + RW_m_crash_data m_crash_report_ram_start EMPTY m_crash_report_ram_size { ; RW data + } RW_m_data m_data_start m_data_size { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld index 31e359ba35..bb7e13f59a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld @@ -66,6 +66,7 @@ __heap_size__ = 0x6000; HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0; +M_CRASH_DATA_RAM_SIZE = 0x100; /* Specify the memory areas */ MEMORY @@ -195,6 +196,18 @@ SECTIONS . = ALIGN(8); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > m_data + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > m_data __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf index 54de75b7bd..d8a1ebd281 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf @@ -72,7 +72,10 @@ define symbol m_text_end = MBED_APP_START + MBED_APP_SIZE - 1; define symbol m_interrupts_ram_start = 0x1FFF0000; define symbol m_interrupts_ram_end = 0x1FFF0000 + __ram_vector_table_offset__; -define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_crash_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_crash_data_size = 0x100; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__ + m_crash_data_size; define symbol m_data_end = 0x1FFFFFFF; define symbol m_data_2_start = 0x20000000; @@ -94,6 +97,8 @@ if (isdefinedsymbol(__heap_size__)) { define exported symbol __VECTOR_TABLE = m_interrupts_start; define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start; define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; +define exported symbol __CRASH_DATA_RAM_START__ = m_crash_data_start; +define exported symbol __CRASH_DATA_RAM_END__ = m_crash_data_start + m_crash_data_size; define memory mem with size = 4G; define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct index 9c6020c8a1..72a6efafe2 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct @@ -80,8 +80,11 @@ #define m_interrupts_ram_start 0x1FFF0000 #define m_interrupts_ram_size __ram_vector_table_size__ -#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) -#define m_data_size (0x00010000 - m_interrupts_ram_size) +#define m_crash_report_ram_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_crash_report_ram_size (0x100) + +#define m_data_start (m_crash_report_ram_start + m_crash_report_ram_size) +#define m_data_size (0x00010000 - (m_interrupts_ram_size+m_crash_report_ram_size)) #define m_data_2_start 0x20000000 #define m_data_2_size 0x00030000 @@ -118,6 +121,8 @@ LR_IROM1 m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; lo VECTOR_RAM m_interrupts_start EMPTY 0 { } #endif + RW_m_crash_data m_crash_report_ram_start EMPTY m_crash_report_ram_size { ; RW data + } RW_m_data m_data_start m_data_size { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld index 3848a8de21..19e7e93db9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld @@ -74,6 +74,7 @@ __heap_size__ = 0x6000; HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0; +M_CRASH_DATA_RAM_SIZE = 0x100; /* Specify the memory areas */ MEMORY @@ -200,6 +201,18 @@ SECTIONS . = ALIGN(8); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > m_data + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > m_data __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf index a56e50070f..b36a17f78c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf @@ -79,7 +79,10 @@ define symbol m_text_end = MBED_APP_START + MBED_APP_SIZE - 1; define symbol m_interrupts_ram_start = 0x1FFF0000; define symbol m_interrupts_ram_end = 0x1FFF0000 + __ram_vector_table_offset__; -define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_crash_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_crash_data_size = 0x100; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__ + m_crash_data_size; define symbol m_data_end = 0x1FFFFFFF; define symbol m_data_2_start = 0x20000000; @@ -101,6 +104,8 @@ if (isdefinedsymbol(__heap_size__)) { define exported symbol __VECTOR_TABLE = m_interrupts_start; define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start; define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; +define exported symbol __CRASH_DATA_RAM_START__ = m_crash_data_start; +define exported symbol __CRASH_DATA_RAM_END__ = m_crash_data_start + m_crash_data_size; define memory mem with size = 4G; define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_ARM_STD/nRF52840.sct b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_ARM_STD/nRF52840.sct index da9be7a8d5..57626d9714 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_ARM_STD/nRF52840.sct +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_ARM_STD/nRF52840.sct @@ -22,8 +22,12 @@ #define MBED_RAM0_START MBED_RAM_START #define MBED_RAM0_SIZE 0x100 -#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE) -#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE) + +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM0_START + MBED_RAM0_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 + +#define MBED_RAM1_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM1_SIZE (MBED_RAM_SIZE - (MBED_RAM0_SIZE + MBED_CRASH_REPORT_RAM_SIZE)) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ER_IROM1 MBED_APP_START MBED_APP_SIZE { @@ -34,6 +38,8 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { RW_IRAM0 MBED_RAM0_START UNINIT MBED_RAM0_SIZE { ;no init section *(*nvictable) } + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } RW_IRAM1 MBED_RAM1_START MBED_RAM1_SIZE { .ANY (+RW +ZI) } diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_GCC_ARM/NRF52840.ld b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_GCC_ARM/NRF52840.ld index 66b96eb3fb..7cb1621ac6 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_GCC_ARM/NRF52840.ld +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_GCC_ARM/NRF52840.ld @@ -38,13 +38,18 @@ #define MBED_RAM0_START MBED_RAM_START #define MBED_RAM0_SIZE 0x100 -#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE) -#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE) + +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM0_START + MBED_RAM0_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 + +#define MBED_RAM1_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM1_SIZE (MBED_RAM_SIZE - (MBED_RAM0_SIZE + MBED_CRASH_REPORT_RAM_SIZE)) MEMORY { FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE RAM_NVIC (rwx) : ORIGIN = MBED_RAM0_START, LENGTH = MBED_RAM0_SIZE + RAM_CRASH_DATA (rwx) : ORIGIN = MBED_CRASH_REPORT_RAM_START, LENGTH = MBED_CRASH_REPORT_RAM_SIZE RAM (rwx) : ORIGIN = MBED_RAM1_START, LENGTH = MBED_RAM1_SIZE } @@ -206,6 +211,18 @@ SECTIONS KEEP(*(.nvictable)) PROVIDE(__stop_nvictable = .); } > RAM_NVIC + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += MBED_CRASH_REPORT_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM_CRASH_DATA .noinit (NOLOAD) : { diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_IAR/nRF52840.icf b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_IAR/nRF52840.icf index c681e88e5a..9396c998b0 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_IAR/nRF52840.icf +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/device/TOOLCHAIN_IAR/nRF52840.icf @@ -24,8 +24,12 @@ if (!isdefinedsymbol(MBED_RAM_START)) { define symbol MBED_RAM0_START = MBED_RAM_START; define symbol MBED_RAM0_SIZE = 0x100; -define symbol MBED_RAM1_START = (MBED_RAM_START + MBED_RAM0_SIZE); -define symbol MBED_RAM1_SIZE = (MBED_RAM_SIZE - MBED_RAM0_SIZE); +define symbol MBED_CRASH_REPORT_RAM_START = (MBED_RAM_START + MBED_RAM0_SIZE); +define symbol MBED_CRASH_REPORT_RAM_SIZE = 0x100; +define symbol MBED_RAM1_START = (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE); +define symbol MBED_RAM1_SIZE = (MBED_RAM_SIZE - (MBED_RAM0_SIZE + MBED_CRASH_REPORT_RAM_SIZE)); +define exported symbol __CRASH_DATA_RAM_START__ = MBED_CRASH_REPORT_RAM_START; +define exported symbol __CRASH_DATA_RAM_END__ = MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE; /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = MBED_APP_START; diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/M487.sct b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/M487.sct index 3244074dde..d81caeb2a8 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/M487.sct +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/M487.sct @@ -11,6 +11,15 @@ #define SPIM_CCM_START 0x20020000 #define SPIM_CCM_END 0x20028000 +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x20000 +#define MBED_STACK_RAM_START (MBED_RAM_START) +#define MBED_STACK_RAM_SIZE 0x800 +#define MBED_VECTTABLE_RAM_START (MBED_STACK_RAM_START + MBED_STACK_RAM_SIZE) +#define MBED_VECTTABLE_RAM_SIZE (4*(16 + 96)) +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 + LR_IROM1 MBED_APP_START { ER_IROM1 MBED_APP_START { ; load address = execution address *(RESET, +First) @@ -19,10 +28,13 @@ LR_IROM1 MBED_APP_START { } - ARM_LIB_STACK 0x20000000 EMPTY 0x800 { + ARM_LIB_STACK MBED_STACK_RAM_START EMPTY MBED_STACK_RAM_SIZE { } - ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 96)) { ; Reserve for vectors + ER_IRAMVEC MBED_VECTTABLE_RAM_START EMPTY MBED_VECTTABLE_RAM_SIZE { ; Reserve for vectors + } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; Reserve for crash data storage } RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/M487.sct b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/M487.sct index 3244074dde..d81caeb2a8 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/M487.sct +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/M487.sct @@ -11,6 +11,15 @@ #define SPIM_CCM_START 0x20020000 #define SPIM_CCM_END 0x20028000 +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x20000 +#define MBED_STACK_RAM_START (MBED_RAM_START) +#define MBED_STACK_RAM_SIZE 0x800 +#define MBED_VECTTABLE_RAM_START (MBED_STACK_RAM_START + MBED_STACK_RAM_SIZE) +#define MBED_VECTTABLE_RAM_SIZE (4*(16 + 96)) +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 + LR_IROM1 MBED_APP_START { ER_IROM1 MBED_APP_START { ; load address = execution address *(RESET, +First) @@ -19,10 +28,13 @@ LR_IROM1 MBED_APP_START { } - ARM_LIB_STACK 0x20000000 EMPTY 0x800 { + ARM_LIB_STACK MBED_STACK_RAM_START EMPTY MBED_STACK_RAM_SIZE { } - ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 96)) { ; Reserve for vectors + ER_IRAMVEC MBED_VECTTABLE_RAM_START EMPTY MBED_VECTTABLE_RAM_SIZE { ; Reserve for vectors + } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; Reserve for crash data storage } RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/M487.ld b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/M487.ld index 22e8abf217..c1336b909c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/M487.ld +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/M487.ld @@ -10,6 +10,7 @@ #define MBED_APP_SIZE 0x00080000 #endif +M_CRASH_DATA_RAM_SIZE = 0x100; StackSize = 0x800; SPIM_CCM_START = 0x20020000; SPIM_CCM_END = 0x20028000; @@ -130,6 +131,18 @@ SECTIONS PROVIDE(__end_vector_table__ = .); } > RAM_INTERN + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM_INTERN + .data : { PROVIDE( __etext = LOADADDR(.data) ); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf index 418eee680b..42c5201399 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf @@ -12,6 +12,8 @@ define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000; define symbol __ICFEDIT_region_IRAM_end__ = 0x20028000 - 1; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_crash_data__ = 0x100; +define symbol __ICFEDIT_size_intvec__ = (4 * (16 + 96)) define symbol __ICFEDIT_size_heap__ = 0x10000; /**** End of ICF editor section. ###ICF###*/ @@ -23,8 +25,12 @@ define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFED define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; /* NOTE: Vector table base requires to be aligned to the power of vector table size. Give a safe value here. */ -define block IRAMVEC with alignment = 1024, size = 4 * (16 + 96) { }; +define block IRAMVEC with alignment = 1024, size = __ICFEDIT_size_intvec__ { }; +define block CRASH_DATA_RAM with alignment = 8, size = __ICFEDIT_size_crash_data__ { }; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __ICFEDIT_region_IRAM_start__ + __ICFEDIT_size_cstack__ + __ICFEDIT_size_intvec__; +define exported symbol __CRASH_DATA_RAM_END__ = __ICFEDIT_region_IRAM_start__ + __ICFEDIT_size_cstack__ + __ICFEDIT_size_intvec__ + __ICFEDIT_size_crash_data__; initialize by copy { readwrite }; do not initialize { section .noinit }; @@ -34,5 +40,6 @@ place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place at start of IRAM_region { block CSTACK }; place in IRAM_region { block IRAMVEC }; +place in IRAM_region { block CRASH_DATA_RAM }; place in IRAM_region { readwrite }; place in IRAM_region { block HEAP }; \ No newline at end of file diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_MICRO/stm32f411re.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_MICRO/stm32f411re.sct index c018724bf7..404e000a00 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_MICRO/stm32f411re.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_MICRO/stm32f411re.sct @@ -27,6 +27,15 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x20000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x198 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F411RE: 512 KB FLASH (0x80000) + 128 KB SRAM (0x20000) LR_IROM1 0x08000000 0x80000 { ; load region size_region @@ -35,9 +44,12 @@ LR_IROM1 0x08000000 0x80000 { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 102 vectors = 408 bytes (0x198) to be reserved in RAM - RW_IRAM1 (0x20000000+0x198) (0x20000-0x198) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct index b8e8b03e12..a879adbb9f 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_ARM_STD/stm32f411re.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x80000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x20000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x198 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F411RE: 512 KB FLASH (0x80000) + 128 KB SRAM (0x20000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 102 vectors = 408 bytes (0x198) to be reserved in RAM - RW_IRAM1 (0x20000000+0x198) (0x20000-0x198) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld index 141bb1f838..a206d6e250 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_GCC_ARM/STM32F411XE.ld @@ -6,6 +6,8 @@ #define MBED_APP_SIZE 512K #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Linker script to configure memory regions. */ MEMORY { @@ -84,6 +86,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf index 904b833a67..62f1fa3f3c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/TOOLCHAIN_IAR/stm32f411xe.icf @@ -9,14 +9,21 @@ define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM = 128kb = 0x20000] Vector table dynamic copy: 102 vectors = 408 bytes (0x198) to be reserved in RAM */ define symbol __NVIC_start__ = 0x20000000; define symbol __NVIC_end__ = 0x20000197; /* Aligned on 8 bytes */ -define symbol __region_RAM_start__ = 0x20000198; +define symbol __region_CRASH_DATA_RAM_start__ = 0x20000198; +define symbol __region_CRASH_DATA_RAM_end__ = 0x20000297; +define symbol __region_RAM_start__ = 0x20000298; define symbol __region_RAM_end__ = 0x2001FFFF; /* Memory regions */ define memory mem with size = 4G; define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + /* Stack and Heap */ /*Heap 84kB and stack 1kB */ define symbol __size_cstack__ = 0x400; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct index e190049940..b1faff5db3 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x20000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1B0 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 2 MB FLASH (0x200000) + 256 KB SRAM (0x40000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } - + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + ; Total: 107 vectors = 428 bytes (0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1B0) (0x20000-0x1B0) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct index 2f2ee23fd4..eb4d41143c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x30000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1B0 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 2 MB FLASH (0x200000) + 192 KB SRAM (0x30000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -46,7 +55,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region } ; Total: 107 vectors = 428 bytes (0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1B0) (0x30000-0x1B0) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld index b23b056ffe..e22e74708d 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld @@ -14,6 +14,8 @@ HEAP_SIZE = 0x6000; #define MBED_APP_SIZE 2048k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Specify the memory areas */ MEMORY { @@ -114,7 +116,18 @@ SECTIONS . = ALIGN(8); __interrupts_ram_end__ = .; /* Define a global symbol at data end */ } > RAM - + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf index 8dcb1a8fea..3dc9c9aca3 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf @@ -10,7 +10,9 @@ define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START; define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000; define symbol __ICFEDIT_region_NVIC_end__ = 0x200001AF; -define symbol __ICFEDIT_region_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200002AF; +define symbol __ICFEDIT_region_RAM_start__ = 0x200002B0; define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; @@ -24,8 +26,13 @@ define symbol __ICFEDIT_size_heap__ = 0x10000; define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_ARM_STD/stm32f437xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_ARM_STD/stm32f437xx.sct index 693f2eb98c..a8a08b182b 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_ARM_STD/stm32f437xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_ARM_STD/stm32f437xx.sct @@ -38,6 +38,15 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x30000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1B0 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address @@ -47,7 +56,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region } ; Total: 107 vectors = 428 bytes (0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1B0) (0x30000-0x1B0) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } @@ -55,6 +64,9 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region .ANY (CCMRAM) } + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + RW_IRAM3 0x40024000 4096 { ; 4 kbytes of Backup SRAM .ANY (BKPSRAM) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_GCC_ARM/STM32F437xx.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_GCC_ARM/STM32F437xx.ld index 086838b557..4c478da276 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_GCC_ARM/STM32F437xx.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_GCC_ARM/STM32F437xx.ld @@ -6,6 +6,8 @@ #define MBED_APP_SIZE 1024k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Linker script to configure memory regions. */ /* 0x1AC resevered for vectors; 8-byte aligned = 0x1B0 (0x1AC + 0x4)*/ MEMORY @@ -87,6 +89,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_IAR/stm32f437xx.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_IAR/stm32f437xx.icf index 97fd4ac509..34ffb23b9a 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_IAR/stm32f437xx.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/TOOLCHAIN_IAR/stm32f437xx.icf @@ -10,7 +10,9 @@ define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START; define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000; define symbol __ICFEDIT_region_NVIC_end__ = 0x200001AF; -define symbol __ICFEDIT_region_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200002AF; +define symbol __ICFEDIT_region_RAM_start__ = 0x200002B0; define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; @@ -25,10 +27,15 @@ define symbol __ICFEDIT_size_heap__ = 0x18000; define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; define region BKPSRAM_region = mem:[from __ICFEDIT_region_BKPSRAM_start__ to __ICFEDIT_region_BKPSRAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct index 6c8fec1c51..b608da9788 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x30000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1B0 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F439xI: 2048 KB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,10 +53,13 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 107 vectors = 428 bytes (0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be used ; should match ER_IROM1::RESET/4 and cmsis_nvic.h::NVIC_NUM_VECTORS - RW_IRAM1 (0x20000000 + 0x1B0) (0x30000 - 0x1B0) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } RW_IRAM2 (0x10000000) 0x10000 { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct index ed103dd089..0ca3edf060 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x30000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1B0 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 2 MB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 107 vectors = 428 bytes(0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1B0) (0x30000-0x1B0) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld index 4aa99d3940..fb42b7b72e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld @@ -6,6 +6,8 @@ #define MBED_APP_SIZE 2048k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Linker script to configure memory regions. */ /* 0x1AC resevered for vectors; 8-byte aligned = 0x1B0 (0x1AC + 0x4)*/ MEMORY @@ -86,6 +88,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf index cf2b2b0135..abb0cf609e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf @@ -10,7 +10,9 @@ define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START; define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000; define symbol __ICFEDIT_region_NVIC_end__ = 0x200001AF; -define symbol __ICFEDIT_region_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_start__ = 0x200001B0; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200002AF; +define symbol __ICFEDIT_region_RAM_start__ = 0x200002B0; define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; @@ -23,9 +25,14 @@ define symbol __ICFEDIT_size_heap__ = 0x15C00; define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_MICRO/stm32f746xg.sct b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_MICRO/stm32f746xg.sct index 897c962691..2e88924207 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_MICRO/stm32f746xg.sct +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_MICRO/stm32f746xg.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x50000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1C8 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F746NG: 1024 KB FLASH (0x100000) + 320 KB SRAM (0x50000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1C8) (0x50000-0x1C8) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_STD/stm32f746xg.sct b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_STD/stm32f746xg.sct index 897c962691..2e88924207 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_STD/stm32f746xg.sct +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_ARM_STD/stm32f746xg.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x50000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1C8 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F746NG: 1024 KB FLASH (0x100000) + 320 KB SRAM (0x50000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1C8) (0x50000-0x1C8) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_GCC_ARM/STM32F746xG.ld b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_GCC_ARM/STM32F746xG.ld index 7c7caebb82..d948e864de 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_GCC_ARM/STM32F746xG.ld +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_GCC_ARM/STM32F746xG.ld @@ -8,6 +8,8 @@ #define MBED_APP_SIZE 1024K #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + MEMORY { FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE @@ -85,6 +87,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_IAR/stm32f746xg.icf b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_IAR/stm32f746xg.icf index 4d8dfcaa4a..7be08cdc48 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_IAR/stm32f746xg.icf +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/TOOLCHAIN_IAR/stm32f746xg.icf @@ -9,7 +9,9 @@ define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM = 320kb = 0x50000] Vector table dynamic copy: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM */ define symbol __NVIC_start__ = 0x20000000; define symbol __NVIC_end__ = 0x200001C7; /* Aligned on 8 bytes */ -define symbol __region_RAM_start__ = 0x200001C8; +define symbol __region_CRASH_DATA_RAM_start__ = 0x200001C8; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200002C7; +define symbol __region_RAM_start__ = 0x200002C8; define symbol __region_RAM_end__ = 0x2004FFFF; define symbol __region_ITCMRAM_start__ = 0x00000000; @@ -19,8 +21,13 @@ define symbol __region_ITCMRAM_end__ = 0x00003FFF; define memory mem with size = 4G; define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region ITCMRAM_region = mem:[from __region_ITCMRAM_start__ to __region_ITCMRAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + /* Stack and Heap */ /*Heap 1/4 of ram and stack 1/12 */ define symbol __size_cstack__ = 0x4000; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_MICRO/stm32f767xi.sct b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_MICRO/stm32f767xi.sct index 0534eeee59..c7cfd9e04a 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_MICRO/stm32f767xi.sct +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_MICRO/stm32f767xi.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x80000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1F8 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F767ZI: 2048 KB FLASH (0x200000) + 512 KB SRAM (0x80000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 126 vectors = 504 bytes (0x1F8) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1F8) (0x80000-0x1F8) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_STD/stm32f767xi.sct b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_STD/stm32f767xi.sct index 0534eeee59..c7cfd9e04a 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_STD/stm32f767xi.sct +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_ARM_STD/stm32f767xi.sct @@ -36,6 +36,15 @@ #define MBED_APP_SIZE 0x200000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x80000 +#define MBED_VECTTABLE_RAM_START (MBED_RAM_START) +#define MBED_VECTTABLE_RAM_SIZE 0x1F8 +#define MBED_CRASH_REPORT_RAM_START (MBED_VECTTABLE_RAM_START + MBED_VECTTABLE_RAM_SIZE) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_VECTTABLE_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; STM32F767ZI: 2048 KB FLASH (0x200000) + 512 KB SRAM (0x80000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,9 +53,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 126 vectors = 504 bytes (0x1F8) to be reserved in RAM - RW_IRAM1 (0x20000000+0x1F8) (0x80000-0x1F8) { ; RW data + RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data .ANY (+RW +ZI) } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_GCC_ARM/STM32F767xI.ld b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_GCC_ARM/STM32F767xI.ld index fcde9d1b71..4d9ef183d7 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_GCC_ARM/STM32F767xI.ld +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_GCC_ARM/STM32F767xI.ld @@ -8,6 +8,8 @@ #define MBED_APP_SIZE 2048K #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + MEMORY { FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE @@ -85,6 +87,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > RAM .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_IAR/stm32f767xi.icf b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_IAR/stm32f767xi.icf index 40316b8e54..d405b4789d 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_IAR/stm32f767xi.icf +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/TOOLCHAIN_IAR/stm32f767xi.icf @@ -9,7 +9,9 @@ define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM = 512kb = 0x80000] Vector table dynamic copy: 126 vectors = 504 bytes (0x1F8) to be reserved in RAM */ define symbol __NVIC_start__ = 0x20000000; define symbol __NVIC_end__ = 0x200001F7; /* Aligned on 8 bytes */ -define symbol __region_RAM_start__ = 0x200001F8; +define symbol __region_CRASH_DATA_RAM_start__ = 0x200001F8; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200002F7; +define symbol __region_RAM_start__ = 0x200002F8; define symbol __region_RAM_end__ = 0x2007FFFF; define symbol __region_ITCMRAM_start__ = 0x00000000; @@ -18,9 +20,14 @@ define symbol __region_ITCMRAM_end__ = 0x00003FFF; /* Memory regions */ define memory mem with size = 4G; define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM_end__]; define region ITCMRAM_region = mem:[from __region_ITCMRAM_start__ to __region_ITCMRAM_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + /* Stack and Heap */ define symbol __size_cstack__ = 0x8000; define symbol __size_heap__ = 0x10000; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_MICRO/stm32l475xx.sct b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_MICRO/stm32l475xx.sct index a657759b32..e9e36dc0f8 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_MICRO/stm32l475xx.sct +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_MICRO/stm32l475xx.sct @@ -36,6 +36,13 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x00018000 +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM_START) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 1MB FLASH (0x100000) + 128KB SRAM (0x20000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -45,7 +52,9 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region .ANY (+RO) } - RW_IRAM1 0x20000000 0x00018000 { ; RW data 96k L4-SRAM1 + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + RW_IRAM1 MBED_RAM0_START MBED_RAM0_SIZE { ; RW data 96k L4-SRAM1 .ANY (+RW +ZI) } ; Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_STD/stm32l475xx.sct b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_STD/stm32l475xx.sct index a657759b32..c9cc382a28 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_STD/stm32l475xx.sct +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_ARM_STD/stm32l475xx.sct @@ -36,6 +36,14 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x00018000 +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM_START) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + + ; 1MB FLASH (0x100000) + 128KB SRAM (0x20000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -44,8 +52,9 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } - - RW_IRAM1 0x20000000 0x00018000 { ; RW data 96k L4-SRAM1 + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + RW_IRAM1 MBED_RAM0_START MBED_RAM0_SIZE { ; RW data 96k L4-SRAM1 .ANY (+RW +ZI) } ; Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld index 09a551af27..f4f4573fad 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld @@ -6,6 +6,8 @@ #define MBED_APP_SIZE 1024k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Linker script to configure memory regions. */ MEMORY { @@ -85,6 +87,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > SRAM1 .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_IAR/stm32l475xx.icf b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_IAR/stm32l475xx.icf index a4cff93836..91af035074 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_IAR/stm32l475xx.icf +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_IAR/stm32l475xx.icf @@ -12,15 +12,22 @@ define symbol __NVIC_start__ = 0x10000000; define symbol __NVIC_end__ = 0x10000187; define symbol __region_SRAM2_start__ = 0x10000188; define symbol __region_SRAM2_end__ = 0x10007FFF; -define symbol __region_SRAM1_start__ = 0x20000000; +define symbol __region_CRASH_DATA_RAM_start__ = 0x20000000; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200000FF; +define symbol __region_SRAM1_start__ = 0x20000100; define symbol __region_SRAM1_end__ = 0x20017FFF; /* Memory regions */ define memory mem with size = 4G; define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; define region SRAM2_region = mem:[from __region_SRAM2_start__ to __region_SRAM2_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region SRAM1_region = mem:[from __region_SRAM1_start__ to __region_SRAM1_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + /* Stack complete SRAM2 and Heap 2/3 of SRAM1 */ define symbol __size_cstack__ = 0x7e00; define symbol __size_heap__ = 0x10000; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_MICRO/stm32l476xx.sct b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_MICRO/stm32l476xx.sct index a657759b32..43ed3d0b1a 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_MICRO/stm32l476xx.sct +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_MICRO/stm32l476xx.sct @@ -36,6 +36,13 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x00018000 +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM_START) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 1MB FLASH (0x100000) + 128KB SRAM (0x20000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -45,9 +52,13 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region .ANY (+RO) } - RW_IRAM1 0x20000000 0x00018000 { ; RW data 96k L4-SRAM1 + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + + RW_IRAM1 MBED_RAM0_START MBED_RAM0_SIZE { ; RW data 96k L4-SRAM1 .ANY (+RW +ZI) } + ; Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM RW_IRAM2 (0x10000000+0x188) (0x08000-0x188) { ; RW data 32k L4-ECC-SRAM2 retained in standby .ANY (+RW +ZI) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_STD/stm32l476xx.sct b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_STD/stm32l476xx.sct index a657759b32..43ed3d0b1a 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_STD/stm32l476xx.sct +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_ARM_STD/stm32l476xx.sct @@ -36,6 +36,13 @@ #define MBED_APP_SIZE 0x100000 #endif +#define MBED_RAM_START 0x20000000 +#define MBED_RAM_SIZE 0x00018000 +#define MBED_CRASH_REPORT_RAM_START (MBED_RAM_START) +#define MBED_CRASH_REPORT_RAM_SIZE 0x100 +#define MBED_RAM0_START (MBED_CRASH_REPORT_RAM_START + MBED_CRASH_REPORT_RAM_SIZE) +#define MBED_RAM0_SIZE (MBED_RAM_SIZE - MBED_CRASH_REPORT_RAM_SIZE) + ; 1MB FLASH (0x100000) + 128KB SRAM (0x20000) LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region @@ -45,9 +52,13 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region .ANY (+RO) } - RW_IRAM1 0x20000000 0x00018000 { ; RW data 96k L4-SRAM1 + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } + + RW_IRAM1 MBED_RAM0_START MBED_RAM0_SIZE { ; RW data 96k L4-SRAM1 .ANY (+RW +ZI) } + ; Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM RW_IRAM2 (0x10000000+0x188) (0x08000-0x188) { ; RW data 32k L4-ECC-SRAM2 retained in standby .ANY (+RW +ZI) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld index 09a551af27..f3bbe03272 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld @@ -6,6 +6,8 @@ #define MBED_APP_SIZE 1024k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + /* Linker script to configure memory regions. */ MEMORY { @@ -85,6 +87,18 @@ SECTIONS __etext = .; _sidata = .; + + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */ + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) /* This is a user defined section */ + . += M_CRASH_DATA_RAM_SIZE; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ + } > SRAM1 .data : AT (__etext) { diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_IAR/stm32l476xx.icf b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_IAR/stm32l476xx.icf index a4cff93836..91af035074 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_IAR/stm32l476xx.icf +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_IAR/stm32l476xx.icf @@ -12,15 +12,22 @@ define symbol __NVIC_start__ = 0x10000000; define symbol __NVIC_end__ = 0x10000187; define symbol __region_SRAM2_start__ = 0x10000188; define symbol __region_SRAM2_end__ = 0x10007FFF; -define symbol __region_SRAM1_start__ = 0x20000000; +define symbol __region_CRASH_DATA_RAM_start__ = 0x20000000; +define symbol __region_CRASH_DATA_RAM_end__ = 0x200000FF; +define symbol __region_SRAM1_start__ = 0x20000100; define symbol __region_SRAM1_end__ = 0x20017FFF; /* Memory regions */ define memory mem with size = 4G; define region ROM_region = mem:[from __region_ROM_start__ to __region_ROM_end__]; define region SRAM2_region = mem:[from __region_SRAM2_start__ to __region_SRAM2_end__]; +define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__]; define region SRAM1_region = mem:[from __region_SRAM1_start__ to __region_SRAM1_end__]; +/* Define Crash Data Symbols */ +define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__; +define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__; + /* Stack complete SRAM2 and Heap 2/3 of SRAM1 */ define symbol __size_cstack__ = 0x7e00; define symbol __size_heap__ = 0x10000; From 9ac31dbaef34584b39f8ace67369224f1f5f84f9 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Mon, 12 Nov 2018 22:16:15 -0600 Subject: [PATCH 3/9] Enable crash capture feature for platforms with linkerscript changes --- platform/mbed_lib.json | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index 1531c48818..9f654321a9 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -136,6 +136,71 @@ }, "UNO_91H": { "stdio-baud-rate": 115200 + }, + "DISCO_L475VG_IOT01A": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "K64F": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "K66F": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_F429ZI": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_F746ZG": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_F767ZI": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_F439ZI": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "UBLOX_EVK_ODIN_W2": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "UBLOX_C030_U201": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUMAKER_PFM_M487": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NRF52840_DK": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_L476RG": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true + }, + "NUCLEO_F411RE": { + "crash-capture-enabled": true, + "reboot-crash-report-enabled": true, + "fatal-error-auto-reboot-enabled": true } } } From 4ec30e3e8fd5684a5f370ff172ed6e00490d4c1d Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Mon, 12 Nov 2018 22:39:36 -0600 Subject: [PATCH 4/9] Added greentea test --- TESTS/host_tests/crash_reporting.py | 71 ++++++++++++++++++++ TESTS/mbed_platform/crash_reporting/main.cpp | 65 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 TESTS/host_tests/crash_reporting.py create mode 100644 TESTS/mbed_platform/crash_reporting/main.cpp diff --git a/TESTS/host_tests/crash_reporting.py b/TESTS/host_tests/crash_reporting.py new file mode 100644 index 0000000000..b2153b1cff --- /dev/null +++ b/TESTS/host_tests/crash_reporting.py @@ -0,0 +1,71 @@ +""" +Copyright (c) 2018 ARM Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import time +from mbed_host_tests import BaseHostTest +from mbed_host_tests.host_tests_runner.host_test_default import DefaultTestSelector + +DEFAULT_CYCLE_PERIOD = 10.0 + +MSG_VALUE_DUMMY = '0' + +MSG_KEY_DEVICE_READY = 'crash_reporting_ready' +MSG_KEY_DEVICE_ERROR = 'crash_reporting_inject_error' +MSG_KEY_SYNC = '__sync' + +class CrashReportingTest(BaseHostTest): + """Test for the crash reporting feature. + """ + + def __init__(self): + super(CrashReportingTest, self).__init__() + self.reset = False + self.test_steps_sequence = self.test_steps() + # Advance the coroutine to it's first yield statement. + self.test_steps_sequence.send(None) + + def setup(self): + self.register_callback(MSG_KEY_DEVICE_READY, self.cb_device_ready) + + def cb_device_ready(self, key, value, timestamp): + """Acknowledge device rebooted correctly and feed the test execution + """ + self.reset = True + + try: + if self.test_steps_sequence.send(value): + self.notify_complete(True) + except (StopIteration, RuntimeError) as exc: + self.notify_complete(False) + + def test_steps(self): + """Reset the device and check the status + """ + system_reset = yield + self.reset = False + + wait_after_reset = self.get_config_item('forced_reset_timeout') + wait_after_reset = wait_after_reset if wait_after_reset is not None else DEFAULT_CYCLE_PERIOD + + #self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) + self.send_kv(MSG_KEY_DEVICE_ERROR, MSG_VALUE_DUMMY) + time.sleep(5.0) + + system_reset = yield + if self.reset == False: + raise RuntimeError('Platform did not auto-reboot as expected.') + + # The sequence is correct -- test passed. + yield True diff --git a/TESTS/mbed_platform/crash_reporting/main.cpp b/TESTS/mbed_platform/crash_reporting/main.cpp new file mode 100644 index 0000000000..8200042dd4 --- /dev/null +++ b/TESTS/mbed_platform/crash_reporting/main.cpp @@ -0,0 +1,65 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "mbed_error.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" + +#if !MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED +#error [NOT_SUPPORTED] crash_reporting test not supported +#endif + +#define MSG_VALUE_DUMMY "0" +#define MSG_VALUE_LEN 32 +#define MSG_KEY_LEN 64 + +#define MSG_KEY_DEVICE_READY "crash_reporting_ready" +#define MSG_KEY_DEVICE_ERROR "crash_reporting_inject_error" + +void mbed_error_reboot_callback(mbed_error_ctx *error_context) { + TEST_ASSERT_EQUAL_UINT(MBED_ERROR_OUT_OF_MEMORY, error_context->error_status); + TEST_ASSERT_EQUAL_UINT(1, error_context->error_reboot_count); + mbed_reset_reboot_error_info(); + + //Send the ready msg to host to indicate test pass + greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); +} + +void test_crash_reporting() +{ + // Report readiness + greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); + + static char _key[MSG_KEY_LEN + 1] = { }; + static char _value[MSG_VALUE_LEN + 1] = { }; + + greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN); + if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) { + MBED_ERROR1(MBED_ERROR_OUT_OF_MEMORY, "Executing crash reporting test.", 0xDEADBAD); + TEST_ASSERT_MESSAGE(0, "crash_reporting() error call failed."); + } + + TEST_ASSERT_MESSAGE(0, "Unexpected message received."); +} + +int main(void) +{ + GREENTEA_SETUP(30, "crash_reporting"); + test_crash_reporting(); + GREENTEA_TESTSUITE_RESULT(0); + + return 0; +} From 254062fc5a0d9d64a4cac4c939cdb60215c7c0dd Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Tue, 13 Nov 2018 17:21:30 -0600 Subject: [PATCH 5/9] Add thread safety across reboot error info operations --- platform/mbed_error.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/platform/mbed_error.c b/platform/mbed_error.c index de4064a9a9..9723146e01 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -168,7 +168,7 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign //Increment error count error_count++; - //Capture the fist system error and store it + //Capture the first system error and store it if (error_count == 1) { //first error memcpy(&first_error_ctx, ¤t_error_ctx, sizeof(mbed_error_ctx)); } @@ -281,7 +281,10 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error //Update the struct with crc last_error_ctx.crc_error_ctx = compute_crc32( (unsigned char *)&last_error_ctx, ((uint32_t)&(last_error_ctx.crc_error_ctx) - (uint32_t)&last_error_ctx) ); + //Protect report_error_ctx while we update it + core_util_critical_section_enter(); memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx)); + core_util_critical_section_exit(); //We need not call delete_mbed_crc(crc_obj) here as we are going to reset the system anyway, and calling delete while handling a fatal error may cause nested exception #if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED system_reset();//do a system reset to get the system rebooted @@ -310,7 +313,10 @@ mbed_error_status_t mbed_set_error_hook(mbed_error_hook_t error_hook_in) mbed_error_status_t mbed_reset_reboot_error_info() { #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED - memset(report_error_ctx, 0, sizeof(mbed_error_ctx) ); + //Protect for thread safety + core_util_critical_section_enter(); + memset(report_error_ctx, 0, sizeof(mbed_error_ctx) ); + core_util_critical_section_exit(); #endif return MBED_SUCCESS; } @@ -321,10 +327,12 @@ mbed_error_status_t mbed_reset_reboot_count() #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED if(is_reboot_error_valid) { uint32_t crc_val = 0; + core_util_critical_section_enter(); report_error_ctx->error_reboot_count = 0;//Set reboot count to 0 //Update CRC crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); report_error_ctx->crc_error_ctx = crc_val; + core_util_critical_section_exit(); return MBED_SUCCESS; } #endif From a07a373c9fb022b5a12d9353b324bd0e70e92f13 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Wed, 14 Nov 2018 13:40:13 -0600 Subject: [PATCH 6/9] Change the reboot-max value semantics and code style and other fixes --- cmsis/TARGET_CORTEX_M/mbed_fault_handler.c | 4 +-- platform/mbed_error.c | 36 ++++++++++------------ platform/mbed_lib.json | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c index abd5611658..62fa90ff07 100644 --- a/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c +++ b/cmsis/TARGET_CORTEX_M/mbed_fault_handler.c @@ -32,10 +32,10 @@ void print_context_info(void); #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED //Global for populating the context in exception handler - mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)((uint32_t)FAULT_CONTEXT_LOCATION); + mbed_fault_context_t *const mbed_fault_context=(mbed_fault_context_t *)(FAULT_CONTEXT_LOCATION); #else mbed_fault_context_t fault_context; - mbed_fault_context_t *mbed_fault_context=(mbed_fault_context_t *)&fault_context; + mbed_fault_context_t *const mbed_fault_context=(mbed_fault_context_t *)&fault_context; #endif //This is a handler function called from Fault handler to print the error information out. diff --git a/platform/mbed_error.c b/platform/mbed_error.c index 9723146e01..4ef76827a7 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -50,7 +50,7 @@ static mbed_error_ctx first_error_ctx = {0}; #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED //Global for populating the context in exception handler - static mbed_error_ctx *report_error_ctx=(mbed_error_ctx *)((uint32_t)ERROR_CONTEXT_LOCATION); + static mbed_error_ctx *const report_error_ctx=(mbed_error_ctx *)(ERROR_CONTEXT_LOCATION); static bool is_reboot_error_valid = false; #endif @@ -66,13 +66,13 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign //we dont have many uses cases to create a C wrapper for MbedCRC and the data //we calculate CRC on in this context is very less we will use a local //implementation here. -static unsigned int compute_crc32(unsigned char *data, int datalen) +static unsigned int compute_crc32(void *data, int datalen) { const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */ unsigned int crc = 0; /* CRC value is 32bit */ - for( ;datalen>=0; datalen-- ) { - unsigned char b = *data; + for ( ;datalen>=0; datalen-- ) { + unsigned char b = (*(unsigned char *)data); crc ^= (unsigned int )(b << 24); /* move byte into upper 8bit */ for (int i = 0; i < 8; i++) { /* is MSB 1 */ @@ -200,9 +200,9 @@ mbed_error_status_t mbed_error_initialize(void) { #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED uint32_t crc_val = 0; - crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); - //Read report_error_ctx and check if CRC is correct for report_error_ctx - if((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) { + crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); + //Read report_error_ctx and check if CRC is correct, and with valid status code + if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0) && (report_error_ctx->error_status < 0)) { is_reboot_error_valid = true; #if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) //Report the error info @@ -214,14 +214,14 @@ mbed_error_status_t mbed_error_initialize(void) //Enforce max-reboot only if auto reboot is enabled #if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED - if( report_error_ctx->error_reboot_count > MBED_CONF_PLATFORM_ERROR_REBOOT_MAX ) { + if ( report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX ) { //We have rebooted more than enough, hold the system here. mbed_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); mbed_halt_system(); } #endif report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error - crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); report_error_ctx->crc_error_ctx = crc_val; } #endif @@ -270,9 +270,9 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED uint32_t crc_val = 0; - crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); //Read report_error_ctx and check if CRC is correct for report_error_ctx - if(report_error_ctx->crc_error_ctx == crc_val) { + if (report_error_ctx->crc_error_ctx == crc_val) { uint32_t current_reboot_count = report_error_ctx->error_reboot_count; last_error_ctx.error_reboot_count = current_reboot_count + 1; } else { @@ -280,18 +280,16 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat } last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error //Update the struct with crc - last_error_ctx.crc_error_ctx = compute_crc32( (unsigned char *)&last_error_ctx, ((uint32_t)&(last_error_ctx.crc_error_ctx) - (uint32_t)&last_error_ctx) ); + last_error_ctx.crc_error_ctx = compute_crc32( &last_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); //Protect report_error_ctx while we update it core_util_critical_section_enter(); memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx)); core_util_critical_section_exit(); //We need not call delete_mbed_crc(crc_obj) here as we are going to reset the system anyway, and calling delete while handling a fatal error may cause nested exception -#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED +#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED && (MBED_CONF_PLATFORM_ERROR_REBOOT_MAX > 0) system_reset();//do a system reset to get the system rebooted - while(1); #endif #endif - mbed_halt_system(); return MBED_ERROR_FAILED_OPERATION; @@ -325,12 +323,12 @@ mbed_error_status_t mbed_reset_reboot_error_info() mbed_error_status_t mbed_reset_reboot_count() { #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED - if(is_reboot_error_valid) { + if (is_reboot_error_valid) { uint32_t crc_val = 0; core_util_critical_section_enter(); report_error_ctx->error_reboot_count = 0;//Set reboot count to 0 //Update CRC - crc_val = compute_crc32( (unsigned char *)report_error_ctx, ((uint32_t)&(report_error_ctx->crc_error_ctx) - (uint32_t)report_error_ctx) ); + crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); report_error_ctx->crc_error_ctx = crc_val; core_util_critical_section_exit(); return MBED_SUCCESS; @@ -345,7 +343,7 @@ mbed_error_status_t mbed_get_reboot_error_info(mbed_error_ctx *error_info) mbed_error_status_t status = MBED_ERROR_ITEM_NOT_FOUND; #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED if (is_reboot_error_valid) { - if(error_info != NULL) { + if (error_info != NULL) { memcpy(error_info, report_error_ctx, sizeof(mbed_error_ctx)); status = MBED_SUCCESS; } else { @@ -519,7 +517,7 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, #endif #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT) - if(print_thread_info == true) { + if (print_thread_info) { mbed_error_printf("\nNext:"); print_thread(osRtxInfo.thread.run.next); diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index 9f654321a9..3fd3b85179 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -120,7 +120,7 @@ }, "error-reboot-max": { "help": "Maximum number of auto reboots permitted when an error happens.", - "value": 0 + "value": 1 }, "fatal-error-auto-reboot-enabled": { "help": "Setting this to true enables auto-reboot on a fatal error.", From f1926c0ea958fba9ff6314bdf4af6d1fdce63646 Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Wed, 14 Nov 2018 22:27:54 -0600 Subject: [PATCH 7/9] Fix linker script errors --- .../TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf | 2 +- .../device/TOOLCHAIN_ARM_STD/stm32f429xx.sct | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf index 42c5201399..05376f3712 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_IAR/M487.icf @@ -13,7 +13,7 @@ define symbol __ICFEDIT_region_IRAM_end__ = 0x20028000 - 1; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_crash_data__ = 0x100; -define symbol __ICFEDIT_size_intvec__ = (4 * (16 + 96)) +define symbol __ICFEDIT_size_intvec__ = (4 * (16 + 96)); define symbol __ICFEDIT_size_heap__ = 0x10000; /**** End of ICF editor section. ###ICF###*/ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct index eb4d41143c..7dedde2cae 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct @@ -53,6 +53,9 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } + + RW_m_crash_data MBED_CRASH_REPORT_RAM_START EMPTY MBED_CRASH_REPORT_RAM_SIZE { ; RW data + } ; Total: 107 vectors = 428 bytes (0x1AC) 8-byte aligned = 0x1B0 (0x1AC + 0x4) to be reserved in RAM RW_IRAM1 (MBED_RAM0_START) (MBED_RAM0_SIZE) { ; RW data From 423b52e1c3b52f05a50c096e35198d72bba84c6f Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Fri, 16 Nov 2018 12:26:23 -0600 Subject: [PATCH 8/9] Fix crc calculation error, code-style issues and other fixes --- TESTS/mbed_platform/crash_reporting/main.cpp | 10 ++- platform/mbed_crash_data_offsets.h | 44 +++++----- platform/mbed_error.c | 91 ++++++++++---------- platform/mbed_error.h | 18 ++-- 4 files changed, 85 insertions(+), 78 deletions(-) diff --git a/TESTS/mbed_platform/crash_reporting/main.cpp b/TESTS/mbed_platform/crash_reporting/main.cpp index 8200042dd4..29668a1121 100644 --- a/TESTS/mbed_platform/crash_reporting/main.cpp +++ b/TESTS/mbed_platform/crash_reporting/main.cpp @@ -29,11 +29,12 @@ #define MSG_KEY_DEVICE_READY "crash_reporting_ready" #define MSG_KEY_DEVICE_ERROR "crash_reporting_inject_error" -void mbed_error_reboot_callback(mbed_error_ctx *error_context) { +void mbed_error_reboot_callback(mbed_error_ctx *error_context) +{ TEST_ASSERT_EQUAL_UINT(MBED_ERROR_OUT_OF_MEMORY, error_context->error_status); TEST_ASSERT_EQUAL_UINT(1, error_context->error_reboot_count); mbed_reset_reboot_error_info(); - + //Send the ready msg to host to indicate test pass greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); } @@ -46,12 +47,15 @@ void test_crash_reporting() static char _key[MSG_KEY_LEN + 1] = { }; static char _value[MSG_VALUE_LEN + 1] = { }; + printf("\nWaiting for inject error\n"); greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN); + printf("\nGot inject error\n"); if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) { + printf("\nErroring...\n"); MBED_ERROR1(MBED_ERROR_OUT_OF_MEMORY, "Executing crash reporting test.", 0xDEADBAD); TEST_ASSERT_MESSAGE(0, "crash_reporting() error call failed."); } - + printf("\nWaiting for inject error"); TEST_ASSERT_MESSAGE(0, "Unexpected message received."); } diff --git a/platform/mbed_crash_data_offsets.h b/platform/mbed_crash_data_offsets.h index f2df59fe13..3d550a7ff5 100644 --- a/platform/mbed_crash_data_offsets.h +++ b/platform/mbed_crash_data_offsets.h @@ -24,28 +24,28 @@ extern "C" { #endif #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED - #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) - extern uint32_t Image$$RW_m_crash_data$$ZI$$Base[]; - extern uint32_t Image$$RW_m_crash_data$$ZI$$Size; - #define __CRASH_DATA_RAM_START__ Image$$RW_m_crash_data$$ZI$$Base - #define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size - #elif defined(__ICCARM__) - extern uint32_t __CRASH_DATA_RAM_START__[]; - extern uint32_t __CRASH_DATA_RAM_END__[]; - #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) - #elif defined(__GNUC__) - extern uint32_t __CRASH_DATA_RAM_START__[]; - extern uint32_t __CRASH_DATA_RAM_END__[]; - #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) - #endif /* defined(__CC_ARM) */ - - /* Offset definitions for context capture */ - #define FAULT_CONTEXT_OFFSET (0x0) - #define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context - #define ERROR_CONTEXT_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE) - #define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context - #define FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET) - #define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET) +#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +extern uint32_t Image$$RW_m_crash_data$$ZI$$Base[]; +extern uint32_t Image$$RW_m_crash_data$$ZI$$Size; +#define __CRASH_DATA_RAM_START__ Image$$RW_m_crash_data$$ZI$$Base +#define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size +#elif defined(__ICCARM__) +extern uint32_t __CRASH_DATA_RAM_START__[]; +extern uint32_t __CRASH_DATA_RAM_END__[]; +#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) +#elif defined(__GNUC__) +extern uint32_t __CRASH_DATA_RAM_START__[]; +extern uint32_t __CRASH_DATA_RAM_END__[]; +#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) +#endif /* defined(__CC_ARM) */ + +/* Offset definitions for context capture */ +#define FAULT_CONTEXT_OFFSET (0x0) +#define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context +#define ERROR_CONTEXT_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE) +#define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context +#define FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET) +#define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET) #endif #ifdef __cplusplus diff --git a/platform/mbed_error.c b/platform/mbed_error.c index 4ef76827a7..0b99a41e3b 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -40,7 +40,7 @@ #define ERROR_REPORT(ctx, error_msg, error_filename, error_line, print_thread_info) print_error_report(ctx, error_msg, error_filename, error_line, print_thread_info) static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line, bool print_thread_info); #else -#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0) +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line, print_thread_info) ((void) 0) #endif static core_util_atomic_flag error_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; @@ -49,9 +49,9 @@ static int error_count = 0; static mbed_error_ctx first_error_ctx = {0}; #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED - //Global for populating the context in exception handler - static mbed_error_ctx *const report_error_ctx=(mbed_error_ctx *)(ERROR_CONTEXT_LOCATION); - static bool is_reboot_error_valid = false; +//Global for populating the context in exception handler +static mbed_error_ctx *const report_error_ctx = (mbed_error_ctx *)(ERROR_CONTEXT_LOCATION); +static bool is_reboot_error_valid = false; #endif static mbed_error_ctx last_error_ctx = {0}; @@ -61,19 +61,20 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign //Helper function to calculate CRC //NOTE: It would have been better to use MbedCRC implementation. But //MbedCRC uses table based calculation and we dont want to keep that table memory -//used up for this purpose. Also we cannot force bitwise calculation in MbedCRC +//used up for this purpose. Also we cannot force bitwise calculation in MbedCRC //and it also requires a new wrapper to be called from C implementation. Since //we dont have many uses cases to create a C wrapper for MbedCRC and the data -//we calculate CRC on in this context is very less we will use a local +//we calculate CRC on in this context is very less we will use a local //implementation here. -static unsigned int compute_crc32(void *data, int datalen) +static unsigned int compute_crc32(const void *data, int datalen) { const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */ unsigned int crc = 0; /* CRC value is 32bit */ - - for ( ;datalen>=0; datalen-- ) { - unsigned char b = (*(unsigned char *)data); - crc ^= (unsigned int )(b << 24); /* move byte into upper 8bit */ + unsigned char *buf = (unsigned char *)data;//use a temp variable to make code readable and to avoid typecasting issues. + + for (; datalen>0; datalen-- ) { + unsigned char b = *buf++; + crc ^= (unsigned int)(b << 24); /* move byte into upper 8bit */ for (int i = 0; i < 8; i++) { /* is MSB 1 */ if ((crc & 0x80000000) != 0) { @@ -191,7 +192,8 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign return MBED_SUCCESS; } -WEAK void mbed_error_reboot_callback(mbed_error_ctx *error_context) { +WEAK void mbed_error_reboot_callback(mbed_error_ctx *error_context) +{ //Dont do anything here, let application override this if required. } @@ -200,32 +202,35 @@ mbed_error_status_t mbed_error_initialize(void) { #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED uint32_t crc_val = 0; - crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); - //Read report_error_ctx and check if CRC is correct, and with valid status code - if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0) && (report_error_ctx->error_status < 0)) { - is_reboot_error_valid = true; -#if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) - //Report the error info - mbed_error_printf("\n== Your last reboot was triggered by an error, below is the error information =="); - ERROR_REPORT( report_error_ctx, "System rebooted due to fatal error", MBED_FILENAME, __LINE__, false ); -#endif - //Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling - mbed_error_reboot_callback(report_error_ctx); + + //Just check if we have valid value for error_status, if error_status is positive(which is not valid), no need to check crc + if (report_error_ctx->error_status < 0) { + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); + //Read report_error_ctx and check if CRC is correct, and with valid status code + if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) { + is_reboot_error_valid = true; +#if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) + //Report the error info + mbed_error_printf("\n== Your last reboot was triggered by an error, below is the error information =="); + ERROR_REPORT(report_error_ctx, "System rebooted due to fatal error", MBED_FILENAME, __LINE__, false); +#endif + //Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling + mbed_error_reboot_callback(report_error_ctx); - //Enforce max-reboot only if auto reboot is enabled -#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED - if ( report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX ) { - //We have rebooted more than enough, hold the system here. - mbed_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); - mbed_halt_system(); + //Enforce max-reboot only if auto reboot is enabled +#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED + if (report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX) { + //We have rebooted more than enough, hold the system here. + mbed_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); + mbed_halt_system(); + } +#endif + report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); + report_error_ctx->crc_error_ctx = crc_val; } -#endif - report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error - crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); - report_error_ctx->crc_error_ctx = crc_val; } #endif - return MBED_SUCCESS; } @@ -267,10 +272,10 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat //On fatal errors print the error context/report ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number, true); } - + #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED uint32_t crc_val = 0; - crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); //Read report_error_ctx and check if CRC is correct for report_error_ctx if (report_error_ctx->crc_error_ctx == crc_val) { uint32_t current_reboot_count = report_error_ctx->error_reboot_count; @@ -280,7 +285,7 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat } last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error //Update the struct with crc - last_error_ctx.crc_error_ctx = compute_crc32( &last_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); + last_error_ctx.crc_error_ctx = compute_crc32(&last_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); //Protect report_error_ctx while we update it core_util_critical_section_enter(); memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx)); @@ -291,8 +296,6 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat #endif #endif mbed_halt_system(); - - return MBED_ERROR_FAILED_OPERATION; } //Register an application defined callback with error handling @@ -313,10 +316,10 @@ mbed_error_status_t mbed_reset_reboot_error_info() #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED //Protect for thread safety core_util_critical_section_enter(); - memset(report_error_ctx, 0, sizeof(mbed_error_ctx) ); + memset(report_error_ctx, 0, sizeof(mbed_error_ctx)); core_util_critical_section_exit(); #endif - return MBED_SUCCESS; + return MBED_SUCCESS; } //Reset the reboot error context @@ -328,13 +331,13 @@ mbed_error_status_t mbed_reset_reboot_count() core_util_critical_section_enter(); report_error_ctx->error_reboot_count = 0;//Set reboot count to 0 //Update CRC - crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx) ); + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); report_error_ctx->crc_error_ctx = crc_val; core_util_critical_section_exit(); return MBED_SUCCESS; } #endif - return MBED_ERROR_ITEM_NOT_FOUND; + return MBED_ERROR_ITEM_NOT_FOUND; } //Retrieve the reboot error context @@ -350,7 +353,7 @@ mbed_error_status_t mbed_get_reboot_error_info(mbed_error_ctx *error_info) status = MBED_ERROR_INVALID_ARGUMENT; } } -#endif +#endif return status; } diff --git a/platform/mbed_error.h b/platform/mbed_error.h index 4a10343626..07d12af03b 100644 --- a/platform/mbed_error.h +++ b/platform/mbed_error.h @@ -831,7 +831,7 @@ typedef struct _mbed_error_ctx { int32_t error_reboot_count;//everytime we write this struct we increment this value by 1, irrespective of time between reboots. Note that the data itself might change, but everytime we reboot due to error we update this count by 1 int32_t is_error_processed;//once this error is processed set this value to 1 uint32_t crc_error_ctx;//crc_error_ctx should always be the last member in this struct -#endif +#endif } mbed_error_ctx; /** To generate a fatal compile-time error, you can use the pre-processor #error directive. @@ -935,10 +935,10 @@ typedef void (*mbed_error_hook_t)(const mbed_error_ctx *error_ctx); /** - * Callback function for reporting error context during boot up. When MbedOS error handling system detects a fatal error + * Callback function for reporting error context during boot up. When MbedOS error handling system detects a fatal error * it will auto-reboot the system(if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled) after capturing the - * error info in special crash data RAM region. Once rebooted, MbedOS initialization routines will call this function with a pointer to - * the captured mbed_error_ctx structure. If application implementation needs to receive this callback, mbed_error_reboot_callback + * error info in special crash data RAM region. Once rebooted, MbedOS initialization routines will call this function with a pointer to + * the captured mbed_error_ctx structure. If application implementation needs to receive this callback, mbed_error_reboot_callback * function should be overriden with custom implementation. By default it's defined as a WEAK function in mbed_error.c. * Note that this callback will be invoked before the system starts executing main() function. So the implementation of * the callback should be aware any resource limitations/availability of resources which are yet to be initialized by application main(). @@ -950,10 +950,10 @@ typedef void (*mbed_error_hook_t)(const mbed_error_ctx *error_ctx); void mbed_error_reboot_callback(mbed_error_ctx *error_context); /** - * Initialize error handling system, this is called by the mbed-os boot sequence. This is not required to be called by Application unless the boot sequence is overridden by the system implementation. + * Initialize error handling system, this is called by the mbed-os boot sequence. This is not required to be called by Application unless the boot sequence is overridden by the system implementation. * NOTE: This function also prints the error report to serial terminal if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED is enabled. * If MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled and if the current reboot count exceeds MBED_CONF_PLATFORM_ERROR_REBOOT_MAX the system will halt when this function is called, - * and in such cases the caller will not get the control back. Also note that calling this function may trigger mbed_error_reboot_callback() if application side overides mbed_error_reboot_callback(). + * and in such cases the caller will not get the control back. Also note that calling this function may trigger mbed_error_reboot_callback() if application side overides mbed_error_reboot_callback(). * @return MBED_SUCCESS on success. * */ @@ -965,13 +965,13 @@ mbed_error_status_t mbed_error_initialize(void); * @param error_info Pointer to mbed_error_ctx struct allocated by the caller. This is the mbed_error_ctx info captured as part of the fatal error which triggered the reboot. * @return 0 or MBED_SUCCESS on success. * MBED_ERROR_INVALID_ARGUMENT in case of invalid error_info pointer - * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system + * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system * */ mbed_error_status_t mbed_get_reboot_error_info(mbed_error_ctx *error_info); /** - * Calling this function resets the current reboot context captured by the system(stored in special crash data RAM region). + * Calling this function resets the current reboot context captured by the system(stored in special crash data RAM region). * @return MBED_SUCCESS on success. * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system */ @@ -979,7 +979,7 @@ mbed_error_status_t mbed_reset_reboot_error_info(void); /** * Calling this function resets the current reboot count stored as part of error context captured in special crash data RAM region. - * The function will also update the CRC value stored as part of error context accordingly. + * The function will also update the CRC value stored as part of error context accordingly. * @return MBED_SUCCESS on success. * MBED_ERROR_ITEM_NOT_FOUND if no reboot context is currently captured by the system */ From f59b99d889a99d1f0a0113bcc441890145e7a63a Mon Sep 17 00:00:00 2001 From: Senthil Ramakrishnan Date: Sun, 18 Nov 2018 20:38:18 -0600 Subject: [PATCH 9/9] Removing support for printing error-report after reboot and other minor fixes --- TESTS/host_tests/crash_reporting.py | 2 + TESTS/mbed_platform/crash_reporting/main.cpp | 18 ++++-- platform/mbed_error.c | 66 ++++++++++---------- platform/mbed_error.h | 3 +- platform/mbed_lib.json | 17 ----- 5 files changed, 48 insertions(+), 58 deletions(-) diff --git a/TESTS/host_tests/crash_reporting.py b/TESTS/host_tests/crash_reporting.py index b2153b1cff..bc4a717078 100644 --- a/TESTS/host_tests/crash_reporting.py +++ b/TESTS/host_tests/crash_reporting.py @@ -59,6 +59,8 @@ class CrashReportingTest(BaseHostTest): wait_after_reset = self.get_config_item('forced_reset_timeout') wait_after_reset = wait_after_reset if wait_after_reset is not None else DEFAULT_CYCLE_PERIOD + #Wait 2 seconds for system to init + time.sleep(2.0) #self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) self.send_kv(MSG_KEY_DEVICE_ERROR, MSG_VALUE_DUMMY) time.sleep(5.0) diff --git a/TESTS/mbed_platform/crash_reporting/main.cpp b/TESTS/mbed_platform/crash_reporting/main.cpp index 29668a1121..dab00237de 100644 --- a/TESTS/mbed_platform/crash_reporting/main.cpp +++ b/TESTS/mbed_platform/crash_reporting/main.cpp @@ -15,6 +15,7 @@ */ #include "mbed.h" #include "mbed_error.h" +#include "mbed_crash_data_offsets.h" #include "greentea-client/test_env.h" #include "unity/unity.h" @@ -29,33 +30,38 @@ #define MSG_KEY_DEVICE_READY "crash_reporting_ready" #define MSG_KEY_DEVICE_ERROR "crash_reporting_inject_error" +static mbed_error_ctx saved_error_ctx = {0}; + void mbed_error_reboot_callback(mbed_error_ctx *error_context) { - TEST_ASSERT_EQUAL_UINT(MBED_ERROR_OUT_OF_MEMORY, error_context->error_status); - TEST_ASSERT_EQUAL_UINT(1, error_context->error_reboot_count); + + TEST_ASSERT_EQUAL_UINT((uint32_t)error_context, ERROR_CONTEXT_LOCATION); + memcpy(&saved_error_ctx, error_context, sizeof(mbed_error_ctx)); mbed_reset_reboot_error_info(); + TEST_ASSERT_EQUAL_UINT(MBED_ERROR_OUT_OF_MEMORY, saved_error_ctx.error_status); + TEST_ASSERT_EQUAL_UINT(1, saved_error_ctx.error_reboot_count); + //Send the ready msg to host to indicate test pass greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); } void test_crash_reporting() { + //Clear any previous status + mbed_reset_reboot_error_info(); + // Report readiness greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); static char _key[MSG_KEY_LEN + 1] = { }; static char _value[MSG_VALUE_LEN + 1] = { }; - printf("\nWaiting for inject error\n"); greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN); - printf("\nGot inject error\n"); if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) { - printf("\nErroring...\n"); MBED_ERROR1(MBED_ERROR_OUT_OF_MEMORY, "Executing crash reporting test.", 0xDEADBAD); TEST_ASSERT_MESSAGE(0, "crash_reporting() error call failed."); } - printf("\nWaiting for inject error"); TEST_ASSERT_MESSAGE(0, "Unexpected message received."); } diff --git a/platform/mbed_error.c b/platform/mbed_error.c index 0b99a41e3b..0faca8b7fc 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -37,10 +37,10 @@ #include #ifndef NDEBUG -#define ERROR_REPORT(ctx, error_msg, error_filename, error_line, print_thread_info) print_error_report(ctx, error_msg, error_filename, error_line, print_thread_info) -static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line, bool print_thread_info); +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) print_error_report(ctx, error_msg, error_filename, error_line) +static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line); #else -#define ERROR_REPORT(ctx, error_msg, error_filename, error_line, print_thread_info) ((void) 0) +#define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0) #endif static core_util_atomic_flag error_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; @@ -71,8 +71,8 @@ static unsigned int compute_crc32(const void *data, int datalen) const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */ unsigned int crc = 0; /* CRC value is 32bit */ unsigned char *buf = (unsigned char *)data;//use a temp variable to make code readable and to avoid typecasting issues. - - for (; datalen>0; datalen-- ) { + + for (; datalen > 0; datalen--) { unsigned char b = *buf++; crc ^= (unsigned int)(b << 24); /* move byte into upper 8bit */ for (int i = 0; i < 8; i++) { @@ -115,7 +115,7 @@ WEAK MBED_NORETURN void error(const char *format, ...) // Prevent recursion if error is called again during store+print attempt if (!core_util_atomic_flag_test_and_set(&error_in_progress)) { handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR()); - ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0, true); + ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0); #ifndef NDEBUG va_list arg; @@ -202,32 +202,34 @@ mbed_error_status_t mbed_error_initialize(void) { #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED uint32_t crc_val = 0; - + //Just check if we have valid value for error_status, if error_status is positive(which is not valid), no need to check crc if (report_error_ctx->error_status < 0) { crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); //Read report_error_ctx and check if CRC is correct, and with valid status code if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) { is_reboot_error_valid = true; -#if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) //Report the error info - mbed_error_printf("\n== Your last reboot was triggered by an error, below is the error information =="); - ERROR_REPORT(report_error_ctx, "System rebooted due to fatal error", MBED_FILENAME, __LINE__, false); -#endif + printf("\n== The system has been rebooted due to a fatal error. ==\n"); + //Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling mbed_error_reboot_callback(report_error_ctx); - - //Enforce max-reboot only if auto reboot is enabled + + //We let the callback reset the error info, so check if its still valid and do the rest only if its still valid. + if (report_error_ctx->error_reboot_count < 0) { + + //Enforce max-reboot only if auto reboot is enabled #if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED - if (report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX) { - //We have rebooted more than enough, hold the system here. - mbed_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); - mbed_halt_system(); - } + if (report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX) { + //We have rebooted more than enough, hold the system here. + printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); + mbed_halt_system(); + } #endif - report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error - crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); - report_error_ctx->crc_error_ctx = crc_val; + report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); + report_error_ctx->crc_error_ctx = crc_val; + } } } #endif @@ -270,7 +272,7 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat (void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR()); //On fatal errors print the error context/report - ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number, true); + ERROR_REPORT(&last_error_ctx, error_msg, filename, line_number); } #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED @@ -447,7 +449,7 @@ static void print_threads_info(const osRtxThread_t *threads) #endif #ifndef NDEBUG -static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, const char *error_filename, int error_line, bool print_thread_info) +static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, const char *error_filename, int error_line) { int error_code = MBED_GET_ERROR_CODE(ctx->error_status); int error_module = MBED_GET_ERROR_MODULE(ctx->error_status); @@ -520,19 +522,17 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *error_msg, #endif #if MBED_CONF_PLATFORM_ERROR_ALL_THREADS_INFO && defined(MBED_CONF_RTOS_PRESENT) - if (print_thread_info) { - mbed_error_printf("\nNext:"); - print_thread(osRtxInfo.thread.run.next); + mbed_error_printf("\nNext:"); + print_thread(osRtxInfo.thread.run.next); - mbed_error_printf("\nReady:"); - print_threads_info(osRtxInfo.thread.ready.thread_list); + mbed_error_printf("\nReady:"); + print_threads_info(osRtxInfo.thread.ready.thread_list); - mbed_error_printf("\nWait:"); - print_threads_info(osRtxInfo.thread.wait_list); + mbed_error_printf("\nWait:"); + print_threads_info(osRtxInfo.thread.wait_list); - mbed_error_printf("\nDelay:"); - print_threads_info(osRtxInfo.thread.delay_list); - } + mbed_error_printf("\nDelay:"); + print_threads_info(osRtxInfo.thread.delay_list); #endif mbed_error_printf(MBED_CONF_PLATFORM_ERROR_DECODE_HTTP_URL_STR, ctx->error_status); mbed_error_printf("\n-- MbedOS Error Info --\n"); diff --git a/platform/mbed_error.h b/platform/mbed_error.h index 07d12af03b..4ed8451d6a 100644 --- a/platform/mbed_error.h +++ b/platform/mbed_error.h @@ -951,8 +951,7 @@ void mbed_error_reboot_callback(mbed_error_ctx *error_context); /** * Initialize error handling system, this is called by the mbed-os boot sequence. This is not required to be called by Application unless the boot sequence is overridden by the system implementation. - * NOTE: This function also prints the error report to serial terminal if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED is enabled. - * If MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled and if the current reboot count exceeds MBED_CONF_PLATFORM_ERROR_REBOOT_MAX the system will halt when this function is called, + * NOTE: If MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled and if the current reboot count exceeds MBED_CONF_PLATFORM_ERROR_REBOOT_MAX the system will halt when this function is called, * and in such cases the caller will not get the control back. Also note that calling this function may trigger mbed_error_reboot_callback() if application side overides mbed_error_reboot_callback(). * @return MBED_SUCCESS on success. * diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index 3fd3b85179..cf5b16325f 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -114,10 +114,6 @@ "help": "Enables crash context capture when the system enters a fatal error/crash.", "value": false }, - "reboot-crash-report-enabled": { - "help": "Enables crash context capture when the system enters a fatal error/crash.", - "value": false - }, "error-reboot-max": { "help": "Maximum number of auto reboots permitted when an error happens.", "value": 1 @@ -139,67 +135,54 @@ }, "DISCO_L475VG_IOT01A": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "K64F": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "K66F": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_F429ZI": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_F746ZG": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_F767ZI": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_F439ZI": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "UBLOX_EVK_ODIN_W2": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "UBLOX_C030_U201": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUMAKER_PFM_M487": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NRF52840_DK": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_L476RG": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true }, "NUCLEO_F411RE": { "crash-capture-enabled": true, - "reboot-crash-report-enabled": true, "fatal-error-auto-reboot-enabled": true } }