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

Write to FLASH inside BLE event

Hello, i have read if not all posts about writing to FLASH while using BLE. But could not find the desirable method.

What i would like to do is to write to flash from characteristic write as it comes. The problem is that sd_flash_write is asynchronous.

So i have to block the device until the write has finished or else the writen data may get corrupted. The only way to know that the sd_flash_write had finished is to wait for NRF_EVT_FLASH_OPERATION_SUCCESS inside sys_evt_handler.

But as some other post mentioned if you call the flash command inside the ble event you don't get the response.

One way to get the response is to store the data somewhere, make a flag which is looked up in the main context. But that means that i am limited to the array size i am storing data in.

Isn't there a way to write directly synchronous from the BLE event or at least to somehow block the further execution untill i get the event?

I'm using nrf52832 with sdk 12.2

Thanks

  • Hi Schef,

    Could you explain a little bit more on:

    • why "writen data may get corrupted" ? Couldn't you store data in another variable until it's finished writing?
    • But as some other post mentioned if you call the flash command inside the ble event you don't get the response. =>Not sure if it's correct. Only when you call the API in a APP_HIGH level then hardfault may occur.
    • Writen data may get corrupted because of a local variable that you want to write at the time of writing will no longer exist. Which means you have to use a buffer which is not suitable for large data transfer.
    • I beleve that the event does not come because of a interrupt priority issue.
    • Sorry I didn't get you at the beginning. Yes, you are correct. This is due to the nature that flash operation will block all CPU activity, so we need to let the softdevice control when to execute flash. And yes, then you will need to wait for NRF_EVT_FLASH_OPERATION_SUCCESS inside sys_evt_handler. And if you put a loop inside the interrupt handler to wait, you will not receive the NRF_EVT_FLASH_OPERATION_SUCCESS event because you still inside the interrupt handler with same priority level.

    • The local variable with large data you need to store, does it have to be in the BLE event handler ? If it's in the APP Low event handler then it's possible to wait for the event there because APP Low has lower priority than the BLE event.

  • I think i have found a solution. I write a word for word in memory so i can check if is written with this simple snippet:

    sd_flash_write(address, &word, 1);
    while (*address != word) {
     nrf_delay_ms(1);
    }
    

    For now that i have tested i think it needed around 2ms for one word or write operation.

  • Well, stay for a long time in a interrupt handler may not the very best solution. CPU will be occupied and any other interrupt handler except for APP HIGH will not be executed. Note that there is a chance that the flash write will not be successful. For example when the softdevice return NRF_EVT_FLASH_OPERATION_ERROR then you may end up in a infinite loop.

    I still don't know what type of data buffer that you have and which event you have to handle the flash writing. If it's not BLE event, but application event (interrupt from peripheral ) then you can set it to APP LOW priority and you should be able to wait for the event instead of writing and waiting word by word.

Related