Hybrid Scheduling

Does anyone have an example of hybrid scheduling that preemptive and cooperative scheduling can coexist in the same system? What I want to do is that my system have several tasks running, one of them is the system check periodically in 1 or 2 second like RAM/ROM check…, I want it to be preemptive which is running in the back with lowest priority except idle task, the other tasks have the normal function with higher priority, I want them to be co-opertive. the realtime kernel book has a short description for it, but didn’t provide more details. I don’t know if it is possible that both scheduling can coexist in the same system. Thanks in advance! Albert

Hybrid Scheduling

The kernel can only be set up in one way in any one build – so all the tasks within the same build use the same scheduling policy. So you can’t set a scheduling policy per task. If I understand your post correctly you want the low priority tasks (Idle and RAM/ROM checker) to be preempted by the higher priority tasks, but for the higher priority tasks to co-operate. Presumably you therefore mean that the higher priority tasks will not time slice. You can effect something like this by setting configUSEPREEMPTION to 1, and configUSETIME_SLICING to 0. Then the lower priority tasks will not time slice either, but will be preempted by the higher priority tasks. If you want the lower priority tasks to share CPU time they can call taskYIELD() manually within their implementations. Likewise the higher priority tasks. The scheduler will switch between the higher priority task, but not just because a tick interrupt occurred. The scheduler will only switch from one task to another because the task either manually called taskYIELD(), or it performed an action that invoked the scheduler (such as posting to a queue on which another task was blocked). Regards.

Hybrid Scheduling

If you want to run the higher priority tasks co-operative as a means of controlling mutual exclusion, be aware that the scheduler will switch between the tasks if an interrupt performs a task that invokes the scheduler i.e. you MUST NOT include ~~~~ if( xHigherPrioritytaskWoken == pdTRUE ) { portYIELDFROMISR(); /* or portENDSWITCHINGISR() depending on the port.*/ } ~~~~ in you interrupt routines if they call any xxxFromISR FreeRTOS functions In addition the scheduler will switch processes (once) as a result of any timeout in the high level processes (such as vTaskDelay or a timeout in a send/receive and not necessarily to the task that triggered the timeout. see https://sourceforge.net/p/freertos/discussion/382005/thread/278999da/ for a thread on configUSETIMESLICING. IMHO, if you want to use co-operative scheduling for your high-level processes you should use it everywhere and merely call taskYIELD() liberally in the low-priority processes

Hybrid Scheduling

I probably only use co-operative scheduling in my system, in higher priority tasks use vTaskDelayUntil to make fixed period call, for example 10ms, in the lowest priority task (system check), call taskYIELD() in the end of the function like Mike said to force context switch. In my higher priority tasks, I would like 2 or 3 tasks have the same priority and with time slicing since they have the same importance. But it looks like “configUSETIMESLICING” only works with “preemptive” and not works for “co-opertive” scheduling, is this right? if this is true, is there a way to implement time slicing for the same priority tasks in co-operative scheduling? Thanks. Albert

Hybrid Scheduling

Albert, If I can be so bold, why do you want to use co-operative scheduling at all?

Hybrid Scheduling

Mike, Actually I am evaluating to see if FreeRtos can be used in my new project, this new project is based on a old project which using OSEK as RTOS and different Micro. OSEK can have preemptive and cooperative coexist in one system. In my previous project It has preemptive low priority system check task and higher priority tasks in cooperative scheduling, some of these higher priority tasks are safety related tasks, using preemptive scheduling will interrupt some safety tasks when running. we only allow the “system check task” to be able to be interrupted by higher periority task. I don’t want to change them too much. Thanks. Albert

Hybrid Scheduling

IMHO, if you want to perturb the old project as little as possible I would stick with co-operative which means you don’t want time slicing. Time slicing would interrupt your “safety tasks”. Your other main concern is that when designing co-operative tasks you have mutual exclusion between tasks, except at the control points. Switching to preemtive/time slicing would require careful examination of the tasks to determine possible race conditions, resource sharing, non-reentrant functions (e.g. sprintf on PIC24’s is non-reentrant), etc. PS. according to RTEL in https://sourceforge.net/p/freertos/discussion/382005/thread/278999da/ (thread on configUSETIMESLICING), it is only after 7.6.0 that co-operative scheduling guarantees control of process switching (don’t know the behaviour prior) mike