Code relocation to the external flash with Mcuboot

Hello,

I am using edge impulse library to achieve on-device classification. I now want to put the edge impulse related code to the external flash and use XIP function there rather than placing them inside my internal flash. I have learned something from the code relocation sample from NCS and zephyr. I now have my own linker script, modified CMakeList and prj.conf, which I show below. For cmakelist: 

zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_RODATA NOCOPY)
For linker script: 
#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>

MEMORY
{
    /* XIP region for Edge Impulse model code + rodata */
    EXTFLASH (rx) : ORIGIN = 0x10120000, LENGTH = 0x00400000
}
#include <zephyr/arch/arm/cortex_m/scripts/linker.ld>
and for prj.conf: 
CONFIG_CODE_DATA_RELOCATION=y
CONFIG_XIP=y
CONFIG_NORDIC_QSPI_NOR_XIP=y
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_nocopy.ld"
. The build process can show part of the code is indeed placed into our external flash partition. But it is complaining about this: Error: Image size (0x10110be8) + trailer (0x630) exceeds requested size 0xe0000. I suspect this is because the relocated section is still included in the mcuboot binary image. We will need to keep mcuboot because we want to use dfu-util on our host machine for firmware upgrade. Is there a way to solve this issue? 

Parents
  • Hi there,

    Here are the practical ways to do that.

    1. Factory / dev-time: flash QSPI as a second image

    Idea:
    Keep MCUboot + main app in internal flash only. Put the Edge Impulse model / code that lives in external flash into a separate .hex/.bin and flash that directly to QSPI at the fixed XIP address.

    Steps

    1. Define the external flash in devicetree and partition manager

      In app.overlay, make sure the QSPI flash is enabled and marked as external flash:

    &mx25r64 {
        status = "okay";
    };
    
    / {
        chosen {
            nordic,pm-ext-flash = &mx25r64;
        };
    };
    

    (Use the actual node name for the chip on their board.)

    2. Use Zephyr’s code relocation for XIP
    What you already have is basically right:

    zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_TEXT NOCOPY)
    zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_RODATA NOCOPY)
    
    And a custom linker script that puts EXTFLASH_TEXT / EXTFLASH_RODATA at the QSPI address.
    3.Generate a separate image for the QSPI content

    After building, use arm-none-eabi-objcopy (or west build artifacts) to extract only the external-flash sections into a second .hex/.bin:

    # Example: create a secondary hex for QSPI contents
    arm-none-eabi-objcopy \
        -O ihex build/zephyr/zephyr.elf \
        --only-section=.extflash_text \
        --only-section=.extflash_rodata \
        extflash_model.hex
    
    (Section names depend on how EXTFLASH_TEXT/EXTFLASH_RODATA are defined.)
    4.Program both images separately
    • Internal flash (MCUboot + app):

    west flash  # or nrfjprog --program app_mcuboot.hex --chiperase
    

    External QSPI contents (at correct ORIGIN, e.g. 0x10120000):

    nrfjprog --program extflash_model.hex --verify --sectorerase --qspi
    

    Or configure a custom west flash --hex-file extflash_model.hex runner that knows how to talk to QSPI.

    RESULT:

    MCUboot image stays within its partition size, and QSPI holds the model/code at a fixed address. No more Image size (0x10110be8) + trailer ... exceeds requested size because those XIP sections are not counted inside the MCUboot image anymore.

    Use a proper SPLIT image to update via DFU the Image Model , Nordic has QSPI XIP split-image feature. V

    HTH

    GL :-) PJ :v:

Reply
  • Hi there,

    Here are the practical ways to do that.

    1. Factory / dev-time: flash QSPI as a second image

    Idea:
    Keep MCUboot + main app in internal flash only. Put the Edge Impulse model / code that lives in external flash into a separate .hex/.bin and flash that directly to QSPI at the fixed XIP address.

    Steps

    1. Define the external flash in devicetree and partition manager

      In app.overlay, make sure the QSPI flash is enabled and marked as external flash:

    &mx25r64 {
        status = "okay";
    };
    
    / {
        chosen {
            nordic,pm-ext-flash = &mx25r64;
        };
    };
    

    (Use the actual node name for the chip on their board.)

    2. Use Zephyr’s code relocation for XIP
    What you already have is basically right:

    zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_TEXT NOCOPY)
    zephyr_code_relocate(FILES src/feature/gait_analysis.c LOCATION EXTFLASH_RODATA NOCOPY)
    
    And a custom linker script that puts EXTFLASH_TEXT / EXTFLASH_RODATA at the QSPI address.
    3.Generate a separate image for the QSPI content

    After building, use arm-none-eabi-objcopy (or west build artifacts) to extract only the external-flash sections into a second .hex/.bin:

    # Example: create a secondary hex for QSPI contents
    arm-none-eabi-objcopy \
        -O ihex build/zephyr/zephyr.elf \
        --only-section=.extflash_text \
        --only-section=.extflash_rodata \
        extflash_model.hex
    
    (Section names depend on how EXTFLASH_TEXT/EXTFLASH_RODATA are defined.)
    4.Program both images separately
    • Internal flash (MCUboot + app):

    west flash  # or nrfjprog --program app_mcuboot.hex --chiperase
    

    External QSPI contents (at correct ORIGIN, e.g. 0x10120000):

    nrfjprog --program extflash_model.hex --verify --sectorerase --qspi
    

    Or configure a custom west flash --hex-file extflash_model.hex runner that knows how to talk to QSPI.

    RESULT:

    MCUboot image stays within its partition size, and QSPI holds the model/code at a fixed address. No more Image size (0x10110be8) + trailer ... exceeds requested size because those XIP sections are not counted inside the MCUboot image anymore.

    Use a proper SPLIT image to update via DFU the Image Model , Nordic has QSPI XIP split-image feature. V

    HTH

    GL :-) PJ :v:

Children
No Data
Related