Unable to read from Flash using flash_area API even though the bytes are present

I have the following pm_static.yml configuration:

custom_bootloader:
  address: 0x0
  end_address: 0xc000
  placement:
    before:
    - tfm
  region: flash_primary
  size: 0xc000
custom_bootloader_header:
  address: 0xc000
  end_address: 0xc200
  placement:
    before:
    - tfm
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0xc000
  end_address: 0xf2000
  region: flash_primary
  orig_span: &id006
  - tfm
  - tfm_nonsecure
  size: 0xE6000
  span: *id006

and I'm trying to acces this `custom_bootloader_header` from my application code. Here's the relevant snippet:

#include <zephyr/storage/flash_map.h>
#include <flash_map_pm.h>



... {

        const struct flash_area *fa;
        printk("custom_bootloader_header: start=%ul, size=%ul\n", fa->fa_off, fa->fa_size);
        flash_area_open(header_flash_area_id, &fa);
        rc = flash_area_read(fa, 0, tags, 256);
        flash_area_close(fa);
}

prj.conf:

CONFIG_FLASH=y
CONFIG_NVS=y

The read function returns `-22`. I can't really do anything with the devicetree because those partitions are ignored when using a static configuration. Not sure what's going on.

Parents
  • Hi,

    The error indicates that the arguments are invalid, i.e https://docs.nordicsemi.com/bundle/zephyr-apis-latest/page/group_system_errno.html#ga2d1678d5a7cc8ce499643f3b8957def4 

    From int flash_area_open ( uint8_t id, const struct flash_area ** fa ) I assume it's triggered by the first id argument. From https://github.com/nrfconnect/sdk-zephyr/blob/main/tests/subsys/fs/nvs/src/main.c you can see how you can set it up, i.e L:45 shows "err = flash_area_open(TEST_NVS_FLASH_AREA_ID, &fa);", and L:20 "#define TEST_NVS_FLASH_AREA_ID FIXED_PARTITION_ID(TEST_NVS_FLASH_AREA)" where TEST_NVS_FLASH_AREA is the storage_partition 

    Could you state how you declare your "header_flash_area_id"? Is it only in the pm_static.yml? If so, how does the application become aware of this partition existing?

    Another sample you can have a look at is the dfu_target.c from the mesh dfu target sample: https://github.com/nrfconnect/sdk-nrf/blob/4d3956f22283e35721c29eabb8093e493dce5456/samples/bluetooth/mesh/dfu/common/src/dfu_target.c#L47C8-L47C23 

    Kind regards,
    Andreas

  • Hi Andreas,

    Thanks for the quick reply.

    I use FIXED_PARTITION_ID(<label>) to get the id:

      int header_flash_area_id = FIXED_PARTITION_ID(custom_bootloader_header);

    I make my application aware of the YML file in my top-level CMakeLists.txt:

    set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot/pm_static_nrf5340_dk_ns.yml)


    Kind Regards,

    Sameer

  • Noted,

    And the results you get with 

      int header_flash_area_id = PM_CUSTOM_BOOTLOADER_HEADER_ID; results in the same error (-22, invalid argument) when calling flash_area_open(header_flash_area_id, &fa);?

    Kind regards,
    Andreas

  • I just tried doing flash_area_open(PM_CUSTOM_BOOTLOADER_HEADER_ID, &fa);

    still observing the same behavior. Please note that flash_area_open returns 0, I get -22 on flash_area_read.

    I also have some debug printing to see the offset and size of the opened flash area: printk("custom_bootloader_header: start=%ul, size=%ul\n", fa->fa_off, fa->fa_size);

    Here's the output (was the same earlier):

    custom_bootloader_header: start=49152, size=512
    flash_area_read rc=-22
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    The offset should be 0xc000 (49152, correct) and size should be 0x200 (512, correct). Below that I do a read and print the first 16 bytes, that are all zero because it's a calloc'd buffer and the -22 return code from the read.

    Kind regards,

    Sameer

  • Hi,

    Sorry for not getting back to you before now. 

    Sameer Srivastava said:
    Please note that flash_area_open returns 0, I get -22 on flash_area_read.

    Good point. 

    What's the "tags" argument you call flash_area_read() with? Does this cause the invalid argument error?

    Kind regards,
    Andreas

  • Hi,

    No problem at all!

    `tags` is just a uint8_t buffer and that's in line with what flash_area_read expects, so I'm not sure if that would be the cause of the issue.

    From what I understand so far, this behavior (reading zeros from flash) could indicate that the region I'm trying to access is protected (even though it doesn't fall under "tfm"). Is there some way for me to verify that? I don't understand why that region would be protected.

    Regards,

    Sameer

  • Sameer Srivastava said:
    `tags` is just a uint8_t buffer and that's in line with what flash_area_read expects, so I'm not sure if that would be the cause of the issue.

    Sounds to me that it should not be the issue. 

    Sameer Srivastava said:
    From what I understand so far, this behavior (reading zeros from flash) could indicate that the region I'm trying to access is protected (even though it doesn't fall under "tfm"). Is there some way for me to verify that? I don't understand why that region would be protected.

    It could indicate this, yes. I've note found any information that this is the case, but if you're able to set up a different partition where you're able to read from it could indicate that this region is somehow protected. You're sure that there's anything loaded in the custom bootloader header partition?

    "Read data from flash area. Area readout boundaries are asserted before read request. API has the same limitation regard read-block alignment and size as wrapped flash driver." The next item is if the bootloader region is defined as a flash area (partition) in your device's flash map. The function reads data from a specified offset within a given flash area, and this includes any area defined in the devicetree or partition manager, such as the bootloader region. You need to ensure that the bootloader partition is properly defined and accessible via its area ID flash_area_read()

    All of these criterias seems to me that are being met w.r.t how you've set up your partitioning.

    The API works with the Partition Manager. When the Partition Manager is used in your project, flash area information is not taken from the devicetree, but instead from the Partition Manager's configuration (specifically, from pm_config.h). The flash_map_pm.h header acts as the backend for the flash area interface in this case, ensuring that APIs like flash_area_read() operate correctly with partitions defined by the Partition Manager Partition Manager flash map library.

    So, as long as your partition is defined in the Partition Manager, you can use flash_area_read() to access it, which it to my understanding also is. Could you have a look at the Partition Manager flash map library and see if there's anything there that you can use to read the bootloader header?
    Kind regards,
    Andreas
Reply
  • Sameer Srivastava said:
    `tags` is just a uint8_t buffer and that's in line with what flash_area_read expects, so I'm not sure if that would be the cause of the issue.

    Sounds to me that it should not be the issue. 

    Sameer Srivastava said:
    From what I understand so far, this behavior (reading zeros from flash) could indicate that the region I'm trying to access is protected (even though it doesn't fall under "tfm"). Is there some way for me to verify that? I don't understand why that region would be protected.

    It could indicate this, yes. I've note found any information that this is the case, but if you're able to set up a different partition where you're able to read from it could indicate that this region is somehow protected. You're sure that there's anything loaded in the custom bootloader header partition?

    "Read data from flash area. Area readout boundaries are asserted before read request. API has the same limitation regard read-block alignment and size as wrapped flash driver." The next item is if the bootloader region is defined as a flash area (partition) in your device's flash map. The function reads data from a specified offset within a given flash area, and this includes any area defined in the devicetree or partition manager, such as the bootloader region. You need to ensure that the bootloader partition is properly defined and accessible via its area ID flash_area_read()

    All of these criterias seems to me that are being met w.r.t how you've set up your partitioning.

    The API works with the Partition Manager. When the Partition Manager is used in your project, flash area information is not taken from the devicetree, but instead from the Partition Manager's configuration (specifically, from pm_config.h). The flash_map_pm.h header acts as the backend for the flash area interface in this case, ensuring that APIs like flash_area_read() operate correctly with partitions defined by the Partition Manager Partition Manager flash map library.

    So, as long as your partition is defined in the Partition Manager, you can use flash_area_read() to access it, which it to my understanding also is. Could you have a look at the Partition Manager flash map library and see if there's anything there that you can use to read the bootloader header?
    Kind regards,
    Andreas
Children
No Data
Related