This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Using sd_flash_write in FreeRTOS

I'm using the nRF52832 with FreeRTOS and nRF5_SDK_17.0.2 on a custom board.

I am using a peripheral from a third party that uses Flash storage for certain parameters.   

When I use the driver using "bare-metal" techniques (no OS, just interrupt driven) everything works fine (including writing to the flash).

I'm trying to integrate this driver into FreeRTOS.   I have all of the major functions working in FreeRTOS except for writing Flash via "sd_flash_write".   I can set a breakpoint, step through and see that the call to this function (in the SD) never returns.

My FreeRTOS setup has a task for BLE (as provided in the Nordic port) and "normal" BLE functions work as expected (including reading the Flash).

If I comment out the write to Flash in the third party driver, all the other functionality of the third party driver work as expected (as integrated into FreeRTOS).

But if I enable the call to write the Flash, that call never returns and the system hangs.

I can't post the code, but am hoping that you may have some ideas what is happening.    Is there some other "hook" needed to allow the SD write flash work with FreeRTOS?

Thanks!

  • Hi Ed, 

    We would need to have a look at how you call the sd_flash_write, if it's called in a high priority task or something. But please make sure you call the function after you initialize the softdevice. 

    Please use logging to check if sd_flash_write() returns instead of stepping. It's because stepping through the code after breakpoint will most likely hangs due to softdevice timing issue/crash after the breakpoint. 

    In our example ble_app_hrs_freertos we do use sd_flash_write to store bond information and don't have any issue. Could you have a look ? 

  • Yes, I think I actually used ble_app_hrs_freertos as the "prototype" for the original app development many months ago.  The SD is initialized in a call from main() before any tasks are created and before the FreeRTOS scheduler is called/started.   Other BLE functions (advertising, scanning, etc.) work as expected.

    I put an NRF_LOG statement right after the call to "write_execute" in nrf_fstorage_sd.c (around line 255) and it never gets executed.  (write_execute calls sd_flash_write).   Call stack window simply says "Running".      Does calling sd_flash_write change the task context to the BLE task?

    I even tried to raise the priority of the "BLE" FreeRTOS task.   Once the call to sd_flash_write() occurs, control doesn't return.   If I hit "pause"  on SES, it looks like the code does a "vector catch" as the Disassembly window shows a table of hex numbers and the call window (SES) is blank...

    As I mentioned previously, if the call to write flash is commented out, the code works as expected.  

    Not sure how to proceed in debugging...   

    Thanks!

  • Hi Ed, 

    I just made a simple example that use fstorage to write something to flash running in a task with xTaskCreate. 
    I added a flash_test() function inside logger_thread() and it seems to work fine. 

    Could you please check  and compare to what you did in your code to see if there is any issue ? 

    You just need to replace main.c in ble_app_hrs_freertos with the main.c attached here. I used SDK v17.1 but I assume it would work the same on SDK v17.0.2

    4456.main.zip

  • Hi Hung,

    Thanks for the example.   I checked my code, and I do the same calls.    BLE is initialized and nrf_fstorage_init is called via fds_init.   nrf_fstorage_write is called (via calls through fds) which in turn eventually calls sd_flash_write.

    The initialization (of both BLE and the flash subsystem) is several seconds before the first attempt to write the flash.

    I can read the Flash, but the first write crashes the system.   I can trace things until the call to "sd_flash_write" which sometimes returns 0, but then crashes immediately (most of the time crashes inside the call).

    sd_flash_write is a call into the soft device (in my case S132).   Can you describe what happens there?   Is context changed as part of the call (if so, then the SD handles things, but if not, then I need to provide stack space in the calling process for the SD to operate in)?

    As I mentioned before, this code all works in a "bare-metal" environment, but I'm porting it to FreeRTOS to have more control over what is running (and when) and to have more visibility into turning things on/off for power handling.

    This is the last part to get working!  

    Thanks for any additional insight you can give on debugging this!

  • Hi Ed, 

    What sd_flash_write() does is to queue the write command in the softdevice to wait until the radio is inactive to make a safe flash write operation. So it's the softdevice handle the flash writing and it doesn't happen at the same context when you call the function. 
    However, you need to keep the buffer alive until you receive the call back that the flash operation has been completed. 

    Have you tried to copy my code in your application and execute it in a thread (e.g logger_thread) and check if the sd_flash_write() works ? 

Related