I've noted that when the system uses co-routines it's dificult to know when send the CPU to sleep.
As I could understand, the documentation suggests to include the vCoRoutineSchedule() call into the vApplicationIdleHook() function, setting configUSE_IDLE_HOOK to 1. I reference the "Scheduling the co-routine" topic at the documentation
The Solution #2
of the FreeRTOS Tutorial evaluates that for a fully preemptive system the power consumption can be reduced if the idle task places the processor into power save (sleep) mode.
With the present co-routine implementation I find hard to detect when all the co-rutines are blocked (delayed) in order to place the processor into a power save mode until the next tick.
In this post
Richard Damon sugest this pseudo-code for the idle hook funcion:
idle hook function (will be called periodically by the idle task)
Enter Critical Section
if(ok to go to sleep)
prepare system to go to sleep
enter sleep state
wake system up from sleep state
end critical section
end critical section
maybe go to idle state if one is available
The question is, how to know when is ok to go to sleep when co-ruoutines are used?
As a possile solution I suggest to change the return value of vCoRoutineSchedule() from void to portBASE_TYPE, and modify this function in order to return pdTRUE when there is at least one ready co-rutine, and return pdFALSE if there is not.
As the documentation
declares, Co-routines are really only intended for use on very small processors that have severe RAM constraints. This kind of constraints can be common in small battery operated appliances.
Please, does anyone see the same dificulty that I do? Does anyone found a good way to solve it?
I know myself as a newbie, in case than more experienced FreeRTOS developers find my suggestion a good one, I would like to work on it and propose some code to discuss.
I'm studing FreeRTOS only for pleasure, as a hobby in my free time. I'm trying to understand line by line, function by function. That's why I could even think about situations that perhaps they are not real life ones.
I don't use co-routines, but it seems to me that what could be done is use the priority feature of co-routines to do this. Set up a Priority 0 co-routine that does the sleep, and put all other co-routines at a higher priority. The Priority 0 co-routine will only get time if no task or other co-routine (unless they also are at priority 0) are able to run.
Both suggestions sound good. The first one could be added under the sourceforge feature request tracker for FreeRTOS, although maybe richard_damons suggestion makes it obsolete?
Dear Richard, your suggestion is really nice and simple. Thanks a lot. I didn't realize.
Perhaps, something that some day may be improved is the number of CPU cicles to determine if any co-routine is in ready state.
One day I read that for a battery operated device each CPU cicle can be measure as miliseconds of authonomy.
But I think your suggestion is really good enough without any kernel modification. It's a pleasure to be studing an OS with this level of community support.
The code actually uses a fairly efficient method to scan for the highest priority co-routine (or task in similar code) that is ready to run. I suspect that by making the sleep routine just the lowest priority may be a very efficient way to check for this, as it uses the existing code without special cases.