nRF52840 app not sleeping, SoftDevice seems involved

Hello-

I'm seeing the nRF52840 stay awake when I don't want it to. I'm calling sd_app_evt_wait() every turn through the main loop with SEVONPEND disabled, but it's waking up and falling through.

I'm capturing a histogram of the entire IRQ set, now including the 16 core exceptions, and I found a "smoking gun"- There's almost a 1:1 correspondence between my main loop turns and the core SVCALL_IRQn exception interrupt:

Reading the nRFSDK / SoftDevice headers, it looks like there's a syscall-style interface- when calling from the app into SoftDevice, it issues the SVC with the call id encoded in the instruction.

My hunch about what's happening here is that I've managed to get my app into a state where it's calling into SoftDevice (maybe to test something?) once per main loop turn. That issues an SVC, which sets the Event register. Then, when I call into sd_app_evt_wait() at the end of my loop, it clears the Event register and simply continues. The cycle repeats again, and my app never sleeps.

So, here are some questions I was hoping an expert could give me some advice + insight into please!

1. Is my hypothesis reasonable? Could this be happening? Does SVC set the Event register?

2. Is there anything in the nRFSDK that lets me audit SoftDevice supervisor calls in an automated way? (I think I can build this into my IRQ capture-and-forward shim)

3. Do you have any other ideas or suggestions?

Sorry to file a relatively open-ended question, but time is critical for us so I'd love any thoughts you all might have!

Best,

Charles

Parents
  • Hi Charles, 


    The problem of not having a spinlock loop is that there is a chance that in your functions that is executed before the sd_app_evt_wait() or __WFE, you may trigger an interrupt. 
    This interrupt may wake the chip up immediately after sd_app_evt_wait/WFE is called. If there is a spinlock, the loop continue and the next WFE at the beginning of the next loop will put the device to sleep as the event register is cleared by the WFE in the last loop. 

    If there is no spinlock loop (a loop checking for a app_wakeup flag) the CPU will just jump to your poll functions which may trigger another interrupt. 

    You may run to this issue if you process a UART logging right before the call. There can be an interrupt after you finish transmitting UART and that can wake the chip up. But if you already monitor all interrupts you should be able to spot that. 

  • Hello! Maybe a clue-

    It seems to start happening right around when I disconnect from BLE. I notice that I'm calling sd_ble_gap_disconnect from my event handler, which is called by the nRFSDK observer, which I believe happens from a SWI2 interrupt. I haven't changed any of the interrupt priorities; is it safe to call arbitrary SoftDevice functions from inside an observer?

Reply
  • Hello! Maybe a clue-

    It seems to start happening right around when I disconnect from BLE. I notice that I'm calling sd_ble_gap_disconnect from my event handler, which is called by the nRFSDK observer, which I believe happens from a SWI2 interrupt. I haven't changed any of the interrupt priorities; is it safe to call arbitrary SoftDevice functions from inside an observer?

Children
  • Hi Charles, 
    I don't see a problem calling sd_ble_gap_disconnect () from a BLE event handler. Unless you changed the default priority. 

    For example in most of our examples you can find that we do this ( ble_app_hrs example): 


    You can have a look at this statement here:  

    So as long as you don't call the softdevice API from an interrupt priority at higher level than 4 (at level 2 or 3) you should be fine. 
    By default SWI2 interrupt has interrupt priority level 6. 

Related