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

Writing to a flash when receiving data via BLE

Good health to all!
I am using Ble, I need to flash received packets.
The best way to do this is using sd_flash_write ().
In the sdk_config.h file, I see #define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 4096 for nRF52 (and 1024 for nRF51).
But where can I set the write block size without fstorage? At the moment it is 1024, which I checked empirically. Is this the maximum value? But nrf_nvmc_write_bytes () allows you to write a whole page, all 4096 bytes at a time.
If, when receiving a message, I call the erase and write function, everything will break due to the slow softdevice.
Therefore, I clear all the pages I need for subsequent writing at the very beginning of the program. But in this case, sd_flash_write () does not fire.

My writing algorithm is that each incoming packet carries me 128 bytes, which I accumulate 8 times in an array of 1024 bytes. And every 8th reception of the message I call the sd_flash_write function (app_flash.addr, app_flash.buffer, 1024);
The second reason why I cannot use sd_flash_page_erase () (and this could be called, for example, every 7th reception of a message) is that the function erases 4096 bytes, and I need to prepare a field for 1024 bytes, because these are possibilities softdevice.

What should I do? How can I establish convenient communication with softdevice and record a buffer for receiving Ble messages?

  • Hi Proton, 

    The size argument in sd_flash_write() is actually the number of words, not the number of bytes. So if you use 1024 it means it's 4096 bytes. 

    And we actually have an issue with a write with such size, have a look here: https://devzone.nordicsemi.com/f/nordic-q-a/48830/softdevice-assertion-failed

    I would suggest to keep the number of bytes writing in one chunk to shorter. In our DFU example we use NRF_FSTORAGE_SD_MAX_WRITE_SIZE = 20

    Note that fstorage automatically split the data into multiple chunks if the data is bigger than  NRF_FSTORAGE_SD_MAX_WRITE_SIZE .

  • With the nrf_nvmc_write_bytes () and nrf_nvmc_write_words () functions, I have the right to choose whether to write in words or bytes. softdevice provides no choice?

    I do not use the FSTORAGE functions and the file system, I want to choose where to write bytes myself.

    NRF_FSTORAGE_SD_MAX_WRITE_SIZE will affect the sd_flash_write () write function too ??

  • Hi Proton, 
    No you don't have an option to choose between bytes or words but 32bit word is the smallest unit you can write with the NVMC on the nRF52 anyway. Here is the spec: 
    The NVMC is only able to write 0 to bits in the flash that are erased (set to 1). It cannot rewrite a bit back
    to 1. Only full 32-bit words can be written to flash using the NVMC interface. To write less than 32 bits,
    write the data as a full 32-bit word and set all the bits that should remain unchanged in the word to 1.
    Note that the restriction on the number of writes (nWRITE) still applies in this case

    If you don't use fstorage, you don't have to configure NRF_FSTORAGE_SD_MAX_WRITE_SIZE and can use sd_flash_write () directly, but as it's mentioned in the other case, we have a bug that if you write 1024 words in one call you may have an issue. Try to split it to two writes for example. 

  • You probably don't know how the nrf_nvmc_write_bytes () and nrf_nvmc_write_words () functions work. It would be strange if they performed the same function and both wrote down words. But nrf_nvmc_write_bytes () writes individual bytes. You can verify this by writing "1" in both functions and looking at the memory:
    nrf_nvmc_write_bytes (addr, massss, 1);
    nrf_nvmc_write_words (addr + 40, massss, 1);
    So I can choose whether to write to me in bytes or in words. And it's a pity that softdevice is not that advanced.

Related