2021-06-04 09:17 AM
Hello. I have run into a problem in a MCU project I have. I'll explain the situation.
We have a STM32F072RB -based product where we are implementing firmware update functionality. There would be 3 binaries in the MCU:
Our initial plan was to build different application binaries with explicitly different locations, but my customer is kind of wishing to use only one application binary. Therefore binary 1 would have exactly the same contents as binary 2.
Some experts say the way my customer wants the functionality is almost impossible to make. What do you say?
If anyone has any pointers what to google, what documents to read, etc, I'm all ears.
(My current, possibly stupid, idea is to make the single application binary to contain some kind of functionality to determine where it is run from and if it is run from binary 2 beginning from address B, then maybe perform some kind of elegant function/resource remapping so that when the image 2 runs, it does not use image 1 addresses for stuff, but locations in image 2 address space. Is this totally dumb?)
Solved! Go to Solution.
2022-01-16 02:21 PM
2021-06-04 09:43 AM
>>Some experts say the way my customer wants the functionality is almost impossible to make. What do you say?
Address/position Independent code, relocatable vector table, sure.
Thick loader defines the ground rules
2021-06-04 10:58 AM
Thanks, I'll get googling with this.
2021-06-04 03:37 PM
I cannot understand how compiling in position Independent mode alone can be enough.
The code must be written in a specific way, to avoid for example this:
void foo() {.... }
const void (*funcptr)() = foo;
as the const data is placed in the flash. Even if not, the image needs to contain relocations.
-- pa
2021-06-04 06:06 PM
Can't the address of a symbol be computed in a PC relative manner?
The real singular problem is absolute addresses within the executable region that might move. The linker should be able to identify these, and the libraries would need to be built with the same options/expectations.
Some testing and validation would be in order, one could start by having the linker build the images for two different base locations, and then comparing and identifying areas where the build changed.
The loader in this case would need to set aside some RAM to relocate the vector table into,and create an environment where either image code run successfully.
2021-06-05 10:07 AM
Here is a pretty dumb idea - pack both binaries in a single file. There you go. It's a "single binary" now.
Seriously... Compile and run firmware only at address A and use the address B as a backup storage. Before update a bootloader can copy the old firmware to it and in case of necessity copy it back to the address A.
More seriously... The "two applications" approach seems easy only for customer, marketing people and other non-engineers. And the gain is also pretty minor. Compared to other more typical approaches, you only gain one feature - in case of a failed update, a user doesn't have to repeat it until it is successful for the device to be fully usable again. But for most use cases there is no such requirement and the only real requirement is for the device to be able to recover. That means the bootloader must be smart enough to always be able to update the main firmware regardless of the main firmware's current state. With such an approach you also don't need to waste a half of the FLASH memory.
2021-06-05 01:37 PM
Yeah I think least hassle for us with most of the customer constraints honored would be if we had permission to have "regular", different binary for bank 1 and bank 2. And off course the bootloader. And yeah I have thought about bundling both application binaries together. I don't understand what's customer's endgame with single binary, but I promised some research.
2021-06-07 07:52 AM
Ok I started to experiment a bit. I had NUCLEO-F070RB evaluation board and I followed this https://archive.is/GZubE : What I did:
To my utmost surprise the thing worked on the first try.
Of course this does not solve the original problem, but now I can experimentally poke the Application with compile and link options and try to arbitrarily locate it, put stuff to r9, etc. I need of course update the position to Bootloader, but only there if everything goes right. What an exciting endeavor so far!
2021-06-07 03:15 PM
Ok, this is too complicated to gather info about. I'm giving up regarding the project (STM32F072RB).
But I'm still interested to get it working as a hobby (NUCLEO-F070RB).
Remember, there are 2 IDE projects, Bootloader and Application. Keeping this in mind, how should I change linker scripts? Should I add got and or plt sections? Where? Bootloader? Application? Both?
(I tried to follow this partially: https://github.com/rgujju/STM32-projects/tree/master/got_plt but I have a bit different scenario I think and I'm failing)
2021-06-07 03:35 PM
In this case you only want position independent code, executing in place.. Every image will use the same stack, data & bss addresses.
So tinkering with GOT looks like overkill.
--pa