[riot-notifications] [RIOT-OS/RIOT] kinetis: Optimize GPIO interrupt handler (#8558)

Joakim Nohlgård notifications at github.com
Tue Nov 6 15:53:17 CET 2018

gebart commented on this pull request.

> @@ -308,11 +308,18 @@ static inline void irq_handler(PORT_Type *port, int port_num)
     /* take interrupt flags only from pins which interrupt is enabled */
     uint32_t status = port->ISFR;
-    for (int i = 0; i < 32; i++) {
-        if ((status & (1u << i)) && (port->PCR[i] & PORT_PCR_IRQC_MASK)) {
-            port->ISFR = (1u << i);
-            int ctx = get_ctx(port_num, i);
-            isr_ctx[ctx].cb(isr_ctx[ctx].arg);
+    unsigned pin = 0;
+    while (status) {
+        unsigned tz = __builtin_ctz(status);
+        pin += tz;

All measurements were performed with the logic analyzer set to 100 MHz sample rate.

Tested with bitarithm_lsb on CM0+ (frdm-kw41z). The timing is on average 5.7µs with bitarithm_lsb on CM0+ (frdm-kw41z), `BITARITHM_LSB_LOOKUP` is defined, `BITARITHM_LSB_BUILTIN` is not defined.
There is quite a bit of other things adding to the measured delay though, so if you want to perform a direct comparison of the MultiplyDeBruijnBitPosition implementation against the GCC builtin armv6 asm implementation I think we will need a different test program.

One more measurement was taken as well, I moved the LED0_ON macro to the first line of the GPIO interrupt callback routine (the one passed as an argument to gpio_init_int). These measurements seem to confirm the improvement from builtin_ctz to bitarithm_lsb

Average time from GPIO pin flank to first line of `cb`:
With `bitarithm_lsb`: 4.4 µs
With `__builtin_ctz`: 4.8 µs

You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20181106/3b487d55/attachment.html>

More information about the notifications mailing list