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

Is it safe to change interrupt handler for GPIOTE while using softdevice ?

Hi,

While trying to measure timings with input captures and pin interrupts, I noticed that the SDK-provided pin changed event is very slow : by the time my handler starts running, the signal level has changed...

I then discovered https://devzone.nordicsemi.com/f/nordic-q-a/54956/copying-vector-table-to-ram-unknown-function-at-0x00000000 and managed to set my own handler for GPIOTE.

Works fine : i typically have a max delay between TIMER0 capture and handler start of ~3us with 1 sensor, and ~70us with 3 sensors.

I then tried to make those measurements while using softdevice (s140) to send out the numbers through BLE.

If measurements are performed within a timeslot, everything seems to work properly, including with the interrupt vector moved to RAM and with my custom GPIOTE handler.

So far so good, but running a couple of examples for a few hours is not enough to uncover all possible problems.

So my question is : do yo see any problems moving the vector table to RAM and tweaking handlers while using softdevice ? or can you confirm this is safe ?

Thanks in advance,

David

Parents
  • Hi Jørgen,


    Thanks a lot for this response and for the time spent.

    In fact, as you stated, the main thing I'm trying to workaround is the time spent in the driver before my event handler gets to run.

    To be honest, I wasn't trying to bypass the MBR/softdevice layer (which I must say I wasn't aware of initially) to save a couple of microseconds ; I was trying to have both a "bare-metal handler" AND the stock handler available in the same app.

    I think your suggestion boils down to *statically* replace the stock handler by another, ad hoc handler.
    This is what I did initially (although your "bare-metal" version does a better job obviously as it also gets rid of any nrf_* or nrfx_* function and uses registers directly -- i'll keep it mind, definitely.)

    And it worked fine, I must admit.

    But keeping the ability to revert back to the stock handler is also very interesting...
    In my specific application, sensors are powered up ~10ms per minute, and I only need minimal latency over those periods. The rest of the time, the stock handler and its other functionalities are valuable (e.g. for other code dealing with buttons which are written using SDK drivers.)
    (Note that I understand that having 2 handlers can also be a source of problems and events must be carefully configured accordingly -- but that's another story).

    So maybe I should rephrase my question :

    Is it possible to dynamically switch between different GPIOTE handlers while using SD ? (by moving the vector table to RAM)
    Or is it bound to fail at some point ?

    As to your hints about using high_accuracy=true and using IN-EVENTS : this is what i'm doing.


    Thanks again for your help.

    Best regards,
    David

  • If you remove the redefinition of the GPIOTE_IRQHandler in modules\nrfx\soc\nrfx_irqs_nrf52840.h, you should be able to dispatch the events manually to separate handlers:

    // GPIOTE_IRQn
    //#define nrfx_gpiote_irq_handler     GPIOTE_IRQHandler

    void GPIOTE_IRQHandler(void)
    {
        if(low_latency_mode == true)
        {
            // Handle time-critical events
            if(NRF_GPIOTE->EVENTS_IN[0] == 1)
            {
                nrf_gpio_pin_toggle(LED_1);
                NRF_GPIOTE->EVENTS_IN[0] = 0;
            }
            
            if(NRF_GPIOTE->EVENTS_PORT == 1)
            {
                nrf_gpio_pin_toggle(LED_2);
                NRF_GPIOTE->EVENTS_PORT = 0;
            }
        }
        
        //Trigger GPIOTE event handler in nrfx driver
        nrfx_gpiote_irq_handler();
    }

    Just make sure that you do not use the same IN events in both implementations, as this will cause issues in the driver.

Reply
  • If you remove the redefinition of the GPIOTE_IRQHandler in modules\nrfx\soc\nrfx_irqs_nrf52840.h, you should be able to dispatch the events manually to separate handlers:

    // GPIOTE_IRQn
    //#define nrfx_gpiote_irq_handler     GPIOTE_IRQHandler

    void GPIOTE_IRQHandler(void)
    {
        if(low_latency_mode == true)
        {
            // Handle time-critical events
            if(NRF_GPIOTE->EVENTS_IN[0] == 1)
            {
                nrf_gpio_pin_toggle(LED_1);
                NRF_GPIOTE->EVENTS_IN[0] = 0;
            }
            
            if(NRF_GPIOTE->EVENTS_PORT == 1)
            {
                nrf_gpio_pin_toggle(LED_2);
                NRF_GPIOTE->EVENTS_PORT = 0;
            }
        }
        
        //Trigger GPIOTE event handler in nrfx driver
        nrfx_gpiote_irq_handler();
    }

    Just make sure that you do not use the same IN events in both implementations, as this will cause issues in the driver.

Children
No Data
Related