Tips for reducing ROM size. (NCS 2.7, nrf52840

NCS 2.7.0
NRF52840
Major subsystems and drivers used: littlefs, nvs, bluetooth, nanopb, spi, spi_nor, i2c, logging, flash_map, multithreading

I'm finding the built image to be 486 KB after size optimization (-Os). The image includes a 130 KB firmware for an external component. That leaves the application size as 366 KB, which seems rather large. In addition, the image is expected to grow as motion algorithms are added.

Looking at the memory report some of the largest items are
Nordic Proprietary Libraries 76.4 KB
bluetooth 47 KB + net 2 KB
Hidden 43.48 KB
No paths 38.2 KB
littlefs 16.8 KB
nanopb 5.7 KB
logging 4.27 KB
nvs 2.9 KB

I'm working with NRF52840 which has a 1MB capacity. I want to have mcuboot with DFU so at least 32KB (?) would be allocated for mcuboot, I want to reserve at least 12KB for NVS. The space available for 2 slots is therefore limited to 980KB or 490 KB max image size.

Is there any way to reduce the size of "Nordic Proprietary Libraries" ?
Is there any way to reduce the size of bluetooth?
What is going on with "Hidden" and "No path" items, why aren't they combined with their original source file?

I'm thinking my best path forward might be to use sysbuild to add a separate section for the external component's firmware. That would make the regions
32 KB mcuboot
132 KB external firmware
12 KB NVS
420 KB application
4 KB swap move buffer
420 KB update slot

With the NRF SDK 5 architecture the images were divided into the bootloader, softdevice (bluetooth, nordic proprietary libraries, etc) and application which made the updatable components smaller. Now with these monolithic images, much more space needs to be reserved for the update slot, effectively making the usable application size much smaller. Basically at this point the application that we previously built on nrf52832 won't even fit in nrf52840 with twice as much flash!

Parents
  • Hello, and sorry for the late reply. 

    We have seen requests for separating out the softdevice like we had in the nRF5 SDK, but unfortunately, we currently have no solution for that. 

    One alternative, that we also use on our DKs, is to have an external flash chip, that you can use as the update slot. That frees up a lot of place for your application. 

    Best regards,

    Edvin

Reply
  • Hello, and sorry for the late reply. 

    We have seen requests for separating out the softdevice like we had in the nRF5 SDK, but unfortunately, we currently have no solution for that. 

    One alternative, that we also use on our DKs, is to have an external flash chip, that you can use as the update slot. That frees up a lot of place for your application. 

    Best regards,

    Edvin

Children
  • Can you explain why the "Nordic Proprietary Libraries"  is so large?

    Is there any tutorial or example on something like an additional updatable region for the external firmware?

    What is the source of "Hidden" and "No path"  ?

    Using our external flash for image update is an option, but it will require we reduce the capacity available to the application. 

    Its pretty sad that we went to a chip with 2x the internal flash capacity and because of Zephyr we will still end up making a product that is less capable than the previous generation.  

    My clients will be really disappointed, the expectation I set was that Zephyr would be equal to or superior to the legacy libraries.  

  • I made some progress today.  I'm now able to place the external firmware image into a dedicated region and create a primary application firmware region and a secondary region for updates.

    Memory region         Used Size  Region Size  %age Used
               FLASH:      364580 B       407 KB     87.48%
                 RAM:      135230 B     259840 B     52.04%
              ext_fw:      132456 B     142848 B     92.73%
          app_noinit:          0 GB         1 KB      0.00%
                 rtt:          0 GB       1280 B      0.00%
            IDT_LIST:          0 GB        32 KB      0.00%

    I setup my pm_static.yml as follows:

    ext_fw:
      address: 0xc200
      end_address: 0x2F000
      region: flash_primary
      size: 0x22200
    app:
      address: 0x2F000
      end_address: 0x94000
      region: flash_primary
      size: 0x65000
    mcuboot:
      address: 0x0
      end_address: 0xc000
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xc000
    mcuboot_pad:
      address: 0xc000
      end_address: 0xc200
      placement:
        align:
          start: 0x1000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0xc000
      end_address: 0x94000
      orig_span: &id001
      - mcuboot_pad
      - ext_fw
      - app
      region: flash_primary
      size: 0x88000
      span: *id001
    mcuboot_primary_app:
      address: 0xc200
      orig_span: &id002
      - ext_fw
      - app
      region: flash_primary
      size: 0x85E00
      span: *id002
    mcuboot_secondary:
      address: 0x94000
      end_address: 0xfa000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x66000
    nvs_storage:
      address: 0xfa000
      end_address: 0x100000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x6000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    ffs_partition:
       address: 0x0
       end_address: 0x800000
       device: DT_NODELABEL(nor_flash)
       region: external_flash
       size: 0x1000000
    

    My next steps that I need help with are reducing the large size of the application.. I don't understand why so much space is taken up by Nordic's proprietary library and the other hidden/no path nodes.

    Also I need to figure out how to configure mcuboot to be able to update the ext_fw region.

    How does mcuboot figure out which region should be updated?

    How do I build an image for updating the ext_fw image?  

    For the ext_fw I will have 2 variables, image_size and image_data.  I need to make sure these are placed at a fixed location in memory.  

    Is there a way I can place these at a fixed location inside of the ext_fw memory_region or do I need to define additional sub partitions that ext_fw spans?

Related