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

fstorage page info

I am attempting to integrate examples/peripheral/flash_fstorage into my project (SDK 14.1.0).

When calling nrf_fstorage_write I get NRF_ERROR_INVALID_LENGTH in response. I assume because I am only trying to write 20 bytes not ~2K. However, for some reason the example can write m_hello_world which is only a handful of bytes. Additionally, a minimum erase size of 536MiB seems too large to be correct. Diffing the example sdk_config.h with the default didn't reveal anything interesting I could change.

nrf5_flash_end_addr_get returns 1048576 (dec?) AKA 0x10000.

print_flash_info displays the following:

erase unit: 536871936 bytes

program unit: 2277 bytes

Any help on why the minimums are so large would be appreciated. Thanks.

  • The program unit should be the word size, which is 4 bytes. The length has to be a multiple of 4 bytes, like the length of m_hello_world.

    Edit 29.11.2017:

    This is a bug. The fix is (as you figured out) to put p_fs->p_flash_info = &m_flash_info; before the if in the init function of nrf_fstorage_sd.c

    This will be fixed in the next SDK release.

  • I tried switching the length to be a multiple of 4. In my test I am using "nrf_fstorage_write(&fstorage, 0x100000, data, 24, NULL)" and I still get ERROR 9 [NRF_ERROR_INVALID_LENGTH]. According to the 14.0 migration guide the length should be in bytes, thus I am doing 24.

    As far as I know the program unit (2277 bytes) retrieved from p_flash_info is read only and cannot be changed. Attempting to set it makes gcc say "error: assignment of member 'program_unit' in read-only object". How would I lower the program unit to be 4 bytes and not 2k?

    I am using &nrf_fstorage_sd in my nrf_fstorage_init line. I am using the s140 soft device with ble in other parts of my code base.

  • I did some more digging and it turns out that p_flash_info is 0x00000000 and so program_unit is some "random" value. I see that it should be set to 4 in nrf_fstorage_sd.c which I am including in my build system.

    Edit: with some logging it seems that the init function is being called twice (once for peer_manager, and once for my code?). However in the second call the if !m_flags.initialized branch is not taken and thus p_flash_info is not set (nrf_fstorage_sd.c:380). This seems incorrect to me. I was under the impression multiple fstorage instances could be constructed and used in different application modules.

  • It should be possible to call nrf_fstorage_init() for every instance you want, but how exactly have you defined your instance? It sounds like you have some undefined values of nrf_fstorage_t?

  • Upon calling nrf_fstorage_init() a second time I get undefined values.

    Moving the "p_fs->p_flash_info = &m_flash_info;" line in the init function of nrf_fstorage_sd.c above the if statement seems to have fixed my issue. This prevents p_flash_info from being uninitalized on subsequent calls to nrf_fstorage_init. I have left the NRF_ATFIFO_INIT line inside the if block. Am I doing something incorrect or is this a bug in the supplied library code? I'd appreciate you guys looking into it. Thanks.

Related