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 ? 

  • 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. 
  • "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.

Reply
  • 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.

Children
  • 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