We are looking for reducing power consumption in our PIC24F freeRTos application.
For reducing power consumption, we are currently looking for using the configUSETICKLESS
IDLE freeRtos option. Since the current pic24f port does not support it yet, I was looking at adding the required portSUPPRESSTICKS
AND_SLEEP() macro myself based on instructions provided on the freeRtos Low Power website (http://www.freertos.org/low-power-tickless-rtos.html).
There something I must be missing though. On that website, it says:
To avoid race conditions the RTOS scheduler is suspended before portSUPPRESSTICKSANDSLEEP() is called, and resumed when portSUPPRESSTICKSANDSLEEP() completes. This ensures application tasks cannot execute between the microcontroller exiting its low power state and portSUPPRESSTICKSAND_SLEEP() completing its execution.
It also says in the example implementation of portSUPPRESSTICKS
/* Determine how long the microcontroller was actually in a low power
state for, which will be less than xExpectedIdleTime if the
microcontroller was brought out of low power mode by an interrupt
other than that configured by the vSetWakeTimeInterrupt() call.
Note that the scheduler is suspended before
portSUPPRESSTICKSANDSLEEP() is called, and resumed when
portSUPPRESSTICKSANDSLEEP() returns. Therefore no other tasks will
execute until this function completes. */
ulLowPowerTimeAfterSleep = ulGetExternalTime();
Finally, from the vTaskSuspendAll() description:
API functions that have the potential to cause a context switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler is suspended.
Based on these previous citations, I can’t understand how it can work when an other interrupt wakes up the cpu. Let’s say I have a uart RX interrupt waking up the CPU, which calls taskYIELD() as recommended by freeRtos guidelines about ISR. Then it would perform a task context change going against the vTaskSuspendAll() documentation, right? Am I missing something or we really cannot use portSUPPRESSTICKS
AND_SLEEP() when we have interrupts using freeRtos services that may provoke a task context?
Thanks for your help