EmbeddedRelated.com
Forums

Patch fixed strings in .hex file

Started by pozz January 16, 2024
Am 17.01.2024 um 08:45 schrieb pozz:
> Il 16/01/2024 19:35, Hans-Bernhard Bröker ha scritto: >> Am 16.01.2024 um 13:19 schrieb pozz: >> >>> I'm wondering how to detect the exact positions (addresses) of serial >>> numbers to fix. >> >> You do not. >> >> Instead, you set up linker scripts, linker options and/or add >> __attribute(()) to the variables' definitions to _place_ them at a >> predetermined, fixed, known-useful location. > > Do you mean to choose by yourself the exact address of *each* string?
Of each st4ring that needs this kind of post-build treatment? Oh yes, absolutely. The key insight is that these are not just ordinary strings like any other: they're post-build configuration data.
> And where would you put them, at the beginning, in the middle or at the > end of the Flash?
That discussion is what hides behind the term "known-useful", above. Typically such elements end up near pre-existing memory region boundaries, with some additional space reserved near them for future expansion.
> You need to calculate the address of the next string > from the address *and length* of the previous string.
You didn't seriously plan on having the length of this kind of string actually changing willy-nilly, did you? These actually have to be fixed-size arrays, i.e. volatile const char foo[D_LENGTH]; or equivalent.
Il 17/01/2024 17:39, Stefan Reuther ha scritto:
> Am 17.01.2024 um 12:54 schrieb pozz: >> Il 17/01/2024 11:27, David Brown ha scritto: >>> While it is possible to do all this using patching of odd places in >>> your file, using specific locations is often a better choice.  Since >>> you haven't already said "Thanks for the advice - I tried it that way, >>> it worked, and I'm happy" in response to any post, I would say that >>> now is the time to take fixed location solutions seriously. >> >> There are many suggested solutions and I think all of them can be used >> with success. Just for sake of curiosity and studying, I'm exploring all >> of them. >> >> Sincerely I don't *like* solutions where you need to choose a fixed >> location by yourself. Why you should make a job that can be done by the >> linker? > > It's not you vs. the linker. You co-operate. You need to tell the linker > about your chip anyway ("code is from 0x1000 to 0xc000, data is from > 0xc000 to 0xd000"). So you can as well tell it "version stamp is from > 0xcc00 to 0xd000, data only before 0xcc00". > > If you have your identification information in a fixed place, you can, > for example, more easily analyze field returns. It's easy for your field > service has to change something, and it's easy to do software updates > that preserve the identification information. You don't need to figure > out which software build is running on the chip and what the address of > the structure happens to be in that one.
Good point, firmware upgrade. I wasn't thinking about it. If the addresses of post-builds strings weren't fixed over all the versions, it would be more complex for the software that manages the upgrade.
> >>> Now your post-build scripts have a simple fixed address to patch the >>> binaries. >> >> How the post-build script should know the exact address of a certain >> field in the struct? > > By defining the struct in a compatible way. For example.... > >> volatile const struct post_build_data { >>   uint32_t serial_number; >>   uint64_t mac_address; > > ...this is a bad idea, because in most (but probably not all) chips, > uint64_t after uint32_t means there's 32 bits of padding, so if you need > serial-before-mac, you should at least make the padding explicit. There > also might be endian problems. > > Using only char/uint8_t fields gives you a very high chance of identical > structure layout everywhere (`uint8_t mac_address[8]`). > > > Stefan