A Status task is level triggered: while its condition variable stays TRUE the scheduler restarts it the moment it finishes. One status task ran more than 20,000 times faster than the freewheeling task beside it and tripped ProcessorLoadWatchdog. Make the task clear its own trigger variable as its last action, so it runs once per request.
Your Status task starts whenever its condition variable is TRUE, and it starts again the instant it finishes, because the variable is still TRUE. On one soft PLC the status task ran more than 20,000 times faster than the freewheeling task beside it, and the runtime raised EXCEPTION [ProcessorLoadWatchdog] occurred in: App= [all], Task= [all]. The single rung inside the POU is not the problem; the execution count is. The fix is one statement: the task clears its own trigger variable as its last action, so it runs once per request. Below: how to confirm the spin in the task monitor, why the watchdog threshold is the wrong knob to turn, and which task type to pick when the logic must repeat.
What the signs point to
Each sign below was present in this fault, and each one narrows the search.
- The exception names every application and every task:
App= [all],Task= [all]. That points to scheduler load on the runtime as a whole, not a fault inside one POU. - The exception appears only while the condition variable is TRUE, and the application runs normally while it is FALSE. That points at the task the variable drives.
- The POU holds one rung and no loops. A small time per execution with a watchdog trip points to the execution count, not the code.
- The project ran on an earlier 3.5 release and faults after the move to 3.5 SP7, on Control Win V3 3.5.7.0 under Windows 10. The task definition carried over; the runtime and the host changed under it.
- In the online task monitor, the status task cycle counter races ahead of MainTask. That is the spin itself, and the next section measures it.
Confirm the spin in the task monitor
- Log in and open the Task Configuration in online mode. Its Monitor tab lists each task with a cycle count and a cycle time. If the login fails, check whether the runtime is running or stopped first.
- Record the cycle counts of MainTask and of the status task while the trigger variable is FALSE. The status task count must stand still.
- Set the trigger variable TRUE from a watch list or the HMI. Do this at a moment when a controller exception is acceptable.
- Read both counters again and compute the ratio: the status task count difference divided by the MainTask count difference over the same interval.
- A ratio far above 1 with a small per-execution time confirms the spin. It exceeded 20,000 to 1 on the machine that showed the fault. A ratio near 1 moves the search to your own code: an image cycle that stalls while logging in a loop is the same class of overload, produced by the logic instead of the task type.
Why a Status task runs back to back
A Status task is level triggered. The scheduler tests the condition variable; TRUE starts the task; the task finishes; the variable still reads TRUE; the task starts again. The task type inserts no idle interval and no cycle time between executions.
An Event task on the same variable would fire once per rising edge, because an edge is a change and a level is a state. A Freewheeling task also has no set period, but the runtime shares processor time across tasks, which is why one rung in MainTask leaves room for everything else. The spinning Status task accepts every slice it is offered, the measured load passes the configured limit, and the watchdog reports it for all tasks. For the full comparison, how cyclic, event and freewheeling tasks work walks the three types side by side.
Example: measuring the spin on one machine
On the machine that showed the fault, the Monitor tab gave this reading. With the trigger variable FALSE for a 60 s window, MainTask advanced about 3,600 cycles and the status task counter stood still, so the freewheeling task was running at its usual pace of roughly one cycle per 17 ms. After the trigger went TRUE, the status task counter climbed more than 20,000 cycles for every single MainTask cycle. At a freewheeling pace of one cycle per 17 ms, that is a status task restarting faster than 1,000 times per second off one request. The result: the ratio 20,000 to 1, with a per-execution time too small to read, confirms the level-triggered spin, not the logic inside the POU.
Scenario: why raising the threshold changes nothing
The watchdog limit lives in the runtime configuration file CODESYSControl.cfg, section [CmpSchedule], as ProcessorLoad.Maximum. The file on the affected machine carried ProcessorLoad.Maximum=80, no ProcessorLoad.Enable entry, and every other scheduler entry commented out: EnableLogger, Timeslicing.Mode, Timeslicing.PlcSlicePercent, Timeslicing.PlcSliceUs, Timeslicing.StartOnProcessorLoad, SchedulerPriority, SchedulerInterval. The suggested change, ProcessorLoad.Enable=1 with ProcessorLoad.Maximum=95, was applied and the exception stayed.
The arithmetic says why. The spin asks for every slice the scheduler offers, so the measured load climbs to essentially 100 percent. Against a limit of 80 percent, that is 100 minus 80, so 20 percentage points past the trip point. Against 95 percent, it is 100 minus 95, so 5 points past. Both settings trip; only the margin changes. Disabling the watchdog would only hide the symptom, and it is the one alarm you get when a task starves the rest of the runtime. Fix the task.
The fix: the task clears its own trigger
- Open the POU the Status task calls.
- Keep the logic that must run, then add the reset as the last action of the POU. In structured text, one statement:
t_manuell := FALSE;. That was the trigger variable in this fault; use the name in your own condition field. In ladder, put a reset coil on the trigger variable on the rung after the logic. - Build, download, and log in.
- Trigger the variable again, the same way as in the measurement above. The pass gate: the variable reads FALSE again immediately, the status task cycle counter advances a small number of cycles and stops, and no exception is raised.
On the machine that showed the fault, this removed the exception.
Two consequences carry into the application. FALSE is now the acknowledgement: every writer of the variable treats FALSE as the run being served. And the body executes once per request, so if the old behavior leaned on repeated executions while the variable stayed TRUE, weigh that against what the process actually needs.
Choose the task type the process needs
| The process needs | Task configuration | Pass gate |
|---|---|---|
| One execution per request | Status task that clears its own trigger variable | Counter advances once per TRUE |
| One execution per change | Event task on the same variable | Counter advances once per rising edge; no reset needed |
| Repeated execution while a condition holds | Cyclic task at a set interval, for example 100 ms, body gated by an IF condition THEN test |
Counter advances at the interval; task load stays low in the Monitor tab |
A cyclic task brings its own timing questions: a cyclic task that waits for an external event covers what to do when the event never arrives. To find how much load a soft runtime can carry before task times slip, find a soft PLC runtime cycle time limit with a load sweep walks the measurement.
When the spin is not the cause
If the monitor ratio sits near 1, or the exception also arrives with the trigger FALSE, the load is in the code or the host, and the per-task cycle times in the Monitor tab name the POU that eats the budget. On the patch question: 3.5.7.20 was installed on the affected machine and the spin survived it, so the patch removed neither the spin nor the exception there.
Recommendation: when the task must run once per request, keep the Status task and make its last statement clear the trigger variable; that removes the exception at any patch level. When the logic must repeat for as long as a condition holds, replace the Status task with a cyclic task at a written interval, for example 100 ms, and gate the body with a condition test. Leave ProcessorLoad.Maximum at its shipped value: the watchdog is what told you the task was spinning.
Questions
Does updating the runtime patch stop the spin?
On the machine that showed this fault, the 3.5.7.20 patch was installed and the spin survived it. A scheduler fix shipped in 3.5 SP7 Patch 2, and whether it matched this fault stayed unclear. Updating is still worth doing, but the self-clearing fix works at any patch level, because it removes the level trigger instead of hoping the scheduler changes.
Why did the fault appear after the move to Windows 10 and 3.5 SP7?
The task configuration moved with the project unchanged. What changed around it is the runtime version and the host. Control Win V3 is a soft PLC on Windows, and Windows 10 sets the thread priorities and timing it runs with. If the machine needs deterministic execution, the realtime variant of the runtime, Control RTE, is the product for that requirement.
What happens if two writers can set the trigger variable?
After the fix, FALSE works as the acknowledgement. If a second writer sets the variable TRUE while the task body sits between its logic and its reset, that request is cleared without being served. When several sources can ask for a run, give each requester its own bit in a request word and clear only the bit you served, or use a request and acknowledge pair.
Is there a setting that paces a Status task?
No. The Status task configuration takes a condition variable and offers no interval to set; the scheduler restarts the task for as long as the condition reads TRUE. Pacing comes from the task type: an Event task gives one execution per rising edge, and a cyclic task runs at the interval you write, for example 100 ms. Pick the type for the behavior, then gate the body with a condition test if needed.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.