Dear Community,
I am quite new in this world, so please be kind :-).
Using Arduino MEGA2560.
I got a task to do arduino sketch where I will check the CRC of the loaded sketch.
So I would like to know, if there is a way how to directly read Flash memory - plase where the sketc is loaded and do CRC from this data.
The result shall be that If I add some line to sketck and load it to the board, the value shall change, if the sketch will be without chenge the number shall stay same.
I tryied to read so many threads but without luck.
I tryied
for (int i = 0; i < 64; i++){
byte b = pgm_read_byte(i);
Serial.print(b,HEX);
}
But this not change if sketch is changed - maybe wrong address I am looking at...
the first many bytes may be interrupt vectors as well as other startup code that doesn't change depending on the sketch
at least one listing i have suggests that main starts at address 0x358 (not sure why i don't see setup and loop)
00000000 T __vectors
00000068 T __trampolines_end
00000068 T __trampolines_start
000000c2 T __ctors_start
000000c4 T __ctors_end
000000c4 T __dtors_end
000000c4 T __dtors_start
000000d0 T __do_clear_bss
000000e0 T __do_global_ctors
000000fe T __bad_interrupt
000002c4 T __vector_16
00000358 T main
00000830 T __tablejump2__
0000083c T _exit
00000840 T _etext
Your simple test for loop probably gives the same result because that particular part of FLASH holds the interrupt vector table (I think!). Unless you use interrupts, it is unlikely to change from one sketch to the next.
The problem you may have is that you would need to determine if the compiled, assembled and linked binary file that gets uploaded to your Arduino occupies contiguous memory locations from $0000 upwards. If your binary file used addresses $0000-$0032 for the vector table but then placed the code starting at address $0100, you would not know this and a simple for loop would included addresses $0033-$00FF in the calculation - which could be any old garbage.
You also would not know the size of the binary file that has been programmed into flash so you wouldn't know where your current sketch ended in memory.
Here is an example I made a while ago. It dumps SRAM, EEPROM and FLASH and gives a reasonably familiar output (if you have worked with hexdump before):
thank to all of you for very good points and summary, I did not expect so fast reaction.
The Dump from jfjlaros works wery good, I just need to somehow do CRC from that stream.
Once I will get there I will try to only do CRC of the flash where is the program.
Do you know how to say to arduino software that before the sketch is loaded all memory for sketches shall be deleted/rewrited?
This will help very much so I do not neet to take care about previous sketches loaded in the procesor.
Thanks a lot again!
This was exactly I was wondering. On some forum thread was writen that only some part is overwriten and the part what is not needed is left untached, so if previous sketch was bigger it shall mess up the process of CRC.
My mistake. I just checked with a couple of different sketches and it appears that the whole of flash isn't erased when a new sketch is uploaded. It looks like only enough pages of flash memory are erased to take the size of the new sketch.
The remaining area(s) of flash contain the remnants of previous sketches.
The OP would likely need to add a step to the build process to calculate the CRC as well as determine the bounds of the flash memory to check the CRC against so that those values could be stored on the chip. That would probably require knowledge of where the linker was placing the various sections and whether there were "holes" in the memory space where previous code remnants would lurk!
You can have the IDE save the output file that gets uploaded to the arduino. That will be in Intel hex format, but for the atmega2560 the flash memory is large enough that it is divided into several pages, making it slightly more complex to calculate the physical addresses the code is stored at.
Do you have any idea how to get some informations where the code is writen? Someone mentioned some linker... is this some way how to deal with this?
I would imagine some code, what is goinf thru memory and a "linker" will say - yes this is a part of a code, or no this not a part of a code - ignore it.
Is here any way?
Or is there some way how to erase the flash complettely - some tool what will leave only bootloader and the res of the memory will be deleted, so the sketch will be always on the same place?
Also I was now going thru some tests and found that If I make some changes in the code the CRC of Flash doesnt change, but CRC of Memory change. How I can know what change is writen to Flash and what part to ProgMemory?
This is a bit confusing
Thanks, this I found, but as markd833 mentioned, the code can be split to more places. So How I can find out where actual code is? I only found that If I dump flash memory the end code is always finished with severals FF bytes. But is all between 0358 and FF part the code?
Also what I found that some parts of sketch are not in flas but in memory directly and there it is even more tricky to find out what is what What I did not I am doing CRC of FLASH from 00000 to the size of the sketch what I got from MemoryFree.h and complette Progmem. This shall be always the same even with multiple downloads, if processed on the same part of the code(in Setup).
I am just not really sure if this is a good way how to do it probably not the clearest one.
Edit: I just go from address 0000 because I also would like to include all settings from processor, so it doesnt hurt to include.
Thanks, I just can not find, if the table you poested is also fit to Mega2560 board. For me it seems too little I see there only 1254 bytes for sketch, what dosnt seems to be right.