diff --git a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp index 769fcfbbe3..dd7e7da675 100644 --- a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp @@ -252,7 +252,7 @@ const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC; #if MBED_CONF_SD_CRC_ENABLED SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) : _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0), - _init_ref_count(0), _crc_on(crc_on), _crc16(0, 0, false, false) + _init_ref_count(0), _crc_on(crc_on) #else SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) : _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0), @@ -678,10 +678,11 @@ uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) cmdPacket[4] = (arg >> 0); #if MBED_CONF_SD_CRC_ENABLED - uint32_t crc; if (_crc_on) { - _crc7.compute((void *)cmdPacket, 5, &crc); - cmdPacket[5] = (char)(crc | 0x01); + MbedCRC crc7; + uint32_t crc; + crc7.compute(cmdPacket, 5, &crc); + cmdPacket[5] = ((uint8_t) crc << 1) | 0x01; } else #endif { @@ -899,12 +900,13 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) #if MBED_CONF_SD_CRC_ENABLED if (_crc_on) { + mbed::MbedCRC crc16(0, 0, false, false); uint32_t crc_result; // Compute and verify checksum - _crc16.compute((void *)buffer, length, &crc_result); - if ((uint16_t)crc_result != crc) { - debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx16 "\n", - crc, (uint16_t)crc_result); + crc16.compute(buffer, length, &crc_result); + if (crc_result != crc) { + debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n", + crc, crc_result); _deselect(); return SD_BLOCK_DEVICE_ERROR_CRC; } @@ -934,9 +936,10 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) #if MBED_CONF_SD_CRC_ENABLED if (_crc_on) { + mbed::MbedCRC crc16(0, 0, false, false); uint32_t crc_result; // Compute and verify checksum - _crc16.compute((void *)buffer, length, &crc_result); + crc16.compute((void *)buffer, length, &crc_result); if ((uint16_t)crc_result != crc) { debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx16 "\n", crc, (uint16_t)crc_result); @@ -962,8 +965,9 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len #if MBED_CONF_SD_CRC_ENABLED if (_crc_on) { + mbed::MbedCRC crc16(0, 0, false, false); // Compute CRC - _crc16.compute((void *)buffer, length, &crc); + crc16.compute(buffer, length, &crc); } #endif diff --git a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h index 08caa4fea7..ebf1048486 100644 --- a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h @@ -256,8 +256,6 @@ private: #if MBED_CONF_SD_CRC_ENABLED bool _crc_on; - mbed::MbedCRC _crc7; - mbed::MbedCRC _crc16; #endif }; diff --git a/drivers/source/MbedCRC.cpp b/drivers/source/MbedCRC.cpp index d4c794c06f..24160acbda 100644 --- a/drivers/source/MbedCRC.cpp +++ b/drivers/source/MbedCRC.cpp @@ -146,3 +146,11 @@ const uint32_t MbedCRC::_crc_table[MBED_CRC #endif // MBED_CRC_TABLE_SIZE > 0 } // namespace mbed + +extern "C" uint32_t mbed_tiny_compute_crc32(const void *data, int datalen) +{ + mbed::MbedCRC crc32(0, 0, false, false); + uint32_t result; + crc32.compute(data, datalen, &result); + return result; +} diff --git a/features/storage/filesystem/littlefs/LittleFileSystem.cpp b/features/storage/filesystem/littlefs/LittleFileSystem.cpp index 66e080b722..6e20476c7b 100644 --- a/features/storage/filesystem/littlefs/LittleFileSystem.cpp +++ b/features/storage/filesystem/littlefs/LittleFileSystem.cpp @@ -25,8 +25,10 @@ namespace mbed { extern "C" void lfs_crc(uint32_t *crc, const void *buffer, size_t size) { uint32_t initial_xor = *crc; - MbedCRC ct(initial_xor, 0x0, true, false); - ct.compute((void *)buffer, size, (uint32_t *) crc); + // lfs_cache_crc calls lfs_crc for every byte individually, so can't afford + // start-up overhead for hardware acceleration. Limit to table-based. + MbedCRC ct(initial_xor, 0x0, true, true); + ct.compute(buffer, size, crc); } ////// Conversion functions ////// diff --git a/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp b/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp index 0c6079dac9..87e452724e 100644 --- a/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp +++ b/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp @@ -309,7 +309,7 @@ static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data { uint32_t crc; MbedCRC ct(init_crc, 0x0, true, false); - ct.compute(const_cast(data_buf), data_size, &crc); + ct.compute(data_buf, data_size, &crc); return crc; } #endif // DEVICE_FLASH diff --git a/features/storage/kvstore/tdbstore/TDBStore.cpp b/features/storage/kvstore/tdbstore/TDBStore.cpp index 61ce279762..954cefb0ef 100644 --- a/features/storage/kvstore/tdbstore/TDBStore.cpp +++ b/features/storage/kvstore/tdbstore/TDBStore.cpp @@ -117,7 +117,7 @@ static uint32_t calc_crc(uint32_t init_crc, uint32_t data_size, const void *data { uint32_t crc; MbedCRC ct(init_crc, 0x0, true, false); - ct.compute(const_cast(data_buf), data_size, &crc); + ct.compute(data_buf, data_size, &crc); return crc; } diff --git a/platform/source/mbed_error.c b/platform/source/mbed_error.c index bc16a3d8ed..37a9711d86 100644 --- a/platform/source/mbed_error.c +++ b/platform/source/mbed_error.c @@ -27,6 +27,7 @@ #include "platform/mbed_power_mgmt.h" #include "platform/mbed_stats.h" #include "platform/source/TARGET_CORTEX_M/mbed_fault_handler.h" +#include "drivers/MbedCRC.h" #include "mbed_rtx.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtx_os.h" @@ -64,36 +65,6 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign //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; - -//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(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--) { - 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) { - crc = (unsigned int)((crc << 1) ^ polynomial); - } else { - crc <<= 1; - } - } - } - - return crc; -} #endif //Helper function to halt the system @@ -246,7 +217,7 @@ mbed_error_status_t mbed_error_initialize(void) //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)); + crc_val = mbed_tiny_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; @@ -258,7 +229,7 @@ mbed_error_status_t mbed_error_initialize(void) if (report_error_ctx->error_reboot_count > 0) { 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 = mbed_tiny_compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); report_error_ctx->crc_error_ctx = crc_val; //Enforce max-reboot only if auto reboot is enabled @@ -321,7 +292,7 @@ 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(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); + crc_val = mbed_tiny_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; @@ -331,7 +302,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 = mbed_tiny_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)); @@ -384,7 +355,7 @@ 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 = mbed_tiny_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;