Repurposing the Factory Backup area on a P1

I would like to repurpose the factory backup area on a P1 for a set of library functions that take up too much space in the user area. I am not sure how to go about this (structure, compiler & linker setup, link to user app etc.) and would appreciate a few pointers (or a full app-note :-).

Yes I know the factory backup is used for/during system upgrades but those are not going to happen in my case; I am freezing my code on v0.6.3 (0.7 and 0.8 use too much RAM and have no functionality I need).

I’m interested in the replies to this as I had thought the OTA backup area was for that purpose and that the Factory backup area was for a production line programmed backup version of firmware. Is that wrong?

This is the P1 memory map for modular fimware:

Region Start Address End Address Size
System Part 1 0x8020000 0x8060000 256 KB
System Part 2 0x8060000 0x80A0000 256 KB
User Part 0x80A0000 0x80C0000 128 KB
OTA Backup 0x80C0000 0x80E0000 128 KB
Factory Backup 0x80E0000 0x8100000 128 KB

When updating user firmware OTA, the firmware is copied into the OTA Backup slot, then the device restarted. The factory backup slot is untouched.

However, when doing system firmware updates OTA, since each part is 256K, it necessarily requires a 256K temporary location to hold the entire part. Thus both the OTA Backup and Factory Backup slots are used, rendering the Factory Backup really OTA Backup #2, not a factory backup at all.

On the Electron and E series, the system parts are only 128K, and the factory backup slot really is a factory backup slot.

What joost is proposing is definitely possible, with some caveats, but I don’t know anyone who has done it yet.

2 Likes

So I understand that this isn’t everyones biggest concern but I would appreciate a bit of help here. I created a simple user library structure which sits next to the user folder in the form of:
usrlib/inc
usrlib/src
usrlib-dynalib/inc
usrlib-dynalib/src
with build, import and makefile all in the form of what I found in the ‘user’ folder. Calling make in the usrlib, usrlib-dynalib compiles and produces output in build/target/usrlib and build/target/usrlib-dynalib

So far so good, but creating the usrlib-part in ‘the style of’ user-part so it can be loaded onto the device is more challenging for me. As I understand it, the objective is to create a usrlib-part.bin which has the libusrlib-dynalib.a file linked/embedded. Correct?

I created modules/usrlib-part with inc and src folders - my first question deals with linker.ld in this folder. The respective user-part linker.ld contains:

MEMORY
{
    APP_FLASH  (rx)  : ORIGIN = 0x080A0000,     LENGTH = 128K

     /* The SRAM Origin is system_part1_module_ram_end, and extends to
        system_static_ram_start */
    SRAM      (rwx) : ORIGIN = 0x20000300, LENGTH = 0x20000 - 0x300 - 42K
    INCLUDE backup_ram_memory.ld
}

INCLUDE module_system_part1_export.ld
INCLUDE module_system_part2_export.ld

INCLUDE ../../shared/stm32f2xx/user.ld

I take it I should add to the user-part/linker.ld the following:

INCLUDE module_usrlib_part_export.ld


In my usrlib-part/linker.ld I have:

MEMORY
{
    APP_FLASH (rx)  : ORIGIN = 0x080E0000, LENGTH = 128K

    /* todo - SRAM must start also at an offset after what has been reserved for system-module 1 */
    SRAM      (rwx) : ORIGIN = 0x20000000, LENGTH = 768 
    INCLUDE backup_ram_memory.ld
}

INCLUDE module_system_part1_export.ld
INCLUDE module_system_part2_export.ld

INCLUDE ../../shared/stm32f2xx/usrlib.ld

I just borrowed these value from what I saw in system-part1/linker.ld, clearly this is not correct. What exactly should I set SRAM to?

I had to make a ton of changes of the varous makefiles (or created new ones) I have questions about those also but I don’t want to blow up this post too much…

@rickkas7; a bit of your (or team member) time on this would be fantastic!

@joost did you ever figure this out? Would love to be able to use Factory backup (& ideally OTA backup) ranges for the app.

@larse, yes i did. The changes to the make files and general compile environment were quite involved, in particular because i had figure out how it all worked without help from particle.

I need to document the changes but have not done so yet. I.e i have no description for you right now. I guess i should have done that right away because my memory is already getting vague on the details. Being in the middle of a final prototype push, i dont have the time to do the write up right now but if you were to start on this yourself and have questions i can try to help. Sorry for not having an easier to digest answer.