Leaving low power on a GPIO interrupt

Hello,
I have a system around an STM32G0B0 going into sleep and waking up frequently but it shall also wake up by a GPIO edge.
I want to understand closer what is going on under the hood of FreeRTOS.
I did like this:

  • disable all FreeRTOS timers and put all but one task into the blocked state by making them wait for a queue
  • call vTaskDelay with a duration of 5 sec
  • now the system enters sleep which I can see looking at supply current
  • after 5 sec the system wakes up, performs one task loop and goes to sleep again, other task remain blocked
    all of that works fine
    also I configured a GPIO pin to trigger an interrupt on a rising edge. The isr sends a message to a queue belonging to the task that calls vTaskDelay. The xQueueReceive is at some place in the loop that runs after sleep exit.
    I output debug messages on a UART. Now what I observe is this:
  • every 5 sec there is a message from the loop and one right before entry of sleep
  • immediately after a rising edge on the GPIO pin a message is sent from inside the isr
  • a message is sent that the queue message is processed, but only after the 5sec sleep interval is finished, so maybe up to 4.9 sec after the isr.
    How comes this? Sleep is left for the isr. Is the vTaskDelay entered again? How can I make it exit sleep and resume operation either in a 5sec interval or on a GPIO edge?

Thanks for any hint

Martin

It is hard to follow the sequence of execution. Possible for you to share some code snippets?

If the task is in vTaskDelay() when the ISR executes, then the task will still finish the vTaskDelay(). This behavior is as designed, and it matches your observations.

If you want the ISR to wake the task immediately, then the task must be waiting in xQueueReceive(). Consider using the xTicksToWait parameter to enforce maximum delays waiting for a something in the queue. As soon as the ISR puts something in the queue, the waiting will end immediately and the task will resume to process the item from the queue.

1 Like

Hello Jeff,

thanks for the explanation.
Two questions for clarification:

  • whether the CPU goes to sleep or not has no impact on the FreeRTOS behaviour ?
  • you suggest a xQueueReceive, I guess a ulTaskNotifyTake or similiar will do as well ?

Thanks
Martin

I tried the second question myself and yes, ulTaskNotifyTake does the job.
Thanks for the help

Hi Martin,

For the first question, FreeRTOS has low power support and CPU sleep is also considered in the design. You can reference this document for more information.