Idle task class and TcIdleFiller

There is some confusion about the purpose and execution of the Idle task class/Task class idle time, and a process in the Profiler named TcIdleFiller. Below is a walkthrough explainer of the purpose and effect of using the Idle task class within a PLC.


  • Automation Runtime operates on a priority system (0-255). The higher the priority number of a task, the higher priority it has when multiple tasks want to run at the same time.
  • If multiple tasks need to run, the task with the higher priority is run first and the lower priority tasks wait. If no higher priority tasks need to run, then the CPU runs no-ops under a priority 0 process named IDLE. IDLE always wants to execute and yields to all other tasks.
  • In general, I break the priorities into 4 general categories:
    • Greater than 230: HW interrupts and I/O scheduling. These are a higher than Cyclic #1 in priority.
    • 230 to 190: Cyclic Tasks. Cyclic #1 has the highest priority, Cyclic #8 has the lowest. Certain time sensitive motion/system operations are also at this priority level.
    • 190 to 4: System Tasks. Ethernet traffic, ANSL/TCP/UDP communication, file operations, logger entries, visualization, webserver, SDM. Most of the OS level tasks and asynchronous workers are at this level.
    • Less than 4: Idle Tasks. These consist of the CPU running no-ops (no operation, CPU does nothing).

Purpose and Effect

  • The cyclic tasks have priority over all system tasks, which is desired because the cyclic code needs to execute at the timing interval configured for the application. System tasks, such as ANSL traffic or visualization updates can typically wait 2ms while a cyclic task completes a time critical operation.
  • If several cyclic tasks execute sequentially or take a long time, this creates an undesirable effect. The system tasks may be blocked from executing for a long duration of time (100-500ms). This causes the visualization to update sporadically, or ANSL packet responses to time out, and those systems will suffer.
  • The solution to this is to periodically provide a small amount of a cyclic task time to system tasks. The configuration of this system is known as the Task Idle Time / Idle Time Task Class.
  • Within the Idle Time Task Class (by default Cyclic #2, 20ms), the last Task Idle Time (by default 2ms) of that cyclic is used for system tasks.
  • This time is reserved ONLY for system tasks. If no system tasks need to run during that time, then TcIdleFiller (no-op) is run at priority 3. Just like IDLE, TcIdleFiller always wants to run, and yields to higher priority tasks. Another way to look at it, is the affected task classes are moved to priority 2 and are not executed since they yield to TcIdleFiller which always wants to run and has priority.
  • This system is active even in Service mode, even where no cyclic tasks are executed.
  • When the SDM displays CPU usage, the value is: 100% - [time spent at Priority 0, IDLE]. For example, if you spent 5% of the CPU time at priority 0, then the CPU usage is 95%.
  • Even though TcIdleFiller is a no-op, it is still considered CPU usage in the SDM.

Under an example configuration, the Idle Time is configured to dedicate the last 2ms of Cyclic #2 (4ms) to system tasks. This is approximately 50% of the CPU time that will be spent on either system tasks, or at priority 3 TcIdleFiller. This time is not indicated as idle for the purposes of CPU usage since it is not at priority 0. This is why if the CPU usage in the SDM will look artificially high while in Service mode. The CPU is spending 1.8ms of every 4ms running no-ops at priority 3, which is not idle for the purposes of CPU usage.

This can be seen in a profiler taken while the PLC is within service mode. The CPU spends 84.584% of its time running Idle tasks (no-ops), yellow box. However, it spends 57.66% of its time with a priority greater than 0, blue box. While the SDM will report CPU usage at 57.66%, the actual CPU usage is closer to 15.5% (I/O system, system tasks for web/SDM, and AS connection).

This behavior will also affect a running system, but to a much less degree. In the example below see that the CPU spends 10.35% of its time running Idle tasks (no-ops), yellow box. The reported CPU usage will be 95.45% because that is the time spent at a priority greater than 0, blue box.

To reclaim some of the TcIdleFiller time for lower priority cyclics, you could move the Idle task class to a higher cyclic, or slow down the Idle task class. These changes won’t affect the amount of time taken by Cyclic #1, because Cyclic #1 has priority to run over lower priority cyclic task classes and system tasks, including during the Task class idle time. The minimum the Task class idle time can be reduced to is your System Tick (base timer for all AR), and the Task class idle time must be a multiple of the System Tick. Zero (0us) is also a valid Task class idle time, which disables the feature.

Ideally, the application engineer finds a line within the application where higher priority tasks (I/O reaction, precision motion, etc.) are above your Idle task class, while lower priority tasks (recipe handling, user management, etc.) are handled in lower priority task classes.


Very good description of the Topic.

Too long cycle times for the idle task class are not advisable, as they might cause long reaction times for background processes (finding newly plugged IO-Modules, Networking, OPC UA, or even some System-Libraries…).
It is better to have 2ms at 20ms than 200ms at 2000ms cycle (both claiming 10% for background).