This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to configure flash and RAM partitions

Hello,

I am trying to partition the RAM and the internal flash of the nRF9160, and I am blocked. 

I began by defining the partitions in the board device tree, based on the examples from the SDK. One of the partitions in flash is labeled "storage",

which I will use for storing application specific data. However when I compiled the code, I got an error saying that the label "storage" does not exist.

Digging through the forum, I found out that I should use the Partition Manager instead of the device tree. So I remove the partition definitions

from the device tree and wrote a pm_static.yml with the partitions I need. However now the firmware crashes immediately on startup.

I am suspecting that Zephyr requires the partitions to be defined in the device tree, even though this particular device tree information is ignored

when the firmware image is build. If this is correct, then I have to keep the partition information in two different places: the device tree and the 

pm_static.yml file. Am I correct ? Because this seems absurd to me.

Quite frankly I am very confused and discouraged with the nrf9160. 

Parents
  • Hi!

    If your application has more than one image (for example including SPM or MCUboot) then you need to use the Partition Manager to partition the memory region. 

    The way to add a static configuration to a multi-image is to define the partitions of the child images in a pm.yml file in every child image (for example MCUboot or SPM). Then when you build the main application with all the child images, the resulting partition configuration can be found in $BUILD_DIR/partitions.yml. Take this file and rename it "pm_static.yml" and place it in the application directory (doc: Configuring static partitions).

    The documentation mentions you can build this pm_static.yml file from scratch, but we really don't recommend doing that. It's much easier to use the one that the build creates for you. 

    Let me know if you have any more questions!

    Best regards,

    Heidi

  • Hello Heidi,

    I was confused by how the NVS sample application works. 

    It seems that "CONFIG_NVS=y" adds the "nvs_storage" flash partition, but I only found out after much head banging. And because the partitions defined in the device tree are ignored, no matter the changes I made to the label or size, nothing would work.

    Thanks for the tip on how to create a pm_static.yml file. I was trying to do it by hand, but going nowhere.

    Regarding the partitions defined in the device tree, I believe they are needed by Zephyr. So, I still need to defined the flash and RAM partitions in the device tree files. Correct ? 

  • Hi!

    As Didrik mentions here, NCS uses the Partition Manager to partition the flash and RAM, and not the device tree.

    Therefore, any devicetree configuration of flash or RAM partitions is ignored by the Partition Manager script.

    This script is used by the build system to properly allocate space for multi-image builds and is thus used for most nRF9160 applications, as all applications using the modem library require SPM as a child image and are therefore multi-image builds.

  • Heidi,

    The problem is that if I remove the partition definitions from the device tree, the code compiles but crashes immediately (hard fault).

    Among the board files is Kconfig.defconfig (which must be present) wich for the nrf9160dk_nrf9160ns board is: 

    # nRF9160 DK NRF9160 board configuration
    
    # Copyright (c) 2018-2020 Nordic Semiconductor ASA
    # SPDX-License-Identifier: Apache-2.0
    
    if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160NS
    
    config BOARD
    	default "nrf9160dk_nrf9160"
    
    # For the secure version of the board the firmware is linked at the beginning
    # of the flash, or into the code-partition defined in DT if it is intended to
    # be loaded by MCUboot. If the secure firmware is to be combined with a non-
    # secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always
    # be restricted to the size of its code partition.
    # For the non-secure version of the board, the firmware
    # must be linked into the code-partition (non-secure) defined in DT, regardless.
    # Apply this configuration below by setting the Kconfig symbols used by
    # the linker according to the information extracted from DT partitions.
    
    # Workaround for not being able to have commas in macro arguments
    DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition
    
    config FLASH_LOAD_SIZE
    	default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION))
    	depends on BOARD_NRF9160DK_NRF9160 && TRUSTED_EXECUTION_SECURE
    
    if BOARD_NRF9160DK_NRF9160NS
    
    config FLASH_LOAD_OFFSET
    	default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION))
    
    config FLASH_LOAD_SIZE
    	default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION))
    
    endif # BOARD_NRF9160DK_NRF9160NS
    
    config BT_WAIT_NOP
    	default BT && $(dt_nodelabel_enabled,nrf52840_reset)
    
    # Workaround for not being able to have commas in macro arguments
    DT_COMPAT_NXP_PCAL6408A := nxp,pcal6408a
    
    config I2C
    	default $(dt_compat_on_bus,$(DT_COMPAT_NXP_PCAL6408A),i2c)
    
    endif # BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160NS

    This is a reference to the device tree partitions: DT_CHOSEN_Z_CODE_PARTITION.

    Or am I reading it wrong ? 

  • Why are you removing the partitions? 

    We don't recommend editing the board directories and the relevant partitions in the devicetree will just be ignored.

  • I am trying to understand how the board definition files are used, because I would like create the definitions for our custom board. And I am using the nrf9160dk_nrf9160 board as a starting point. And if I going to copy existing definitions, at least I would like to understand what I am copying.

    The use of the partition definitions in the board files is very confusing, because:

    1. the definitions are ignored

    2. the definitions cannot be edited out (even though they are ignored)

    So is it correct to say that the partition definitions have to be the same on the partition manager *and* the device tree ? 

  • Hi!

    NelsonGoncalves said:
    So is it correct to say that the partition definitions have to be the same on the partition manager *and* the device tree ? 

     No. When using the Partition Manager, the partitions in the device tree are ignored.

    I don't think that you're actually using the Partition Manager here. Can you confirm that your application is a multi-image build?

    Could you give me some more details on specifically what you're trying to do? 

    pm_static.yaml is only supposed to be used when a product is out in the field and you can't move the partitions anymore. During development, you should always use the dynamic solution. 
Reply
  • Hi!

    NelsonGoncalves said:
    So is it correct to say that the partition definitions have to be the same on the partition manager *and* the device tree ? 

     No. When using the Partition Manager, the partitions in the device tree are ignored.

    I don't think that you're actually using the Partition Manager here. Can you confirm that your application is a multi-image build?

    Could you give me some more details on specifically what you're trying to do? 

    pm_static.yaml is only supposed to be used when a product is out in the field and you can't move the partitions anymore. During development, you should always use the dynamic solution. 
Children
  • "Can you confirm that your application is a multi-image build?"

    Yes, I believe it is a multi-image build. It has the SPM and our own application which uses the LTE modem. No bootloader yet, though. But we will most likely only use an immutable bootloader.

    "Could you give me some more details on specifically what you're trying to do?"

    It started out as an attempt to create a storage space in the internal flash and read/write over it using NVS. I took the NVS sample and tried to adapt it, but failed.

    The rationale for using the NVS storage is that our application (running as non-secure) is required to support the change of symmetric encryption keys during a communication session with a remote client. We cannot store them in the KMU because the application is non-secure, the only options are either to store them in plaintext in the internal flash or encrypted in an external flash.

    The use of NVS seemed simpler and faster than accessing an external flash. Recently one your colleagues suggested here that I could use a customized SPM for accessing secure resources from a non-secure app.

    But even if a customized SPM will solve our key storage problems, I still don't understand why this is needed in the device tree definition:

    chosen {
    zephyr,flash = &flash0;
    zephyr,sram = &sram0_ns;
    zephyr,code-partition = &slot0_ns_partition;
    };

    if the Partition Manager is used and the device tree partitions are ignored. As soon as I remove it, my application crashes immediately.

    EDIT: here are the config and board files I am currently using board_and_config_files.zip

  • This is a somewhat not related issue, but my point is just to make it clear how difficult using the NCS sometimes is:

    Based on the UDP sample (nrf\samples\nrf9160\udp) I changed "prj.conf" to add the modem library to my build.

    Compiled my application *without* any changes, flashed and it immediately crashed. Same code, no changes, crash.

    So I took a look at the flash/ram partitions with "ninja rom_report". Noticed immediately that the RAM partitions changed, and that the section allotted to the non-secure application had changed.

    Could this be the problem ? Probably not because the DTS partitions are ignored, but then again only the RAM partitions changed. After a few hours I finally found that I forgot to copy this config option:

    CONFIG_MAIN_STACK_SIZE=4096

    But why was my code working before, and not now ? This option is not specific to the modem library. Grepping through the NCS source code I did not see any immediate connection to the modem library. The Zephyr doc says this is the stack size for the main thread. So why do I need to set it now and not before ? 

    But the larger problem is that each sample appears to have config options specific to the particular sample application, Zephyr OS and the Nordic libraries. And these options are spread across the DTS (although some parts seem to be ignored but nonetheless needed), Kconfig files and several other .conf , .yml  and .overlay files. Which of these should I copy/modify to my application ? Not possible to know without some trial and error, head banging and searching through this forum.

    Sorry for the long rant, but understand how frustrating working with the NCS can be.

  • Hi!

    I'll just mention this here for future reference and other users on DevZone. 

    When you build a multi-image build (for instance by building an application for the non-secure board which automatically adds the SPM as a child image) the Partition Manager gets enabled implicitly and takes over partitioning. The PM will define all partitions that are needed based on which subsystem are enabled in the application (for example enabling NCS will give you a secure partition) and will also expose a Kconfig to the user to determine the size of this partition. 

    chosen {
    zephyr,flash = &flash0;
    zephyr,sram = &sram0_ns;
    zephyr,code-partition = &slot0_ns_partition;
    };

    This is part of the devicetree bindings and will break the build of deleted, but you can just ignore them. Bindings are not related to the partitioning. 

    With the non-secure and secure regions, there is a way to call secure functions from the non-secure app using secure entry gateway functions.

    If you need to do anything more in Kconfig than simply enabling the modules you need, there might be a bug in the Partition Manager.

    Let me know if there's anything else I can do for you!

    Best regards,

    Heidi

Related