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

Background DFU causes problem on FreeRTOS tasks

Env setup:

nrf52840 on PCA10056, SDK 16.0.0, S140, FreeRTOS, secure bootloader

Description:

I'm trying BLE background DFU in the application.

Had reference iot/background dfu code. But the final impl is porting dfu/ and ble_dfu/ under sdk/components/libraries/bootloader/ to my application.

The code works with nRF Connect and nRF Toolbox, to transfer dfu payload to flash bank1.

My application was based on ble_app_hrs_freertos/

During the porting, I need to enable the app scheduler for nrf_dfu_req_handler.c, to handler incoming payload written to flash asynchronously.

Disable the dfu timer, since the other BLE connection (e.g. heart rate) is still working

FreeRTOS tasks:

1. invoke nrf_sdh_freertos_init to create softdevice task

2. create a dfu task for consuming app scheduler

void dfu_thread(void * arg) {

    UNUSED_PARAMETER(arg);

    while (1) {

        app_sched_execute();

        osDelay(10);

    }

}

3. modify the log task, (disable the freertos idle task, not using the task suspend, wake up way), lower priority

while(1) {

    if (NRF_LOG_PROCESS()) {

        osDelay(1);

    } else {

        nrfx_gpiote_out_toggle(15);  - debug led

        osDelay(50);

    }

}

4. a log task to report alive

while(1) {

     NRF_LOG_DEBUG("alive");

    osDelay(1000);

}

Problem:

  • sometimes running the background dfu, after transfer complete, the system keeps normal running state, with "alive" message
  • sometimes running the background dfu, after transfer complete, the "alive" message won't show periodically.
    • in this situation, the debug led still blinking
    • press a button to print other log(in in_pin_handler), still working
  • sometimes running the background dfu, the transfer stuck, 
    • in this situation, debug led stopped
    • press a button to print other log, not working 
  • don't run background dfu, just BLE connect / read HRM / disconnect, repeat, the system keeps normal state

I suspect there's something wrong when running freertos with the app scheduler.

Wondering if anyone has similar setup, could share your experience and maybe some debug direction?

Parents
  • Monza,

    app scheduler is just a context changing API. app_sched_put will put the context into the queue and app_sched_execute will execute the context. 

    The most important thing is the context in which you are calling app_sched_execute. In your case, you are calling it inside the dfu_thread. This should work fine in terms of API usage. The app_scheduler is not probably the best API in terms of stack usage, you could probably reduce the queue buffers of the app_scheduler if you think that fits your design. 

    Second, we have not tested the usage of FreeRTOS and app_scheduler. app_scheduler is designed for someone who does not have the fancy features of the FreeRTOS. Inside FreeRTOS, normally you communicate between tasks using inter task communications like message queues or notifications. These inter-task communications are very stack friendly and use smaller stack for inter-task communication only as compared to app_scheduler.

    Lastly, what you are doing is something we have not tested, that said, it should work. the stack overflow problem is something understandable, please increase the stack size more, to get around the problem. You could phase out app_scheduler and try to port it to use FreeRTOS message queues instead.

Reply
  • Monza,

    app scheduler is just a context changing API. app_sched_put will put the context into the queue and app_sched_execute will execute the context. 

    The most important thing is the context in which you are calling app_sched_execute. In your case, you are calling it inside the dfu_thread. This should work fine in terms of API usage. The app_scheduler is not probably the best API in terms of stack usage, you could probably reduce the queue buffers of the app_scheduler if you think that fits your design. 

    Second, we have not tested the usage of FreeRTOS and app_scheduler. app_scheduler is designed for someone who does not have the fancy features of the FreeRTOS. Inside FreeRTOS, normally you communicate between tasks using inter task communications like message queues or notifications. These inter-task communications are very stack friendly and use smaller stack for inter-task communication only as compared to app_scheduler.

    Lastly, what you are doing is something we have not tested, that said, it should work. the stack overflow problem is something understandable, please increase the stack size more, to get around the problem. You could phase out app_scheduler and try to port it to use FreeRTOS message queues instead.

Children
No Data
Related