-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature request: CRC for program memory #4165
Comments
@s0170071, have a look here (https://github.com/FrankBoesing/FastCRC), not sure if it works with 8266 but there are examples you can try. Is your code regularly writing to the flash chip using SPIFFS or EEPROM? If so that may be your problem. Flash chips have a relatively low number of lifetime write cycles. The cheaper chips may only survive a few thousand writes before failing. The better quality ones can survive a few hundred thousand, but still. not a good idea to be writing to them repeatedly, they're really only meant to store your code and things like user settings. If you want to write to memory repeatedly you should use an SD card instead. |
@ondabeach previous comment is correct. I would only add that SPIFFS does wear leveling, so the flash lifetime is much longer vs writing directly to a flash sector like with eeprom. |
@ondabeach @devyte as far as i understand, @s0170071 is asking about the memory-mapped part of flash, i.e the program memory (not SPIFFS or EEPROM). What you could do is to calculate CRC32 of the binary using some external tool, and then embed this value into some known location in flash using e.g. |
That's exactly what I was thinking. The CRC goes to the bin file after linking. Using a py script or so.
Although I have found md5 options for another linker, but they are not working here.
Could you point out how I would place the CRC into that sector you were talking about?
|
|
@igrr: Thank you. Your solution assumes that the location 0xffc has not previously been used by the linker. I know that there are linker commands to place e.g. jumptables at specific locations in the memory, I just don't know them for the ESP8266 linker. |
@ondabeach Thank you for the hint on fastCRC. For now I use https://github.com/bakercp/CRC32/tree/master/examples/CRC32. Does the job and since the CRC is only calculated once on startup I am fine for the moment... Got to admit I have not measured the time yet :-o |
The first sector of flash (0x0 - 0x1000) is occupied by the bootloader, which is why i assume that there's nothing in the last word of this sector, at the moment (i.e. bootloader size is less than 4092 bytes). ESP8266 linker is just your normal GNU LD from binutils, so normal binutils documentation applies. |
I was not aware the bootloader is flashed every time along with the binary. |
I've just tried that and got a warning:
which makes sense because the linker script does not place this section anywhere in the output file. You can modify the linker script to place this section at some known location. |
Thanks. I'll try on and let you know when I got something usable. |
got something. Short version:
Tested, works. |
long version: use this arduino sketch:
It checks the checksum that has been uploaded along with the program code against a calculated checksum (MD5). When you compile, the linker places a dummy string in the memory. There is no adjustment of linker scripts necessary. The dummy string will be replaced by the real checksum and the region of memory which has been taken into consideration for this calculation.
If you use the script with the binary of the sketch provided above, it outputs:
You can see a list of the memory segments in the binary. If the crc dummy is found in any of them , this will be indicated. If all goes well, the Arduino sketch outputs a simple
What needs some doing is
|
Why do this with esptool though? It already mixes two entirely unrelated features: generation of binaries and uploading. I don't see a reason to use esptool for this when this can be done using e.g. |
I understand what you mean. I thought of the esptool because its already part of the toolchain. This would allow anybody to check the memory just by adding it to the sketch. Defining hooks and and adding python scripts to the toolchain might put off many people. And you do it over and over again if you re-install. dd alone does not work as you still need to calculate the md5- and just for the part of the memory that you can read at run-time. An md5 for the whole binary would not work. You have to sort of disassemble the .bin to find the segments. Furthermore you need to know where in the memory the segments go. They are not necessarily adjacent. Once you know all that you could use dd - or - stick with python as you probably do all the above with it anyway and dd is Linux only. Btw, why is it that I cannot read the bootloader section at run time ? Is it a hardware constraint or does pgm_read_byte() filter that ? |
I got it up and running myself. Anyone who wants to secure their flash contents, please have a look here: |
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 esp8266#4165
* 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.
I do occasionally struggle with failing flash chips and are implementing a CRC32. From 0x400000 to 0x410000-1 which is the SPI flash mapped to the memory map.
That part I got working, however, I need a matching, link-time generated CRC in memory.
Question:
The text was updated successfully, but these errors were encountered: