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!

Parents
  • 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, 

    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 ? 

  • Hi Hung,

    Yes.   I added "flash_test()"  (and the associated event handler) to my code and called it from the logger thread (before it enters the task loop) as shown in the example you provided.   

    The write call from the logger thread performs the write, and logs that it has written to flash.   

    But later in the code, where my call initiates a write to the flash via fds, the write hangs/crashes.

    My calls worked in a "bare-metal" environment, but now fail after porting the application to FreeRTOS.

    I have approximately 16 FreeRTOS tasks running at various priority levels.   None of them consume much CPU power, so the CPU is idle most of the time (by design).     BLE is advertising as expected and scanning for other BLE devices, so the BLE/SoftDevice appears to be working as expected.

    Any insight is appreciated!

    Thanks!

  • Hi Ed,

    We would need to have more data about the crash to find what could be the issue. It would be easier for us if you can provide a minimum example that can reproduce the issue so that we can test here. Could you try to implement the fds write in the HRS FreeRTOS example and check if you get the same error. 


    Or you can try removing other features in your application to make it as similar to the HRS FreeRTOS as possible and still showing the error. 

  • Hi Hung,

    I got the Flash writes to work by reducing the priority of all FreeRTOS tasks to "tskIDLE_PRIORITY" (which is level 0, or the lowest priority), but leaving the priority of the BLE task at the hard-coded level 2 as shown in the example.

    This raises some questions about the needs of the soft device task, etc.    Does it simply have to be the highest priority task?

    Can you shed any light on the requirements of this task?

    Thanks!

  • Hi Ed,

    CktDesigner said:
    I got the Flash writes to work by reducing the priority of all FreeRTOS tasks to "tskIDLE_PRIORITY" (which is level 0, or the lowest priority), but leaving the priority of the BLE task at the hard-coded level 2 as shown in the example.

    If reducing the priorities your application freertos tasks to be lower than the BLE task works for you, then it means that before your change, your tasks are not yielding properly to give a chance for the softdevice task to pull the events. Seems like the application tasks are waiting indefinitely for the flash event to happen without yielding or timeout and the flash event cannot come since the task is not yielding the cpu for the ble event task to pull the softdevice events eventually.

    CktDesigner said:
    This raises some questions about the needs of the soft device task, etc.    Does it simply have to be the highest priority task?

    It does not need to be high priority task as long as other higher priority tasks are behaving and yielding to let the softdevice task pull events.

    CktDesigner said:
    Can you shed any light on the requirements of this task?

    This task is pretty simple. When SD_EVT_IRQHandler is triggered, hinting that there are SD events waiting to be pulled, this softdevice task then just pulls events from the softdevice and call the appropriate event handlers.

Reply
  • Hi Ed,

    CktDesigner said:
    I got the Flash writes to work by reducing the priority of all FreeRTOS tasks to "tskIDLE_PRIORITY" (which is level 0, or the lowest priority), but leaving the priority of the BLE task at the hard-coded level 2 as shown in the example.

    If reducing the priorities your application freertos tasks to be lower than the BLE task works for you, then it means that before your change, your tasks are not yielding properly to give a chance for the softdevice task to pull the events. Seems like the application tasks are waiting indefinitely for the flash event to happen without yielding or timeout and the flash event cannot come since the task is not yielding the cpu for the ble event task to pull the softdevice events eventually.

    CktDesigner said:
    This raises some questions about the needs of the soft device task, etc.    Does it simply have to be the highest priority task?

    It does not need to be high priority task as long as other higher priority tasks are behaving and yielding to let the softdevice task pull events.

    CktDesigner said:
    Can you shed any light on the requirements of this task?

    This task is pretty simple. When SD_EVT_IRQHandler is triggered, hinting that there are SD events waiting to be pulled, this softdevice task then just pulls events from the softdevice and call the appropriate event handlers.

Children
No Data
Related