interrupt latency

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
joki_2146851
Level 3
Level 3
5 likes given First like received First like given

I'm trying to use the interrupt from GPIO to trigger a digitization on rising edge.  First of all, what is the latency of the rising edge, and is there a time hysteresis, and if there is can I set it to be minimal, also is there some onboard checking of this to make sure it was high for some period of time so I can bypass this.

I have wired a 10us pulser to the sw1 input (replacing the sw1 input) which I was able to get working manually and write to the uart port. What I don't know is how the system responds to this interrupt, and how can I maximize the bandwidth. Also, how I might give a higher priority to the interrupt.  The FW examples kind of hide how this is done, however, there is an example for the GPIO and interrupts so I'm wondering if setting them up this way might provide less latency.  Also, is there anyway to get a main loop or does that live somewhere in the background and is inaccessible?

0 Likes
1 Solution

I checked with the SW team and here's what we can provide:

> what is the latency..


All GPIO interrupts are serialized to the application thread. In other words, the application never handles any interrupts in interrupt context. The latency to get to the application thread context interrupt handler depends on a number of things. If the device is sleeping, then this will generally be under 3mS. If not sleeping and not connected, then this will be of the order of a few tens of uS. When connected, the connection state machines have a higher priority than the application thread. So there may be some delay (of the order of a few hundred uS) in handling the interrupt.

> and is there a time hysteresis, and if there is can I set it to be minimal…

By this, we are assuming that you mean if there is jitter – yes, there is, the upper bound of this is of the order of 3 mS (when sleep is enabled). This is already as low as it can be. The app cannot control this.

> also is there some onboard checking of this to make sure it was high for some period of time so I can bypass this.

No, there is no onboard checking (in other words, debounce) if the gpio driver is used like in temperature_sensor or spi_comm_* sample applications. If buttons in the application’s BLE_PROFILE_GPIO_CFG config structure, then yes, the FW debounces interrupts.

> I have wired a 10us pulser to the sw1 input…

The HW can detect these edges, but if the period of the pulse is also of the order of 10uS, then the FW/app cannot handle every edge/transition. The system was not designed to be used like this.

> is there anyway to get a main loop or does that live somewhere in the background and is inaccessible?

There is no main() loop in the system. This is a multi-threaded system and the architecture of application is designed to be an event driven system.

View solution in original post

10 Replies
legic_1490776
Level 5
Level 5
25 likes received 10 likes received First like received

I am interested in this question as well.

I've observed typical latency somewhere between 10ms and 30ms on gpio interrupts, which is higher than I would like.

Is there any way to reduce the typical latency?

0 Likes

I checked with the SW team and here's what we can provide:

> what is the latency..


All GPIO interrupts are serialized to the application thread. In other words, the application never handles any interrupts in interrupt context. The latency to get to the application thread context interrupt handler depends on a number of things. If the device is sleeping, then this will generally be under 3mS. If not sleeping and not connected, then this will be of the order of a few tens of uS. When connected, the connection state machines have a higher priority than the application thread. So there may be some delay (of the order of a few hundred uS) in handling the interrupt.

> and is there a time hysteresis, and if there is can I set it to be minimal…

By this, we are assuming that you mean if there is jitter – yes, there is, the upper bound of this is of the order of 3 mS (when sleep is enabled). This is already as low as it can be. The app cannot control this.

> also is there some onboard checking of this to make sure it was high for some period of time so I can bypass this.

No, there is no onboard checking (in other words, debounce) if the gpio driver is used like in temperature_sensor or spi_comm_* sample applications. If buttons in the application’s BLE_PROFILE_GPIO_CFG config structure, then yes, the FW debounces interrupts.

> I have wired a 10us pulser to the sw1 input…

The HW can detect these edges, but if the period of the pulse is also of the order of 10uS, then the FW/app cannot handle every edge/transition. The system was not designed to be used like this.

> is there anyway to get a main loop or does that live somewhere in the background and is inaccessible?

There is no main() loop in the system. This is a multi-threaded system and the architecture of application is designed to be an event driven system.

Thanks,

It sounds like I need to keep my device out of sleep mode, then to have the lowest latency. What would be the best way to do this? I'm sure the answer is simple, but there is quite a bit to sort through. A suggestion on the best way to prevent sleeping would be great. Also note the app note talking about hardware interfaces says to call the function gpioDriver_init() but note that this does not exist in the example applications you refer to. This caused some headaches and it would be worth fixing the documentation.


0 Likes

To permanently disable sleep, register a callback using devlpm_registerForLowPowerQueries() and then in the callback, always return 0. For an example, see ws_upgrade_uart.c in uart_firmware_upgrade sample application. Note that this will drain more power than when sleep is enabled.

Sorry, looked in the source tree I have from 1.1dk and do not see any call to

devlpm_registerForLowPowerQueries. Tried to put it in a callback using this and returning 0, but callback never was entered.


0 Likes

I was not able to get this callback to work either.

However, I did find that I was able to achieve much better interrupt latency by calling this:

    devlpm_enableWakeFrom(DEV_LPM_WAKE_SOURCE_GPIO);

This consistently provides under 20ms latency from a GPIO interrupt, whereas previously I was seeing latencies upwards of 200ms after the device went into deep sleep.  I gather that previously I was only getting interrupts when some other event happened to wake up the system.. 

0 Likes

In your BLE_PROFILE_CFG structure, is powersave_timeout member set to 0? If it is, then call devlpm_init() in your application create function before the call to devlpm_registerForLowPowerQueries().

0 Likes

Yes powersave_timeout was set to zero, by the way is there some documentation on what all of the variables mean in the BLE_PROFILE_CFG structure, perhaps I missed it. I know what some of them mean at least I think I do based on the name, but the aforementioned variable would be good to know what it means. Comments in the code are helpful, but a few sentences on each of them would be awesome!

0 Likes

I agree that documenting what all of the variables mean in the BLE_PROFILE_CFG structure would make alot of sense and be useful to many others in the future.  I will look into allocating resources internally to work on this project.

0 Likes

In addition, the firmware already does a gpio_init() before the app is initialized, so this is not needed.

0 Likes