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

SD BLE Event priority and task management

Currently I have a few characteristics which are Authorized Read and Writes. Upon detected of the Authorization from the Central I trigger a few events such as:

  1. Measure Temp
  2. Measure Battery
  3. Start/Stop app_timers
  4. Blink LED
  5. Start PWM
  6. Start Timer and GPIOTE sd_nvic_SetPriority(TIMER2_IRQn, NRF_APP_PRIORITY_LOW);
  7. sd_ble_gap_rssi_start()
  8. sd_ble_gatts_value_set()
  9. Save to Flash

...etc

In cases like reading Temp or Battery, these call sd_ functions. So my question is, does this violate the proper IRQ Priority sequencing? Since I initialize the SOFTDEVICE_HANDLER_INIT with scheduler param = true I always assumed this meant BLE events are now moved automatically to scheduler context and thus I didn't have an issue called any sd_ functions from these events. Could someone provide some clarity on this please? Thank you

I ask because in the field some testers have seen their device basically brick. Power Reset's do not bring it back to life. They have to physically trigger the Reset pin in order to get the Device working again.

-DC

Parents
  • What do you mean 'violate the proper IRQ priority sequencing'? You can't violate it, the ARM processor will only process the highest priority interrupt outstanding at the time.

    The rule for calling sd_ functions is trivially simple, you can call sd_ functions from any priority level from thread up to but not including the interrupt priority set for the SVC interrupt (priority of which is in the softdevice spec) but calling it from any higher priority from that will result in a hardfault. That's the whole rule, doesn't matter if you are calling sd_ functions from an interrupt handler, indirectly from an interrupt handler by way of one of the device driver modules like app_timer or from code responding to a BLE event either in the SWI2 handler directly or after the event has been moved to thread context by the scheduler.

    You'd probably find out rather quickly during development if you called a sd_ function from the wrong context, as interrupt priorities aren't random and changeable, so you probably aren't.

    Using the scheduler is fine, unless of course you run out of queue space and then either end up in an error handler or miss events ... all depending on how you handle running out of queue space.

    Since a pin reset is a subset of a power on reset it's rather hard to suggest how power cycling the device would not recover it when a pin reset would; when you power them up they start fresh from the reset handler, they don't remember where they were locked up last time and go right back there. You'll have to get one of the testers to send the device back in its non-functional state so you can put a debugger on it, power it up, and find out what it's doing in that case.

Reply
  • What do you mean 'violate the proper IRQ priority sequencing'? You can't violate it, the ARM processor will only process the highest priority interrupt outstanding at the time.

    The rule for calling sd_ functions is trivially simple, you can call sd_ functions from any priority level from thread up to but not including the interrupt priority set for the SVC interrupt (priority of which is in the softdevice spec) but calling it from any higher priority from that will result in a hardfault. That's the whole rule, doesn't matter if you are calling sd_ functions from an interrupt handler, indirectly from an interrupt handler by way of one of the device driver modules like app_timer or from code responding to a BLE event either in the SWI2 handler directly or after the event has been moved to thread context by the scheduler.

    You'd probably find out rather quickly during development if you called a sd_ function from the wrong context, as interrupt priorities aren't random and changeable, so you probably aren't.

    Using the scheduler is fine, unless of course you run out of queue space and then either end up in an error handler or miss events ... all depending on how you handle running out of queue space.

    Since a pin reset is a subset of a power on reset it's rather hard to suggest how power cycling the device would not recover it when a pin reset would; when you power them up they start fresh from the reset handler, they don't remember where they were locked up last time and go right back there. You'll have to get one of the testers to send the device back in its non-functional state so you can put a debugger on it, power it up, and find out what it's doing in that case.

Children
  • Hi RK,

    I meant in terms of causing hardfaults with calling an sd_ function on a BLE event. Or how within a ADC_IRQHandler() @ NRF_APP_PRIORITY_LOW theres a call to sd_ble_gatts_value_set()

    I do use the scheduler for everything including, app_timer, SOFTDEVICE_HANDLER_INIT, button. I current do not have method for handling running out of Scheduler Queue space other than simply resetting the system on detection of any error via APP_ERROR_CHECK(err_code) and with an sd_nvic_SystemReset() call.

    I have received a few units back which are bricked. Applying power does nothing, but as soon as I connect the programming pins the boards come to life.

    -DC

  • I'm pretty hard pressed to come up with a rational reason that a functioning board would do something different on a power reset than on a pin reset and even more so just because a debugger is connected. Remote unlikely possibilities are reset pin somehow tied low on powerup which actually bouncing it or connecting a debugger (same pin) fixes or some startup code which looks at the reset reason register on reset and heads into a loop somewhere, it's possible then that a pin reset which changed that register or a debugger connection, which often does a soft reset, might cause the code to take a different path.

    Or some race condition, either hardware or software which catches out a board powering up, but is stable if a board is reset.

    None of those seem very likely however do they.

  • "Or how within a ADC_IRQHandler() @ NRF_APP_PRIORITY_LOW theres a call to sd_ble_gatts_value_set()".

    Just apply the rule, is NRF_APP_PRIORITY_LOW lower than the SVC handler priority (the answer is yes) so it's fine, you can call the sd_ functions from that IRQ context, you can do it all day long as often as you like.

  • I guess conversely, calling an sd_ function from a BLE event handler? Does this mean call on a BLE event app_timer_start() violates this?

  • That question doesn't make sense, are you asking about BLE event handlers or app_timers, which are two entirely different things. And app_timer_start() is a function you call, not a function you write which calls other things.

    Either way the answer continues to be the same, if you are running in any context less than the priority of the SVC handler, you can call sd_ functions. If you are running at or above that priority, you cannot. You don't need to enumerate every possible scenario, that's the entire rule, there is no more to it than that.

Related