Hello,
I wish to exchange variables (16 bytes) between bootloader and application in RAM.
What i have to modify please ?
Both LD file ?
Thank you
Hello,
I wish to exchange variables (16 bytes) between bootloader and application in RAM.
What i have to modify please ?
Both LD file ?
Thank you
Hi,
There are three options:
1) using SVC interface
Either use the Buttonless DFU as an example of using SuperVisor Calls to exchange data between app and bootloader. This would require storage in the Bootloader Settings page which has automatic deletion available when you go back to the application
This implementation is however too complex to write anything about in this answer and it may have some security considerations since you need to update the format of the bootloader settings page to do so.
2) using a named section
The alternative method is just allocating a page to use for data exchange and use a named section to refer to this from code.
Edit linker script for main app and bootloader
MEMORY
{
FLASH (rx) : ORIGIN = 0x78000, LENGTH = 0x6000
RAM (rwx) : ORIGIN = 0x200057b8, LENGTH = 0xa848
uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
dfu_exchange_page(r) : ORIGIN = 0x00067000, LENGTH = 0x1000 // Add this and set to what page to use
uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
}
Add this in linker script sections
SECTIONS
{
.dfu_exchange_page(NOLOAD) :
{
PROVIDE(__start_ dfu_exchange_page = .);
KEEP(*(SORT(.dfu_exchange_page *)))
PROVIDE(__end_dfu_exchange_page = .);
} > dfu_exchange_page
}
Create a structure type
typedef struct
{
uint32_t version; // Ensure you aren’t handling illegal version
uint32_t crc; // CRC of the rest of the structure to ensure to not act on invalid data
uint32_t some_shared_data;
uint32_t some_other_shared_data;
} dfu_exchange_data_t;
Create an instance of this type in the named section in both projects, set it to used to ensure that it is not optimized away
dfu_exchange_data_t m_dfu_exchange
__attribute__((section(".bootloader_settings_page")))
__attribute__((used));
Use Flash API to write/erase from app/bootloader (don’t know if you need to go both ways)
Notes:
3) Using an absolute address – The simplest, brute force method
As long as you have a structure type known to both bootloader and application it is also a possibility to skip the linker scripts altogether and just make an absolute address into a structure type
typedef struct
{
uint32_t version; // Ensure you aren’t handling illegal version
uint32_t crc; // CRC of the rest of the structure to ensure to not act on invalid data
uint32_t some_shared_data;
uint32_t some_other_shared_data;
} dfu_exchange_data_t;
dfu_exchange_data_t * p_dfu_exchange = (dfu_exchange_data_t*)0x67000;
Note: This is the simplest one but it will not be protected against the code growing into this area. You don’t have any assurances what will be in this page so you my end up erasing your code if you aren’t keeping track of what is at the address you are casting (and potentially are erasing). Method 2 is much safer in that regard.
Ketil
Thank you for your response.
Your proposal works in flash right ? Do you have any equivalent in RAM please ? (i will be limited by the number of flash cycle during product life)
Hi,
Yes, these suggestions are for Flash memory. You can use option 3 with a named section of an absolute address that work for RAM with some additional modification.
// Example code
RAM (rwx) : ORIGIN = 0x200057b8, LENGTH = 0xa848 // before
RAM (rwx) : ORIGIN = 0x200057b8, LENGTH = 0x9848 // after
Set the section to use RAM retention according to the information about the RAM[7].POWERSET register. See POWER_RAM_POWERSET_S1RETENTION_Msk.
NRF_POWER->RAM[7].POWERSET = POWER_RAM_POWERSET_S1RETENTION_Msk;
The reason for reserving the top-page is that the stack is placed on the highest address in the memory layout in GCC. If this is reserved (not used) in both app and bootloader there will be no risk of invalid data being written to that location. This will however make 1 page of RAM unavailable in the system.
Note that you will not have absolute assurances on the content in cases of power failures. This might be an issue if your bootloader needs to do multiple iterations of updates before the full firmware update process is finished (e.g. updating SoftDevice+Bootloader and then app). This is the reason why the buttonless DFU uses flash to store peer-data.. If we lost power during the firmware upgrade (which will reboot multiple times) we are never put in a bricked scenario (where the peer data is unavailable). You need to consider this with regards to your FW update process.
Ketil
Thank you, i will try that asap.