FreeRTOS High-level article one----idle task analysis

Source: Internet
Author: User

When the RTOs Scheduler starts to work, the idle task is created automatically, taking the lowest priority (0 priority) to ensure that at least one task is running.

   Xreturn = Xtaskcreate (Prvidletask,                         "IDLE", Configminimal_stack_size,                         (void *) NULL,                         (tskidle_priority | Portprivilege_bit),                         &xidletaskhandle);

An idle task is an FreeRTOS task because the FreeRTOS design requires at least one task to be in a running state. Let's take a look at the work of the idle task.

1. Freeing up memory

Starting with the V9.0 version, if one task deletes another task, the stack of the deleted task and the TCB are immediately released. If a task deletes itself, the task's stack and TCB are deleted by the idle task as before. So the idle task begins to check if a task has deleted itself, and if so, the idle task is responsible for removing the TCB and stack space for the task.

2. Handling Idle Priority Tasks

When using a preemptive kernel, tasks of the same priority use the time slice method to gain CPU privileges. If a task shares a priority with an idle task, and the macro Configidle_should_yield is set to 1, the idle task does not have to wait until the time slice is exhausted before the task is switched on.

So the idle task checks if there are multiple tasks in the Ready list under the idle priority, and then performs a task switch, allowing the user task to gain CPU privileges.

Macro Configidle_should_yield controls the behavior of the task in the idle priority. This will only work if the following conditions are met.

    1. Using preemptive kernel scheduling
    2. User tasks use Idle priority.

Multiple tasks that share the same priority through a time slice, if the share has a priority greater than the idle priority, and assume that there are no higher priority tasks, those tasks should get the same processor time.

However, if you share an idle priority, the situation is slightly different. When Configidle_should_yield is 1 o'clock, other user tasks that share the idle priority are ready, the idle task immediately yields the CPU, and the user task runs, ensuring the fastest response to user tasks. In this mode there will also be undesirable effects (depending on your program needs), described as follows:

The figure depicts four tasks in idle priority, tasks A, B, and C are user tasks, and task I is an idle task. Context switching occurs periodically in T0, T1 ... T6 moment. When the user task runs, the idle task immediately yields the CPU, but the idle task has consumed a certain amount of time in the current time slice. The result is that the idle task I and user task a share a time slice. User task B and user task C have thus gained more processor time than user task A.

The following methods can be used to avoid:

    • If appropriate, place the individual tasks in the idle priority into the idle hook function;
    • The created User task priority is greater than the idle priority level;
    • Set Idle_should_yield to 0;

Setting Configidle_should_yield to 0 will prevent the idle task from giving up the CPU for the user task until the time slice of the idle task ends. This ensures that all tasks that are in the idle priority are assigned to the same number of processor time, but this is at the expense of a higher percentage of processor time allocated to idle tasks.

3. Execute Idle task hook function

The idle task hook is a function that is implemented by the user, and the RTOs specifies the name and parameters of the function, which is called during each idle task cycle.

To create a free hook:

    1. Set the Configuse_idle_hook in the FreeRTOSConfig.h file to 1;
    2. Define a function with the functions name and parameters as follows:

This hook function cannot invoke API functions that cause the idle task to block (for example: Vtaskdelay (), queue with blocking time, and semaphore function), and the use of the coprocessor inside the hook function is allowed.

It is common to use the idle hook function to set the CPU into power saving mode.

4. Low power tickless mode

Usually, FreeRTOS callback idle task hook function (need to implement by the designer), in the idle task hook function to set the microprocessor into a low-power mode to achieve the purpose of power saving. Because the system responds to a system beat interrupt event, this method periodically exits and then enters a low-power state. If the system is running too fast, most of the power and CPU time is consumed by entering and exiting the low power state.

The FreeRTOS tickless idle mode stops the periodic system beat interruption during idle cycles. Stopping periodic system beat interrupts allows the microcontroller to be in low-power mode for extended periods of time. The porting layer needs to configure an external wake-up interrupt, which wakes the microcontroller from a low-power mode when the wake-up event arrives. When the microcontroller wakes up, it will re-enable the system to interrupt the cycle. Since the microcontroller is going into low power, the system beat counter is stopped, but we need to know how many times the system beat interrupt period can be converted, which requires an external clock source that is not affected by the low power consumption, that is, when the microprocessor is in the low power mode, it is also timed, This allows an adjustment value to be calculated from the external timer and written to the RTOS system beat counter variable when the system is restarted.

The source code for the idle task is shown below, where the macro porttask_function is translated as: void Prvidletask (void * pvparameters).

Static Porttask_function (prvidletask,pvparameters) {/* prevents compiler warning */(void) pvparameters; for (;;)   {/* Check if a task has deleted itself, if any, the idle task is responsible for deleting the TCB and stack space for this task */prvchecktaskswaitingtermination (); #if (configuse_preemption = = 0) {/* If we do not use preemptive scheduling, we will force the task to switch to see if any other tasks become effective. If you use preemptive scheduling, you do not need this, because the task becomes active and the idle task is preempted. */   Taskyield ();   } #endif/* configuse_preemption */#if ((configuse_preemption = = 1) && (Configidle_should_yield = = 1)) {/* When using a preemptive kernel, tasks of the same priority use time slices to gain CPU permissions. If a task shares a priority with an idle task, the idle task does not have to wait until the time slice runs out before the task is switched on. If there are multiple tasks in the Ready list under the idle priority, perform the user task */if (   Listcurrent_list_length (& (pxreadytaskslists[tskidle_priority)) > (ubasetype_t) 1) {Taskyield ();}  } #endif/* ((Configuse_preemption = = 1) && (Configidle_should_yield = = 1)) */#if (Configuse_idle_hook = = 1) {externvoid vapplicationidlehook (void);/* Invokes a user-defined function. This allows the designer to implement background functionality without increasing task overhead Note: This function does not allow the invocation of functions that might cause blocking in a task. */   Vapplicationidlehook (); } #endif/* Configuse_idle_hook */#if (Configuse_tickless_idle! = 0) {   ticktype_txexpectedidletime;/* If the scheduler is suspended every time an idle task is executed, then the scheduler is released, which is difficult to satisfy, so the same comparison is performed two times ( Xexpectedidletime and Configexpected_idle_time_before_sleep), the first comparison is to test whether the expected idle time is reached and does not suspend the scheduler. */xexpectedidletime= Prvgetexpectedidletime (); if (Xexpectedidletime >= configexpected_idle_time_before_sleep) {vTaskSuspendAll ();   {/* Now the Scheduler is suspended, need to sample idle time again, this idle time can use */Configassert (xnexttaskunblocktime >= xtickcount);   Xexpectedidletime= Prvgetexpectedidletime (); if (xexpectedidletime >= configexpected_idle_time_before_sleep) {portsuppress_ticks_and_sleep (xExpectedIdleTime   );   }} (void) Xtaskresumeall ();} } #endif/* Configuse_tickless_idle *}}






FreeRTOS High-level article one----idle task analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.