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

  • 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?

  • 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. 

  • Update-

    We were doing a lot of work (blocking TWI / SPI transactions etc) inside of our SoftDevice event handler, which happens from inside the SWI2/EGU2 interrupt handler.

    We changed our code to simply enqueue inbound writes to a queue in our handler, and our main loop drains the queue and processes from the thread context, with the rest of our logic.

    I'm not sure exactly what caused the system from sleeping, but it might have been us doing something "bad" from inside the SWI2 interrupt observer callback.

  • Hi Charles, 

    Thanks for the info. It's a good practice to avoid complex activities or blocking functions inside a interrupt handler. But I assume this doesn't explain the interrupt histogram you got. 

    Let us know if you still see the issue occurs. 

Related