mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-10 04:22:05 +03:00
Add a CRC32 over progmem and ESP.checkFlashCRC (#6566)
* Add a CRC32 over progmem and ESP.checkFlashCRC Automatically embed a CRC32 of the program memory (including bootloader but excluding any filesystems) in all images in unused space in the bootloader block. Add a call, ESP.checkFlashCRC() which returns false if the calculated CRC doesn't match the one stored in the image (i.e. flash corruption). Fixes #4165 * Add example that corrupts itself, comments Show CRC checking catch a 1-bit error in program code by corrupting a large array, and then return it to clean and verify the CRC matches once again. Add comments to the CRC check routine Clean up pylint complaints on crc32bin.py * Check linker script for CRC space in bootsector Add an assertion in the eboot linker file to guarantee that we have at least 8 bytes of unused space at the end of the boot sector to patch in the CRC. If not, the eboot link will fail. * Add note about what to do if CRC check fails Per discussion with @d-a-v. When the CRC check fails, you could *try* to do certain things (but may not succeed since there is known flash corruption at that point). List a few ideas for application authors. * Only single, flash/ram friendly crc32() function * Combine the CRC calc and bin generation in 1 step Per discussion w/@mcspr, combine the CRC calculation with the binary generation, removing the additional build step.
This commit is contained in:
committed by
GitHub
parent
9985a32914
commit
52d84b1ead
@ -26,6 +26,7 @@
|
||||
#include "MD5Builder.h"
|
||||
#include "umm_malloc/umm_malloc.h"
|
||||
#include "cont.h"
|
||||
#include "coredecls.h"
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
@ -447,6 +448,25 @@ bool EspClass::checkFlashConfig(bool needsEquals) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EspClass::checkFlashCRC() {
|
||||
// The CRC and total length are placed in extra space at the end of the 4K chunk
|
||||
// of flash occupied by the bootloader. If the bootloader grows to >4K-8 bytes,
|
||||
// we'll need to adjust this.
|
||||
uint32_t flashsize = *((uint32_t*)(0x40200000 + 4088)); // Start of PROGMEM plus 4K-8
|
||||
uint32_t flashcrc = *((uint32_t*)(0x40200000 + 4092)); // Start of PROGMEM plus 4K-4
|
||||
uint32_t z[2];
|
||||
z[0] = z[1] = 0;
|
||||
|
||||
// Start the checksum
|
||||
uint32_t crc = crc32((const void*)0x40200000, 4096-8, 0xffffffff);
|
||||
// Pretend the 2 words of crc/len are zero to be idempotent
|
||||
crc = crc32(z, 8, crc);
|
||||
// Finish the CRC calculation over the rest of flash
|
||||
crc = crc32((const void*)0x40201000, flashsize-4096, crc);
|
||||
return crc == flashcrc;
|
||||
}
|
||||
|
||||
|
||||
String EspClass::getResetReason(void) {
|
||||
char buff[32];
|
||||
if (resetInfo.reason == REASON_DEFAULT_RST) { // normal startup by power on
|
||||
|
@ -176,6 +176,8 @@ class EspClass {
|
||||
|
||||
bool checkFlashConfig(bool needsEquals = false);
|
||||
|
||||
bool checkFlashCRC();
|
||||
|
||||
bool flashEraseSector(uint32_t sector);
|
||||
bool flashWrite(uint32_t offset, uint32_t *data, size_t size);
|
||||
bool flashRead(uint32_t offset, uint32_t *data, size_t size);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "coredecls.h"
|
||||
#include "pgmspace.h"
|
||||
|
||||
// moved from core_esp8266_eboot_command.cpp
|
||||
uint32_t crc32 (const void* data, size_t length, uint32_t crc /*= 0xffffffff*/)
|
||||
@ -27,7 +28,7 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc /*= 0xffffffff*/)
|
||||
const uint8_t* ldata = (const uint8_t*)data;
|
||||
while (length--)
|
||||
{
|
||||
uint8_t c = *ldata++;
|
||||
uint8_t c = pgm_read_byte(ldata++);
|
||||
for (uint32_t i = 0x80; i > 0; i >>= 1)
|
||||
{
|
||||
bool bit = crc & 0x80000000;
|
||||
|
Reference in New Issue
Block a user