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

Cannot call sd_ppi_channel_assign in GPIOTE interrupt context

Hi Expert,

At my nRF51 platform, I opened two GPIOTE users one of which is used to handle an external sensor interrupt. After invoking app_gpiote_user_register(&sensor_gpiote_user_id, low_to_high_bitmask, high_to_low_bitmask, sensor_gpiote_event_handler), I had to add my code logic at sensor_gpiote_event_handler callback, right? But my issue is triggered here when I try to read sensor data via TWI in this callback. Through deep debugging, I found the root casue is from the calling routine of sd_ppi_channel_assign in it. This API would never be returned, so the system hung there...

But if I do some trick to start a timer at sensor_gpiote_event_handler instead, then it will be OK to read sensor data at timer's timeout handler. it's weird.

AFAIK, GPIOTE_Handler shoule have the highest priority for application, are there some clues shared to me? Thanks a lot!

Parents
  • No the system didn't 'hung there' nor did it stop - it went to the Hardfault Handler which then spun in a busy loop forever.

    This is a usual and often-discussed issue, you can't call SVC from a higher priority context than SVC itself has, SVC has priority 2, if you are calling it from GPIOTE at priority 1 then the processor will hardfault, you can't have priority inversion.

    all the sd_* functions use SVC hence you cannot call an sd_* function from anything other than main thread context or APP_LOW_PRIORITY which is 3.

    So either do what you're doing and use a timer, or put GPIOTE down to priority 3 or use the scheduler or set a flag and let main context do the call. Any of those work.

  • The scheduler I mention in this case is Nordic's app_scheduler, it's quite light, all it does is keep a queue of events and the main thread, instead of just running a while(1){__wfe} forever loop just checks after each wfe() whether there's anything to process and processes it. It's a good way to get diverse events back down to main thread context and it's trivial to implement and won't impose hardly any delay.

    There's other options too, bit heavy-handed but you could use the available SWI software interrupt, trigger that and then do your processing in the handler for that, just run that at APP_LOW.

    If keeping GPIOTE at APP_HIGH is important, I'd look at app_scheduler, it's going to be the 10 minute fix.

Reply
  • The scheduler I mention in this case is Nordic's app_scheduler, it's quite light, all it does is keep a queue of events and the main thread, instead of just running a while(1){__wfe} forever loop just checks after each wfe() whether there's anything to process and processes it. It's a good way to get diverse events back down to main thread context and it's trivial to implement and won't impose hardly any delay.

    There's other options too, bit heavy-handed but you could use the available SWI software interrupt, trigger that and then do your processing in the handler for that, just run that at APP_LOW.

    If keeping GPIOTE at APP_HIGH is important, I'd look at app_scheduler, it's going to be the 10 minute fix.

Children
No Data
Related