Fix crc calculation error, code-style issues and other fixes

pull/8702/head
Senthil Ramakrishnan 2018-11-16 12:26:23 -06:00
parent f1926c0ea9
commit 423b52e1c3
4 changed files with 85 additions and 78 deletions

View File

@ -29,7 +29,8 @@
#define MSG_KEY_DEVICE_READY "crash_reporting_ready" #define MSG_KEY_DEVICE_READY "crash_reporting_ready"
#define MSG_KEY_DEVICE_ERROR "crash_reporting_inject_error" #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(MBED_ERROR_OUT_OF_MEMORY, error_context->error_status);
TEST_ASSERT_EQUAL_UINT(1, error_context->error_reboot_count); TEST_ASSERT_EQUAL_UINT(1, error_context->error_reboot_count);
mbed_reset_reboot_error_info(); mbed_reset_reboot_error_info();
@ -46,12 +47,15 @@ void test_crash_reporting()
static char _key[MSG_KEY_LEN + 1] = { }; static char _key[MSG_KEY_LEN + 1] = { };
static char _value[MSG_VALUE_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); greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN);
printf("\nGot inject error\n");
if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) { if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) {
printf("\nErroring...\n");
MBED_ERROR1(MBED_ERROR_OUT_OF_MEMORY, "Executing crash reporting test.", 0xDEADBAD); 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, "crash_reporting() error call failed.");
} }
printf("\nWaiting for inject error");
TEST_ASSERT_MESSAGE(0, "Unexpected message received."); TEST_ASSERT_MESSAGE(0, "Unexpected message received.");
} }

View File

@ -24,28 +24,28 @@ extern "C" {
#endif #endif
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) #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$$Base[];
extern uint32_t Image$$RW_m_crash_data$$ZI$$Size; 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_START__ Image$$RW_m_crash_data$$ZI$$Base
#define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size #define __CRASH_DATA_RAM_SIZE__ Image$$RW_m_crash_data$$ZI$$Size
#elif defined(__ICCARM__) #elif defined(__ICCARM__)
extern uint32_t __CRASH_DATA_RAM_START__[]; extern uint32_t __CRASH_DATA_RAM_START__[];
extern uint32_t __CRASH_DATA_RAM_END__[]; extern uint32_t __CRASH_DATA_RAM_END__[];
#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__)
#elif defined(__GNUC__) #elif defined(__GNUC__)
extern uint32_t __CRASH_DATA_RAM_START__[]; extern uint32_t __CRASH_DATA_RAM_START__[];
extern uint32_t __CRASH_DATA_RAM_END__[]; extern uint32_t __CRASH_DATA_RAM_END__[];
#define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__) #define __CRASH_DATA_RAM_SIZE__ (__CRASH_DATA_RAM_END__ - __CRASH_DATA_RAM_START__)
#endif /* defined(__CC_ARM) */ #endif /* defined(__CC_ARM) */
/* Offset definitions for context capture */ /* Offset definitions for context capture */
#define FAULT_CONTEXT_OFFSET (0x0) #define FAULT_CONTEXT_OFFSET (0x0)
#define FAULT_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) for Fault Context #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_OFFSET (FAULT_CONTEXT_OFFSET + FAULT_CONTEXT_SIZE)
#define ERROR_CONTEXT_SIZE (0x80 / 4) //32 words(128 bytes) bytes for Error Context #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 FAULT_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + FAULT_CONTEXT_OFFSET)
#define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET) #define ERROR_CONTEXT_LOCATION (__CRASH_DATA_RAM_START__ + ERROR_CONTEXT_OFFSET)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -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) #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); static void print_error_report(const mbed_error_ctx *ctx, const char *, const char *error_filename, int error_line, bool print_thread_info);
#else #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 #endif
static core_util_atomic_flag error_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; 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}; static mbed_error_ctx first_error_ctx = {0};
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
//Global for populating the context in exception handler //Global for populating the context in exception handler
static mbed_error_ctx *const report_error_ctx=(mbed_error_ctx *)(ERROR_CONTEXT_LOCATION); static mbed_error_ctx *const report_error_ctx = (mbed_error_ctx *)(ERROR_CONTEXT_LOCATION);
static bool is_reboot_error_valid = false; static bool is_reboot_error_valid = false;
#endif #endif
static mbed_error_ctx last_error_ctx = {0}; static mbed_error_ctx last_error_ctx = {0};
@ -66,14 +66,15 @@ 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 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. //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 */ const unsigned int polynomial = 0x04C11DB7; /* divisor is 32bit */
unsigned int crc = 0; /* CRC value 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 = (*(unsigned char *)data); unsigned char b = *buf++;
crc ^= (unsigned int )(b << 24); /* move byte into upper 8bit */ crc ^= (unsigned int)(b << 24); /* move byte into upper 8bit */
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
/* is MSB 1 */ /* is MSB 1 */
if ((crc & 0x80000000) != 0) { 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; 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. //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 #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
uint32_t crc_val = 0; uint32_t crc_val = 0;
crc_val = compute_crc32( report_error_ctx, offsetof(mbed_error_ctx, crc_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 //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)) { if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) {
is_reboot_error_valid = true; is_reboot_error_valid = true;
#if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG) #if MBED_CONF_PLATFORM_REBOOT_CRASH_REPORT_ENABLED && !defined(NDEBUG)
//Report the error info //Report the error info
mbed_error_printf("\n== Your last reboot was triggered by an error, below is the error information =="); 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 ); ERROR_REPORT(report_error_ctx, "System rebooted due to fatal error", MBED_FILENAME, __LINE__, false);
#endif #endif
//Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling //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); mbed_error_reboot_callback(report_error_ctx);
//Enforce max-reboot only if auto reboot is enabled //Enforce max-reboot only if auto reboot is enabled
#if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_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. //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_error_printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count);
mbed_halt_system(); mbed_halt_system();
} }
#endif #endif
report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error 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) ); 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->crc_error_ctx = crc_val;
} }
}
#endif #endif
return MBED_SUCCESS; return MBED_SUCCESS;
} }
@ -270,7 +275,7 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
uint32_t crc_val = 0; 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 //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; 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 last_error_ctx.is_error_processed = 0;//Set the flag that this is a new error
//Update the struct with crc //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 //Protect report_error_ctx while we update it
core_util_critical_section_enter(); core_util_critical_section_enter();
memcpy(report_error_ctx, &last_error_ctx, sizeof(mbed_error_ctx)); 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
#endif #endif
mbed_halt_system(); mbed_halt_system();
return MBED_ERROR_FAILED_OPERATION;
} }
//Register an application defined callback with error handling //Register an application defined callback with error handling
@ -313,7 +316,7 @@ mbed_error_status_t mbed_reset_reboot_error_info()
#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED #if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
//Protect for thread safety //Protect for thread safety
core_util_critical_section_enter(); 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(); core_util_critical_section_exit();
#endif #endif
return MBED_SUCCESS; return MBED_SUCCESS;
@ -328,7 +331,7 @@ mbed_error_status_t mbed_reset_reboot_count()
core_util_critical_section_enter(); core_util_critical_section_enter();
report_error_ctx->error_reboot_count = 0;//Set reboot count to 0 report_error_ctx->error_reboot_count = 0;//Set reboot count to 0
//Update CRC //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; report_error_ctx->crc_error_ctx = crc_val;
core_util_critical_section_exit(); core_util_critical_section_exit();
return MBED_SUCCESS; return MBED_SUCCESS;