cancel
Showing results for 
Search instead for 
Did you mean: 

Overwrite 4 Bytes at given location in Hex file

Jayant
Associate II

Write 4 Bytes at given location in Hex file (Flash segment)

I tried this:

const uint32_t __attribute__ ((section(".checksumdata"), used)) CodeChecksum = 0x12345678;

Jayant_0-1715865618048.png

 

Jayant_1-1715865693572.png

But when I build code, It doesn't changes only ".checksumdata", but also other intermittent bytes in hex file. How we can resolve this issue?

7 REPLIES 7
Peter BENSCH
ST Employee

Welcome @Jayant, to the community!

A hex file in Intel format consists not only of the data bytes, address and length, but also the checksum of the respective record. So if you change the value of CodeChecksum, the checksum at the end of the record will inevitably change as well.

Have you made a text comparison of such hex files and what exactly is the difference?

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Jayant
Associate II

But when I build code, It doesn't changes only ".checksumdata", but also other intermittent line in hex file. How we can resolve this issue?

const uint32_t __attribute__ ((section(".checksumdata"), used)) CodeChecksum = 0x61d6714;

Expected:

Jayant_1-1715921898381.png

Not expected:

Jayant_0-1715921852126.png

 

 

 

 

 

 

 

 

 

 

Writing any flash device is always done via "pages": you cannot write a single word in a flash device:

It works this way:

  • read a page (the page size depends on the device, e.g. 1K or often 4K)
  • when read to memory: modify the single word (in RAM copy)
  • go to flash and erase the page
  • write the entire page back (from the modified RAM copy)

Flash memories are not RAMs! They are always managed by "pages" (or sectors).

Techn
Senior II

One simple trick is to create a pointer with uint32_t *var1 = (uint32_t *)0x0800FC00;

Then assign the value in your main() function as var1 = 0x12345678;

I don't want to write in runtime, I need to right variable in FLASH memory at the time of building code when creating hex file

A checksum or CRC is typically added in a post-link step.

Often it is placed at the end of the binary data, and not the end of the FLASH memory, as otherwise you need to fill the entire memory space with data or fill bytes to expand it to some maximal size.

The linker should be able to compute the size of the image and place that value within the image, a topic that's be covered multiple times in the last decade.

IAR and other tools can compute and place sums/CRCs, GNU not so much. Perhaps looks at tools like SRECORDS

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Andreas Bolsch
Lead II

As I wanted to have CRC at very end of flash, too, I did the  following: In ld script:

/* CRC32 checksum goes into FLASH at the very end */
.chcksm ORIGIN(FLASH) + LENGTH(FLASH) - 4 :
{
. = ALIGN(4);
KEEP(*(.chcksm))
. = ALIGN(4);
} >FLASH

I.e. no extra memory section required. Then 'objcopy -O srec --gap-fill 0xFF file.elf file.hex'. This will emit the line with the checksum in a fixed 16-byte record. Finally my Makefile gets start and end addresses, calculates the actual checksum incl. the required srecord stuff and injects that into the srecord file:

BEG=$$(nm $< | sed -n -E 's/^(\w+).*_sidata$$/\1/p' | tr [:lower:] [:upper:]); \
END=$$(nm $< | sed -n -E 's/^(\w+).*chcksm$$/\1/p' | tr [:lower:] [:upper:]); \
CHCKSM=$$(./$(BUILD_DIR)/calc_crc32 $@ 0x$${BEG} 0x$${END}); \
sed -i -E "s/^S3..$${END}.*$$/$${CHCKSM}/" $@;

Slightly cumbersome, but once it works, it does work as desired.