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

nrfx_gpiote_in_init and logging within its event handler

Hi there. When nrfx_gpiote_in_init's event handler is called, is it being called as an interrupt? I note that if I use NRF_LOG_INFO within the body of the event handler, then my device will reboot on occasion. What I think I must do is to enqueue an event for processing outside of being an interrupt, but I've not yet confirmed that I should need to, or how. Any pointers here are appreciated. Thanks.

  • Christopher Hunt said:
    I’ll give the breakpoint a go. Thanks.

    Great, I look forward to hearing if this identifies your issue!

    Christopher Hunt said:
    Re the main vs interrupt context, is it not possible for the main context to be interrupted?

    It is absolutely possible for the main context to be interrupted - in fact, this is the usual procedure when working with an EVENTS / TASKS system.
    This is why the main context has the lowest priority.

    Christopher Hunt said:
    If the main context was halfway through writing into memory, couldn’t an interrupt routine cause havoc when reading that same memory?

    Yes, this is touching on some central themes in real-time operating systems
    In general, you should not have a higher priority interrupt relying on a lower priority interrupt having finished its processing, because you are not guaranteed that this will happen. The general main-power-optimize configuration demonstrates this principle well, because if main never gets to run that just means that the device will not go to sleep mode - which does not block the higher priority interrupts.

    Your main context should expect to be interrupted at any time during its procedures - this is especially the case when the SoftDevice is enabled, since the SoftDevice take priority over any application layer task when it needs to complete timing-critical procedures. This is also shown in the interrupt priority figure I linked above.

    Christopher Hunt said:
    The template example calls upon the power manager to loop, so I don’t see how I could poll for state to change...

    Yes, this causes the CPU to enter a low-power state while waiting for an event to be generated.
    This drastically reduces power consumption compared to having the CPU idle while waiting for an event to be generated.
    When an event is generated, the CPU will wake, return from the power_manage function. handle the event, and continue the main loop - going back to the low-power state if no other event has been generated.

    Please do not hesitate to ask if anything still should be unclear, or if you should have any other questions!

    Best regards,
    Karl

  • I didn't realise that when BLE causes the entering of sleep mode, that it powers off everything. This explains what I'm seeing as the sleep code causes a reset:

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
    Unsure what then will wake it up...?
    Back to the original question though, I was trying to understand whether GPIOTE handlers are called as an interrupt. I've learnt from you that they are. So that I can synhcronise the activities of my application, and so that no data is becoming corrupted, it appears as though I need to use the scheduler. Thus, when I get a GPIO event, I can then schedule my application to do something on the main context. I shall look further into this via https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/scheduler-tutorial. Thanks.
  • Just to follow up. I'm now using the scheduler quite successfully. Thanks for taking the time to confirm that the GPIOTE handlers are called in an interrupt context. It is quite confusing starting out as it appears that some of the BLE handlers are invoked in the main context via the scheduler. Anyhow, I'm all good now. Thanks again.

  • Christopher Hunt said:
    I'm now using the scheduler quite successfully.
    Christopher Hunt said:
    Anyhow, I'm all good now. Thanks again.

    I am glad to hear that you are all good now, and have achieved the sought-after functionality!

    Just to round up your previous questions:

    Christopher Hunt said:
    I didn't realise that when BLE causes the entering of sleep mode, that it powers off everything. This explains what I'm seeing as the sleep code causes a reset:

    Yes, SYSTEM OFF mode is the lowest possible power consumption mode - the device is turned off. This happens when the device is inactive for a certain amount of time ( i.e you turn it on and leave it ). The BLE examples are set up with this functionality as default, and you may wake the device ( causing a reset ) by pressing the buttons on the DK.

    Christopher Hunt said:
    So that I can synhcronise the activities of my application, and so that no data is becoming corrupted, it appears as though I need to use the scheduler.

    This is a possibility, but it is not the only way to ensure that the transfers are not interrupted. You could also make use of the nrfx_ drivers - since they use the easyDMA feature - and possibly also connecting it with PPI in order to minimize the necessary CPU hands-on time.
    In essence, easyDMA lets your peripherals ( such as GPIOTE, UARTE, SPIM/S, etc ) write to memory directly, without having the CPU pay attention. Then, when a transfer is finished, an event is generated to tell the CPU that data is available.
    You are free to implement this using the scheduler as well, but I though I should mention it since both easyDMA and PPI are two very powerful features of the nRF52 series.

    Christopher Hunt said:
    Thanks again.

    It is no problem at all, Christopher! I am happy to help.

    Please do not hesitate to open a new ticket if you should encounter any issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl 

Related