Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

problem on SoftDevice V6 scan_start/stop

I have problem on SoftDevice V6.0.0(nrf52832) scan_start/stop.

modified ble_app_blinky_c(ble_central)
1. app_timer add (20ms cyclic)
2. app_timer handler, run sd_ble_gap_scan_start() or sd_ble_gap_scan_stop() Alternately
   start->stop->start->stop cyclic
3. if after sd_ble_gap_scan_start() run, ADVERTISE_REPORT is received.
4. if after sd_ble_gap_scan_stop() run, ADVERTISE_REPORT is not received.

But Rarecase,
When after sd_ble_gap_scan_stop(), ADVERTISE_REPORT is received.

Is sd_ble_gap_scan_stop() not stop scanning Immediately?

  • This code is simplified code.
    The ultimate goal is that implement for my proprietary mesh library.

    It repeatedly transmits and receives irregularly.

    Scanning is stopped, when only transmit packet is exist.

    What I would like to know is to release the buffer that SoftDevice passed in scan_start.

    Since you may notice advertise_report after scan_stop is executed or it may not be notified, we can not judge this.

  • Hi,

    I have had a look at the code example. The perceived out-of-order advertising report can be explained by the use of interrupts. While the report is always received by the SoftDevice before scanning is stopped, the report event is sometimes handled after scanning has been stopped.

    Since sec_req_timeout_handler() is running in same interrupt priority as SoftDevice events (both priority 7), you may sometimes see the following scenario:

    1. sec_req_timeout_handler() starts.
    2. SoftDevice preempts sec_req_timeout_handler() due to incoming advertisement, and generates an event containing the advertising report.
    3. sec_req_timeout_handler() continues. It stops scanning, sets s_is_scanning to false, and returns.
    4. on_adv_report() starts. It processes the event from step 2.

    As you can see, while the advertisement was received before the call to sd_ble_gap_scan_stop(), its event was handled afterwards.

    For testing I changed the priority level of SoftDevice envents to 6. With that setting, s_error_count stays at 0.

    Please note that setting the interrupt level of SoftDevice event interrupts equal to that of peripheral interrupts is a workaround for avoiding preemption of peripheral interrupts. You find it as swi_interrupt_priority_workaround() and it is called inside nrf_sdh_enable_request() in nrf_sdh.c. If you disable this workaround (as I did for testing) you may experience trouble with peripherals because the interrupts gets preempted by the application's SoftDevice event handling.

    What all of this means is that the SoftDevice only returns advertising reports if scan is active. If you see advertising reports after scan is disabled, it is because of the way events and interrupts are handled in your application. What you see is SoftDevice events that were generated earlier but that has not yet been run because they were blocked by other interrupts.

    Regards,
    Terje

  • OK thanks.

    But, my real application is,
    FreeRTOS based.
    sd_ble_gap_scan_stop() and nrf_sdh_evts_poll() is called by same task.

    simply code is follow,
    ...
    buffer = malloc(...);
    sd_ble_gap_scan_start(buffer);
    for (;;) {
     waitForEvent();
     ...                         <- advertise receive(A)
     if ( stop_event ) {
       sd_ble_gap_scan_stop();
     ...     (free(buffer);)                    <- I want to free buffer.
     }
     nrf_sdh_evts_poll();
      -> nrf_sdh_ble_evts_poll()
       -> sd_ble_evt_get()
       *** get advertise_report in buffer ***
    }

    If (A) is receive, sd_ble_evt_get() return (A)advertise.
    If (A) is not receive, sd_ble_evt_get() not return any advertise.

    I want to free buffer after sd_ble_gap_scan_stop().
    but I do not know whether to be return advertise-report by sd_ble_evt_get().
    If sd_ble_evt_get() is return advertise-report, buffer free operation is buggy.

    I want to know whether exist advertise-report on buffer, before do free buffer.

  • Hi,

    Like Terje showed you on a standalone application, you had a issue with interrupt priorities.

    Similarly in FreeRTOS, it seems like you might have issue with priority selection with the tasks. In FreeRTOS higher number with priority means higher priority (with interrupt handlers, lower priority number means higher priority. Yes, it is confusing, but please read the lines few times and you will get it, if you already did not knew.

    Softdevce task will always check in a loop to see if there are any events that it needs to pull. But this task will be masked by any other higher priority tasks. So if it is important for your application to process softdevice events as and when they happen, then you should increase the priority of the softdevice compared to other tasks.

  • No.

    I don't use softdevice_task.(without nrf_sdh_freertos.c).

    sd_ble_gap_scan_start()/sd_ble_gap_scan_stop()/nrf_sdh_evts_poll() is called on same task(my original task).
    It's not preempt.(in order execute.)

    I consider,
    SoftDevice is not release buffer when call sd_ble_gap_scan_stop().

    It's BUG?

Related