Force GPIOTE event manually.

Using SDK17.1.0, I need to manually force an event handler to run. But the event handler is part of the SDK and is declared static. Key constraint is that i cannot modify the SDK.

I'm using the app_button library. But the handler i registered for the button doesn't run when the chip is wakes up from shutdown mode (following button press). I am aware this is because the debounce timer doesn't start (started in the gpiote event handler).

I tried manually running my local app_button handler, but of course this skips many steps within the app_button library and causes all sorts of problems. So, essentially i need to call a function from further back in the call stack/ chain of events.

But every function that potentially provides a route to triggering the app_button event handler is declared static or is out of scope of my code.

The event handler i'd like to trigger is below: (line 245 app_button.c)

 

static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    app_button_cfg_t const * p_btn = button_get(pin);
    bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
    bool is_active = !((p_btn->active_state == APP_BUTTON_ACTIVE_HIGH) ^ is_set);

    /* If event indicates that pin is active and no other pin is active start the timer. All
     * action happens in timeout event.
     */
    if (is_active && (m_pin_active == 0))
    {
        NRF_LOG_DEBUG("First active button, starting periodic timer");
        timer_start();
    }
}

Ideally i could do to find the memory location in which the pointer to the above handler is stored (when it is initialised). i could, for example, do this using the following code:

   nrfx_gpiote_evt_handler_t handler = channel_handler_get((uint32_t)channel_port_get(BTN_PIN));
         handler(BTN_PIN, GPIOTE_CONFIG_POLARITY_HiToLo);       

But again, both of these functions are static.

 

Ideally, i'm looking for suggestions of global functions that can be used to retrieve a pointer to the gpiote event handler (the one in the first extract of code above). Or some other way of manually forcing a button action. Even if i could perhaps manually force the pin's IRQ at register level?

Thanks,

Sean

Parents
  • Hi Sean,

    May I ask why you want to call the event handler directly in the first place? What is the end goal? And can you potentially achieve the end goal in another matter (for instance by doing the same as the event handler from another function)?

    Also, while I understand that in some cases you may have qualified the SDK as is and cannot change it, it seems a bit unfortunate that it leads to a the need for potentially dirty hacks. It seems counter productive if the goal of not changing the SDK is related to quality somehow.

    If this really is the approach you need to use, then perhaps an alternative could be this: Read a function pointer from a specific address (for simplicity you could perhaps put it in UICR for testing, but in order to support DFU etc later it should be in normal flash). Call that function pointer when you want to call the static event handler. Then, after you have built the project, check the map file to find the address of the event handler, and write that to the location that should hold the function pointer. This could be done manually first for testing. When you get this working, you can script this so that you automatically parse the map file and modify the hex file, writing the address/pointer to the fixed location you have reserved for it.

    Einar

Reply
  • Hi Sean,

    May I ask why you want to call the event handler directly in the first place? What is the end goal? And can you potentially achieve the end goal in another matter (for instance by doing the same as the event handler from another function)?

    Also, while I understand that in some cases you may have qualified the SDK as is and cannot change it, it seems a bit unfortunate that it leads to a the need for potentially dirty hacks. It seems counter productive if the goal of not changing the SDK is related to quality somehow.

    If this really is the approach you need to use, then perhaps an alternative could be this: Read a function pointer from a specific address (for simplicity you could perhaps put it in UICR for testing, but in order to support DFU etc later it should be in normal flash). Call that function pointer when you want to call the static event handler. Then, after you have built the project, check the map file to find the address of the event handler, and write that to the location that should hold the function pointer. This could be done manually first for testing. When you get this working, you can script this so that you automatically parse the map file and modify the hex file, writing the address/pointer to the fixed location you have reserved for it.

    Einar

Children
No Data
Related