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.

Parents
  • Actually, it seems to reboot no matter whether I log or not. I'm using the BLE template project and so I'm now beginning to wonder if the reset is a feature of BLE not being connected. So far, if I connect the device I've not seen it reset.

  • Thanks Karl.

    Yes, I’ve got debug enabled. It could well be the sleep mode that I’m encountering. I shall check further.

    If I need to perform logic in the main context, how can I trigger that from the interrupt context?

    FYI my code is derived from the BLE template example. Thanks.

  • Christopher Hunt said:
    Thanks Karl.

    It is no problem at all, Christopher.

    Christopher Hunt said:
    Yes, I’ve got debug enabled. It could well be the sleep mode that I’m encountering. I shall check further.

    Are you using deferred logging?
    If you are, then you could place a breakpoint in the on_adv_evt handlers IDLE event, to see if this is the event sending the device to sleep.

    Christopher Hunt said:
    If I need to perform logic in the main context, how can I trigger that from the interrupt context?

    Is there a particular reason why would like it to be performed in the main context?
    The easiest way to do this would be to set a variable during the interrupt, and have a conditional section as part of the main function.
    However, you could also just change the priority level of the particular peripherals interrupt, and process the interrupt directly in the event handler.

    Christopher Hunt said:
    FYI my code is derived from the BLE template example. Thanks.

    Thank you for clarifying.

    Best regards,
    Karl

  • I’ll give the breakpoint a go. Thanks.

    Re the main vs interrupt context, is it not possible for the main context to be interrupted? If the main context was halfway through writing into memory, couldn’t an interrupt routine cause havoc when reading that same memory? Or perhaps I’m making some incorrect assumptions here...

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

  • 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.

Reply Children
  • 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