This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

VMC Volatile memory controller

I would like to set memory retention for system off with memory address and size of some retained struct. System off example has this for NRF52, but I'm not able to find clear documentation for nRF5340.
Header hal/nrf_vmc.h has API for this. Function nrf_vmc_ram_block_retention_set takes NRF_VMC_S/NRF_VMC_NS, block and nrf_vmc_retention_t with 4 values.
Documentation at https://infocenter.nordicsemi.com/topic/ps_nrf5340/vmc.html?cp=3_0_0_6_39 has16 retention bits for each POWER register. Memory page https://infocenter.nordicsemi.com/topic/ps_nrf5340/chapters/soc_overview/doc/soc_overview.html?cp=3_0_0_2_1#memory do not state how many ram sections there is for each block.
So how do I calculate and set correct register and correct bit to retain wanted memory area?
Parents Reply Children
  • Finally got this working. Required rather extensive study of how things are built and linked. I was hoping to be able to patch bootloader without touching SDK directories, but did not find a way. If there is nicer way to achieve the same suggestions are welcome.

    Mcuboot Modifications

    At ncs/v1.7.0/bootloader/mcuboot

    To the end of CMakeLists.txt:

    zephyr_library_sources(
    ${CMAKE_CURRENT_SOURCE_DIR}/boot_keep_out.c
    )
    zephyr_linker_sources(SECTIONS boot_keep_out.ld)

    New file boot_keep_out.c:

    #include <stdint.h>

    /* Reserve one memory section for retainable ram across boots */
    #define BOOT_LOADER_KEEP_OUT_REGION_SIZE 0x3000
    __attribute__((section(".boot_loader_keep_out")))
    uint8_t boot_loader_keep_out_ram[BOOT_LOADER_KEEP_OUT_REGION_SIZE];

    New file boot_keep_out.ld:

    SECTION_PROLOGUE (boot_loader_keep_out, 0x2006A000 (NOLOAD),)
    {
    KEEP(*(SORT_BY_NAME(".boot_loader_keep_out*")))
    }

    Application Modifications

    To app CMakeLists.txt:

    set(PM_STATIC_YML_FILE "${CMAKE_CURRENT_SOURCE_DIR}/pm_static.yml")
    zephyr_linker_sources(SECTIONS src/boot_keep_out.ld)
    To pm_static.yml file:
    # Reserve area from RAM to be retained by boot through modified mcuboot
    sram_primary:
    address: 0x20000000
    end_address: 0x2006a000
    region: sram_primary
    size: 0x6a000

    retained_sram:
    address: 0x2006a000
    end_address: 0x2006e000
    placement:
    before:
    - pcd_sram
    after:
    - sram_primary
    region: retained_sram
    size: 0x3000
    C file with retained data:
    __in_section_unique(boot_loader_keep_out) struct retained_data retained;
    src/boot_keep_out.ld
    SECTION_PROLOGUE (boot_loader_keep_out, 0x2006A000 (NOLOAD),)
    {
    KEEP(*(SORT_BY_NAME(".boot_loader_keep_out*")))
    }

    Block Calculation Hints

    #define SRAM_BEGIN (uintptr_t)DT_REG_ADDR(DT_NODELABEL(sram0))
    #define SRAM_END (SRAM_BEGIN + (uintptr_t)DT_REG_SIZE(DT_NODELABEL(sram0)))
    /* Number of blocks */
    #define BLOCK_COUNT 8
    /* Sections / block */
    #define SECTIONS_PER_BLOCK 16
    /* Size of a controllable RAM section in the small blocks */
    #define SECTION_SIZE 4096

    NRF_VMC_S->RAM[block].POWERSET = 1LU << (VMC_RAM_POWER_S0RETENTION_Pos + section);
    volatile uint32_t dummy = NRF_VMC_S->RAM[block].POWERSET;
    ARG_UNUSED(dummy);
    - Arto
Related