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.

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