Writing to settings (non-volatile memory) causes GPIO interrupt triggering losses

SDK 2.1.0

nRF9160

Hi,

I recently configured a GPIO input in my project with an associated interrupt whenever it detects a high to low transition. The transition is externally generated every 20ms.

With each interruption, a work is rescheduled.

Everything works as expected until there is a great write (buffer[3500]) to the Settings.

After writing, the work is executed, meaning that the transition was not detected.

It seems to me that it's a problem of priorities...

I wanted to know if it is possible, and how, to change the priority of GPIO interrupts.

Regards,

Ricardo

Parents
  • Ok, I understand. So while you are performing the flash operation, no interrupts are forwarded to your application, and when the write is done, you will get one interrupt (50.761), which is the queued up interrupt, and then it will presume as normal from 50.764 (until the next flash operation). 

    What kind of work is it that you are rescheduling on the GPIO interrupt? 

    The thing is that when you are performing flash write operations, the CPU is occupied, so it is not possible to do anything else at that point in time. 

    How time sensitive is the work you are rescheduling. It could be possible to limit the amount you write to flash (but do it more often), so that it doesn't take 90ms. But unless you time it to happen directly after a cross detection, it may still block your interrupt from triggering exactly when it occurs. However, if only one interrupt happens while you are writing to flash, this interrupt will be forwarded to the CPU (your application) when the flash write is done. 

    Alternatively, it is possible to do some tricks using DPPI to count the number of cross detections while the flash write operations are ongoing, and then catch up with the work once the flash write operation is done. Let me know what you think.

    Best regards,

    Edvin

  • Hi Edvin,

    Thanks for the explanation.

    I thought it could be some error in my implementation, or that it was possible to change the priorities of writing to flash in relation to GPIO interrupts... being a CPU limitation, I have to think of another way.

    What kind of work is it that you are rescheduling on the GPIO interrupt? 

    It's nothing elaborate, it's just a calback assigned by lwm2m to notify the failure and imminent shutdown.

    It could be possible to limit the amount you write to flash (but do it more often), so that it doesn't take 90ms.

    The write to flash is a single 3500 byte buffer, it's not easy to split this write, and as you say, it can always match and fail.

    Alternatively, it is possible to do some tricks using DPPI to count the number of cross detections while the flash write operations are ongoing, and then catch up with the work once the flash write operation is done.

    I don't need to know how many transitions happened, I just need to notify them as soon as possible if one fails.

    I'm more inclined to, before writing, cancel the scheduled work, at least I won't get false positives every time I finish writing.


    Regards,
    Ricardo

  • I think I understand. 

    Whenever you get a GPIO interrupt, it will be sent to your application, unless another process is blocking it, which in your case is the flash write. In that case, it will be forwarded to your application once the blocking action is finished. 

    RicardoCarvalho said:
    I don't need to know how many transitions happened, I just need to notify them as soon as possible if one fails.

    In that case, you will be notified as soon as possible, once the flash write has finished. If it fails twice during the flash write, however, you will only be notified once, because when an interrupt is being handled, it is also cleared. If an interrupt happens twice before you handle it, it doesn't stack, so you will only know that it happens once.

    So as I mentioned, it is possbile to set up a counter using the DPPI (a peripheral used to link up events and tasks in other peripherals). So you could link up the event where the GPIO triggers, to a task in a timer set in counter mode to increment by one. This way you can have an event counter to count the number of events without involving the CPU. Then, you can later in the interrupt handler check how much the timer has incremented to see how many times it happened. However, that is only if you need the amount of times it happened while writing.

    Best regards,

    Edvin

Reply
  • I think I understand. 

    Whenever you get a GPIO interrupt, it will be sent to your application, unless another process is blocking it, which in your case is the flash write. In that case, it will be forwarded to your application once the blocking action is finished. 

    RicardoCarvalho said:
    I don't need to know how many transitions happened, I just need to notify them as soon as possible if one fails.

    In that case, you will be notified as soon as possible, once the flash write has finished. If it fails twice during the flash write, however, you will only be notified once, because when an interrupt is being handled, it is also cleared. If an interrupt happens twice before you handle it, it doesn't stack, so you will only know that it happens once.

    So as I mentioned, it is possbile to set up a counter using the DPPI (a peripheral used to link up events and tasks in other peripherals). So you could link up the event where the GPIO triggers, to a task in a timer set in counter mode to increment by one. This way you can have an event counter to count the number of events without involving the CPU. Then, you can later in the interrupt handler check how much the timer has incremented to see how many times it happened. However, that is only if you need the amount of times it happened while writing.

    Best regards,

    Edvin

Children
  • Hi Edvin,

    Whenever you get a GPIO interrupt, it will be sent to your application

    I don't send it whenever I receive an interruption, on the contrary, I'm interested in detecting the lack of interruptions, whenever I receive a GPIO interruption I reschedule a work for 25msec (it waits for the next interruption), in the absence of an interruption the work is executed and then it reports the failure to the application.

    What it seems to me is happening is that because writing to flash takes more than 25msec, when it finishes, the work is queued and executed, reporting a false lack of interrupt to the application.

    That's why I said that the best solution would be to cancel the work before writing...

    Regards,

    Ricardo

    Edit:
    I will try something else, I will transfer all settings storage to external flash, this should solve the problem.

    Edit 2:
    Just to say that moving settings storage to external flash solves the problem.

Related