B&R Execution Model: Cyclic Task Scheduling, IEC 61131-3 Semantics, and Watchdog Behavior
Overview
B&R Automation Runtime uses a deterministic, priority-based preemptive multitasking system built on VxWorks. Programs written in IEC 61131-3 languages (Ladder Diagram, Structured Text, Function Block Diagram, Instruction List, Sequential Function Chart) and ANSI C are executed in cyclically-repeating task classes with configurable priorities and cycle times. Understanding this model is essential for diagnosing timing-related bugs, cycle time violations, and SERVICE mode entries on undocumented machines.
Priority System
Automation Runtime uses a deterministic, priority-based preemptive multitasking system built on a real-time operating system (RTOS) derived from VxWorks. B&R does not publicly document the exact RTOS version or whether it uses a licensed Wind River VxWorks kernel or a B&R-developed RTOS, but the scheduling behavior is consistent with VxWorks’s priority-based preemptive scheduler with a hardware timer tick interrupt driving context switches.
B&R uses a priority range of 0 to 255, where higher numbers have higher priority. When multiple tasks want to run simultaneously, the higher-priority task always runs first. The RTOS tick timer (configurable, typically 1 ms) drives the scheduler’s periodic evaluation of task readiness.
The priority space is divided into four tiers:
| Priority Range | Tier | What Runs Here |
|---|---|---|
| > 230 | Hardware/Interrupt | HW interrupts, I/O scheduling. Higher priority than Cyclic #1. |
| 190–230 | Cyclic Tasks | Cyclic #1 (highest) through Cyclic #8 (lowest). Motion control, time-critical logic. |
| 4–190 | System Tasks | Ethernet, ANSL/TCP/UDP, file operations, logger, visualization, webserver, SDM, OPC-UA. |
| < 4 | Idle Tasks | No-op filler (IDLE at priority 0, TcIdleFiller at priority 3). |
Scheduler Internals
The RTOS scheduler uses a tick-driven, priority-based preemptive algorithm:
- Timer tick interrupt fires at the configured system tick rate (typically 1 ms on the CP1584, derived from the Intel Atom HPET or LAPIC timer)
- The tick ISR runs the scheduler: it checks all ready queues and dispatches the highest-priority ready task
- Preemption: If a higher-priority task becomes ready (via interrupt or timeout), the currently running task is immediately preempted — even mid-instruction
- Round-robin within priority: Tasks at the same priority level are scheduled round-robin
- Time slicing: B&R does NOT use time slicing within a priority level for cyclic tasks. Each cyclic task runs to completion (or until preempted) within its allocated window
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. This means on a system with a 1 ms tick, idle time granularity is 1 ms.
Memory Protection
The Intel Atom E640T provides hardware MMU/MPU capabilities, but B&R Automation Runtime uses them with specific scope:
- Kernel/user protection: The MMU protects the AR kernel and system memory from user task access — user tasks cannot corrupt the OS kernel or system structures
- Flat task model: All user tasks (cyclic, event, etc.) share a single flat address space with no task-to-task isolation. A buggy cyclic task CAN corrupt another cyclic task’s data. See ar-rtos.md Section 2.3 for details
- Page faults (accessing unmapped or protected memory) trigger EXCEPTION 7 (address error) or EXCEPTION 25314 (Page Fault) and result in SERVICE mode
- The Exception task class (EXC) has access to all memory spaces for error handling
- The integrated I/O processor uses DMA (Direct Memory Access) to update the I/O image in memory without CPU involvement
Interrupt Handling
Interrupts on the CP1584 follow the VxWorks interrupt model:
| Interrupt Source | Priority | Handler | Latency |
|---|---|---|---|
| CPU timer tick | 240+ | RTOS scheduler | Deterministic, typically < 5 us |
| X2X bus interrupt | ~235 | X2X driver | < 10 us |
| POWERLINK interrupt | ~233 | EPL driver | < 10 us |
| Ethernet RX interrupt | ~20 | Network driver | Variable (higher with high traffic) |
| USB interrupt | ~15 | USB driver | Variable |
| Exception (fault) | 255 (highest) | Exception handler | Immediate |
When an interrupt fires, the RTOS saves the current task’s context (registers, stack pointer, flags) and jumps to the registered interrupt handler. After the handler completes, the context is restored and the highest-priority ready task resumes.
Task Classes
B&R provides up to 8 cyclic task classes (Cyclic #1 through Cyclic #8), each with:
- A configurable cycle time
- A priority (Cyclic #1 = highest, Cyclic #8 = lowest)
- One or more assigned programs/tasks
- A configurable watchdog tolerance
- A configurable jitter tolerance
Default Cycle Times
| Task Class | Default Cycle Time | Typical Use |
|---|---|---|
| Cyclic #1 | 10 ms (default) | Motion control, time-critical I/O, PID loops |
| Cyclic #2 | 20 ms (default) | Standard logic, I/O processing |
| Cyclic #3 | 50 ms (configurable) | HMI updates, data exchange |
| Cyclic #4–8 | 100–1000 ms (configurable) | Recipe handling, logging, diagnostics |
The CP1584 has a shortest achievable task class cycle time of 400 µs (hardware limitation).
Task Class Execution Model
Each task class operates as follows:
- The cycle timer for the task class expires
- If a higher-priority task class is still running, the current class waits (preemptive priority)
- All programs/tasks assigned to the class execute sequentially within the class
- After all tasks complete, the class yields and waits for the next cycle
- I/O data is updated at specific synchronization points (see I/O Cycle section)
Time →
|---TC#1---|---TC#1---|---TC#1---|---TC#1---|
| ProgA | ProgA | ProgA | ProgA |
|----TC#2----|----TC#2----|----TC#2----|
| ProgB ProgC | ProgB ProgC | ProgB ProgC |
|-------TC#3-------|-------TC#3-------|
| ProgD ProgE ProgF | ProgD ProgE ProgF |
Jitter Tolerance
Each task class has a configurable jitter tolerance — the allowed deviation from the exact cycle time before an exception is triggered. This is different from the watchdog timeout (which covers total cycle time violations). Jitter tolerance is important for motion control applications where exact timing is critical.
I/O Cycle Synchronization
I/O data exchange is synchronized with the cyclic task system. This is a critical concept that differs from some other PLC platforms:
Synchronizing Tasks with the I/O Cycle
The I/O cycle runs independently and deterministically. Task classes can be configured to:
- Read inputs at the start of the task class cycle
- Write outputs at the end of the task class cycle
- Run synchronized with the I/O bus cycle (X2X, POWERLINK)
When a task class is synchronized to the I/O cycle:
- Input data is read from the I/O image at the start of the cycle
- Logic executes using that input data
- Output data is written to the I/O image at the end of the cycle
- Multiple task classes reading the same inputs see identical input data within one I/O cycle
The Integrated I/O Processor
The CP1584 has a dedicated I/O processor that processes I/O data points in the background. This means:
- I/O scanning runs independently of the main CPU task execution
- The I/O image in memory is continuously updated by the I/O processor
- Cyclic tasks read from a snapshot of the I/O image, not directly from hardware
This architecture provides excellent I/O performance but means that I/O timing is decoupled from task class timing.
Watchdog Behavior
Cycle Time Violations
A cycle time violation occurs when the sum of runtimes of all tasks in a task class exceeds the configured cycle time. This is the #1 cause of SERVICE mode entries (approximately 80% of all SERVICE mode events).
By default, a cycle time violation triggers:
- A system emergency stop
- The controller boots in ERROR mode
- The PLC then enters SERVICE mode
- All outputs are set to zero
- The error is logged in the AR logbook
Common Causes of Cycle Time Violations
- Infinite loops in IEC code (most common)
- Blocking I/O operations (e.g., waiting for a response in a cyclic task)
- Excessive computation in a fast task class
- String operations or memory allocation in cyclic code
- File I/O performed in a cyclic task
- Division by zero causing exception handling overhead
- Page faults from invalid memory access
Configuring Watchdog Tolerance
The watchdog tolerance for each task class can be increased to allow occasional overruns without triggering an emergency stop. However, this does not fix the underlying timing problem.
Task Idle Time and System Task Starvation
The Problem
Because cyclic tasks (priority 190–230) have higher priority than system tasks (priority 4–190), a long-running cyclic task class can starve system tasks of CPU time. This causes:
- Visualization updates to become sporadic or freeze
- OPC-UA responses to time out
- Ethernet communication to fail
- SDM data to become stale
- File operations to hang
- USB device discovery to fail
The Solution: Task Idle Time
The Task Idle Time / Idle Time Task Class mechanism reserves a portion of a cyclic task class’s time for system tasks to execute. This is configured in the CPU’s task class properties.
Default configuration:
- Idle Time Task Class: Cyclic #2 (20 ms cycle)
- Task Idle Time: 2 ms (last 2 ms of the 20 ms cycle)
During the idle time window:
- The affected task class is effectively moved to priority 2
- System tasks can run at their normal priority (4–190)
- If no system tasks need to run,
TcIdleFillerruns no-ops at priority 3 - Cyclic #1 (and any higher-priority cyclics) still preempt everything
SDM CPU Usage Reporting
The SDM reports CPU usage as: 100% - time spent at priority 0 (IDLE)
This means:
TcIdleFillerno-ops count as “CPU usage” even though the CPU is doing nothing- In SERVICE mode with default idle time, CPU usage appears artificially high (~50-60%) when the real usage is near 0%
- Don’t be alarmed by high SDM CPU readings in SERVICE mode — it’s the TcIdleFiller effect
Tuning the Idle Time
Guidelines for tuning without the original project:
- Minimum idle time: System tick (base timer for AR), must be a multiple of system tick
- Zero (0 µs) disables idle time entirely (dangerous — can starve all system tasks)
- Better to have frequent short windows: 2 ms every 20 ms is better than 200 ms every 2000 ms, even though both reserve 10% for background tasks
- Don’t put idle time in a low-priority task class even if it’s fast — use TC#3 at 50 ms rather than TC#8 at 10 ms
- The idle time follows the tolerance of its assigned task class — delays cascade if cyclics overrun
Exception Handling
Exception Types
| Exception | Trigger | Default Action |
|---|---|---|
| Cycle time violation | Task class exceeds cycle time | Emergency stop → SERVICE mode |
| Page fault | Invalid memory access | SERVICE mode, error logged |
| Stack overflow | Task stack exceeded | SERVICE mode, error logged (S/E LED error code) |
| Divide by zero | Division by zero in cyclic code | SERVICE mode |
| Hardware fault | FPGA error, RAM error | System halt (non-recoverable) |
| Watchdog | Watchdog timer expired | Emergency stop → SERVICE mode |
Exception Handling Configuration
The default behavior (emergency stop on cycle time violation) can be changed:
- Exception handling can be configured per task class
- Actions can be: ignore, log only, stop task, or emergency stop
- For production machines from defunct OEMs, it’s often safer to leave defaults (emergency stop) to prevent dangerous behavior from timing errors
Troubleshooting Execution Issues
Diagnosing Cycle Time Violations
- Check the AR logbook for cycle time violation entries (error codes typically in the 9xxx range)
- Use the Profiler in Automation Studio to see which task/function block is consuming time
- Check task class configuration — are cycle times realistic for the hardware?
- Look for blocking operations in cyclic code:
- File I/O (
FileOpen,FileRead) - Network operations (
TcpOpen, synchronous communication) WAITstatements or delay loops- String operations on long strings
- File I/O (
Diagnosing System Task Starvation
Symptoms:
- OPC-UA clients disconnect or time out
- Visualization freezes or updates erratically
- Ethernet communication fails intermittently
- New I/O modules plugged in are not detected
- Web interface becomes unresponsive
Solution:
- Check Task Idle Time configuration — increase if too small
- Move idle time to a higher-priority task class
- Reduce cycle times of lower-priority task classes
- Look for cyclic tasks that consistently overrun their cycle time
Monitoring Task Execution at Runtime
Without Automation Studio:
- PVI API — read task cycle time, max cycle time, current load per task class
- OPC-UA — if exposed, monitor task cycle time nodes
- System variables —
RTInfofunction block data (see system-variables.md) - AR logbook — check for cycle time warnings/violations
- SDM — monitor CPU usage, task class load indicators
Using RTInfo Function Block
The RTInfo function block from the BRSystem library provides runtime information about the current task class:
(* In structured text *)
rtInfo_0(enable := TRUE);
// Available outputs:
// rtInfo_0.cycletime - Current cycle time of this task class
// rtInfo_0.maxcycletime - Maximum cycle time recorded
// rtInfo_0.taskload - Current load of this task class
// rtInfo_0.tasknumber - Current task class number
Cycle Time Tolerance and Watchdog Configuration Details
Cycle Time vs. Maximum Cycle Time vs. Tolerance
B&R distinguishes between three related but distinct timing parameters per task class:
| Parameter | Exception Code | What It Checks | Default Behavior |
|---|---|---|---|
| Cycle Time | 144 | Total time for all tasks in the class must complete within this window | Emergency stop |
| Maximum Cycle Time | 145 | Peak cycle time must not exceed (cycle time + max tolerance) | Emergency stop |
| Cycle Time Tolerance | 144 (extended) | Extra time allowed beyond cycle time before violation is declared | Emergency stop |
The cycle time tolerance is an additional buffer beyond the base cycle time. If the base cycle time is 10 ms and the tolerance is 2 ms, the task class can run up to 12 ms before Exception 144 fires. After the tolerance window expires and the task still hasn’t completed, Exception 145 (maximum cycle time violation) fires.
Critical rule from B&R (AS 4.3.5 SP release notes): If a tolerance is defined that is NOT a multiple of the cycle time, the value is silently ignored — no error is displayed. The tolerance must be a multiple of the cycle time for it to take effect.
Adjusting Tolerance Without the Project
If you have Automation Studio but not the project source, you can still adjust tolerance via online changes:
- Connect to the PLC with a minimal project
- Login online
- Navigate to the target system configuration
- Locate the task class properties
- Increase the cycle time tolerance value
- Apply the online change — this takes effect immediately without stopping the PLC
This is a runtime band-aid only — it does not fix the underlying cause of the cycle time violation. See online-changes.md for the full procedure.
Watchdog Variants
B&R implements two watchdog mechanisms:
-
Task class watchdog — Per-task-class timer that fires if the class doesn’t complete within (cycle time + tolerance). This is the most common.
-
System watchdog — A hardware-level watchdog timer that resets the entire CPU if the RTOS kernel stops responding. This is a safety net for kernel-level hangs (e.g., driver deadlock, hardware fault). The system watchdog cannot be configured from Automation Studio.
If the system watchdog fires, the CPU performs a complete hardware reset — this is different from a SERVICE mode entry. The AR logbook will not contain an entry for this event because the logger didn’t get a chance to write it. A system watchdog reset is indicated by the CPU booting up with no log entry for the previous session.
Community-Sourced Troubleshooting Wisdom
PV_lkaddr() Causing Maximum Cycle Time Violation
A known cause of Exception 145 on B&R systems is the PV_lkaddr() function from the SYS_Lib library. This function is used to obtain the address of a variable for use with PV_xget()/PV_xset() direct memory access. The issue occurs when:
- An initialization section of a function block calls
PV_lkaddr()only once (as intended) - But the function block’s instance data is not properly initialized on first scan
- The call to
PV_lkaddr()triggers an expensive name resolution operation - This operation exceeds the cycle time tolerance, triggering Exception 145
Fix: If you encounter this pattern in the profiler, check the AR logbook for the specific task class and look for PV_lkaddr references. If you have the source code, add a guard flag to ensure PV_lkaddr() is only called after the task class has completed its first full cycle.
Profiler “Unknown” Cyclic Task
When profiling a PLC with a different version of Automation Studio than what was used to compile the original project, one of the cyclic tasks may appear as “unknown” in the profiler diagram. This is caused by a symbol version mismatch — the profiler cannot resolve function block names from a different AS version. This is not a real problem; it simply means you cannot see the individual function blocks within that task class.
Workaround: Use the same AS version (or the same major version) as the original project to get full profiler resolution. If you don’t know the original AS version, check the AR version on the PLC and install the corresponding AS version.
Tools > Upgrades Stopped Working (July 2026 Known Issue)
As of July 2026, there is an active B&R Community thread titled “Tools - Upgrades stopped working” with 7 responses. The B&R Upgrade Service, which runs as a Windows service and downloads AR firmware packages from B&R’s website, can stop functioning due to:
- Windows firewall changes blocking the service
- TLS certificate updates on B&R’s server
- Antivirus software quarantining downloaded upgrade files
- The service running under
LOCAL_SERVICEaccount without sufficient rights to write toC:\Temp
Fix steps:
- Delete everything in
C:\Temp - Restart the PC
- Start AS explicitly as Administrator
- Check that the B&R Upgrade Service is running (Windows Services)
- Try switching the service user from
LOCAL_SERVICEtoLOCAL_SYSTEMor vice versa - If still failing, check
C:\Users\<username>\AppData\Roaming\BR\Logging\Datafor error logs
Practical Gotchas for Undocumented Machines
-
Cycle time violations are the #1 cause of SERVICE mode. If a CP1584 keeps going into SERVICE mode and you don’t have the project, check the AR logbook first — it’s almost certainly a cycle time violation.
-
Default idle time setup masks problems. If someone moved the idle task class to a very slow cycle (e.g., TC#8 at 100ms), system tasks will respond very slowly, making the PLC appear “sluggish” without any visible error.
-
Task priorities are fixed — you can’t change the priority number. Only the cycle time, jitter tolerance, and idle time are configurable. If the original programmer put a slow operation in Cyclic #1, there’s no way to lower its priority without access to the project.
-
I/O synchronization matters for motion. If a task class handling motion control is NOT synchronized to the I/O cycle, the I/O data read by the motion task may be from a different cycle than expected, causing jerky motion or missed position capture events.
-
SERVICE mode stops ALL tasks. When the PLC enters SERVICE mode, no cyclic tasks run, no I/O is updated, and all outputs are zeroed. The machine literally stops. If outputs must be maintained during debugging, this must be configured in advance (which requires the project).
-
The reset button always enters SERVICE mode by default. Don’t press it during production.
-
CPU usage in SDM is not what you think. The SDM calculates CPU usage as
100% - time_at_priority_0. BecauseTcIdleFillerruns at priority 3 (not 0), its no-op time counts as “CPU usage”. In SERVICE mode, SDM will show ~50-60% CPU usage when the real usage is near 0%. On a running system, this effect is smaller but still present — the SDM always over-reports by the amount of time spent in TcIdleFiller. A community member measured: SDM reported 95.45% while the actual CPU usage (system tasks + I/O) was only ~37.9%. -
Don’t put idle time in a low-priority task class even if it’s fast. The idle time follows the tolerance of its assigned task class. Using TC#8 at 10ms means idle time is delayed by any higher-priority cyclic that runs long. Use TC#3 at 50ms instead — the higher priority ensures idle time windows are more predictable.
-
The profiler recording time must be at least 2× the slowest task class cycle. For intermittent faults, use 10+ seconds. If the profiler shows nothing despite cycle time violations, check the filter settings — the offending task class may be excluded.
-
System watchdog resets leave no log entry. If the CPU resets and there’s no log entry for the previous session, a system watchdog reset (kernel hang) is the likely cause. This is a hardware-level reset — the RTOS never got a chance to log anything.
Exception Task Classes (EXC)
Exception task classes handle fatal errors that occur while Automation Runtime is running and cannot be corrected by the OS alone. The EXC task class has the highest priority in the entire system — it interrupts all normal tasks, high-speed tasks, and interrupt tasks.
How Exception Handling Works
- An exception occurs while a normal task is running
- The normal task is immediately interrupted (EXC has absolute highest priority)
- The exception task assigned to EXC executes
- Processing of normal tasks resumes from the point of interruption
Exception Codes
| Exception # | Description | Common Cause |
|---|---|---|
| 2 | Bus error | Memory bus fault, DMA failure |
| 3 | Address error | Unaligned memory access |
| 4 | Illegal instruction | Corrupted code, wrong CPU target |
| 5 | Division by zero | Missing zero-check in cyclic code |
| 6 | Range overflow | Array index out of bounds |
| 7 | Null pointer | Dereferencing NULL pointer |
| 8 | Privilege violation | Accessing protected memory region |
| 10 | Unimplemented instruction | Code compiled for wrong CPU |
| 24 | Spurious interrupt | Interrupt with no handler |
| 128 | I/O Exception | IO module failure, bus communication error |
| 144 | TC cycle time violation | Normal cyclic task exceeded cycle time |
| 145 | TC maximum cycle time violation | Peak cycle time exceeded tolerance |
| 146 | TC Input cycle time violation | Input processing exceeded limit |
| 147 | TC Output cycle time violation | Output processing exceeded limit |
| 160 | HSTC maximum cycle time violation | High-speed task exceeded max cycle |
| 170 | CAN I/O exception | CAN bus communication failure |
Configuring Exception Tasks
In Automation Studio, exception tasks are configured per CPU:
- Right-click CPU → Insert Object → Exception
- Select the exception type (e.g., “Division by zero”, “TC cycle time violation”)
- Enable/disable execution of the exception task
- Assign a program to the exception task class
The EXC task class shares its global data area with Cyclic #1, enabling fast data exchange without PLC-global variables.
Practical note for undocumented machines: If the original project configured custom exception handlers, you won’t know what they do without the source code. The exception codes above are logged in the AR logbook regardless.
Interrupt Task Classes (IRQ)
Interrupt task classes handle asynchronous hardware events (triggered by hardware interrupts). IRQ tasks have higher priority than all normal cyclic tasks, but lower priority than exception tasks.
IRQ Task Characteristics
- Each interrupt-capable module can be assigned its own IRQ task
- The IRQ task is processed each time the corresponding hardware interrupt triggers
- Only available on B&R 2010 systems (X20, X67) — not supported on older B&R 2003/2005 hardware
- Useful for: hardware encoder triggers, high-speed digital input capture, external sync signals
Typical IRQ Sources
| Source | Use Case |
|---|---|
| Digital input module interrupt | High-speed part detection, emergency stop capture |
| Encoder module latch signal | Position capture at external trigger event |
| Timer interrupt | Precise timing for specialized applications |
| Communication module | CAN bus event-triggered processing |
Practical note: IRQ tasks are rarely used in standard machine control. If you find IRQ tasks configured on an undocumented CP1584, they’re likely handling high-speed measurement or encoder capture. The exception codes 170 (CAN I/O) and 128 (I/O Exception) are most relevant for IRQ-related diagnostics.
High-Speed Task Classes (HSTC)
High-speed task classes are activated by hardware interrupts rather than by the system scheduler. This provides lower latency and jitter than normal cyclic tasks.
Types of High-Speed Task Classes
| Type | Trigger | Use Case |
|---|---|---|
| Timer HSTC | Hardware timer interrupt | Ultra-fast cyclic processing below normal TC limits |
| RIO HSTC | Remote I/O cycle completion interrupt | Immediate access to fresh remote I/O data |
| MP HSTC | MP_trigger() function call | Multi-processor synchronization (legacy) |
Timer HSTC
Timer HSTCs use a dedicated hardware timer to trigger execution. The cycle time is configurable in Automation Studio and independent of the system scheduler. All tasks assigned to a Timer HSTC execute exactly once per cycle.
RIO HSTC
Remote I/O HSTCs are triggered by an interrupt generated at the end of each remote I/O cycle. The configured cycle time is the minimum — if the RIO cycle takes longer, the HSTC starts later accordingly.
Practical note for CP1584: The CP1584 supports Timer HSTCs and RIO HSTCs. The minimum Timer HSTC cycle time is lower than the minimum Cyclic #1 time (400 us). HSTCs are typically used only in specialized motion control or high-speed measurement applications.
Startup Behavior
Boot Sequence and Task Initialization
When the CP1584 powers on:
- BIOS/Bootloader executes (VxLD loader) — hardware init, memory test
- Automation Runtime kernel loads — VxWorks starts, drivers initialize
- System configuration is read from CF card — hardware config, network config
- INIT phase — all task classes execute their initialization subroutines once
- TRANSITION to RUN — I/O modules initialize, POWERLINK starts
- Normal cyclic execution begins — task classes cycle per their configuration
Task Structure: Init vs Cyclic
Every task in a task class has two parts:
| Part | Execution | Purpose |
|---|---|---|
| Initialization subroutine | Executed once during INIT phase | Set initial values, one-time setup, calibration |
| Cyclic part | Executed every cycle | Main control logic, I/O processing |
In Automation Studio, the initialization part is accessed via View → Init Subroutine.
Startup Modes
| Mode | Behavior | Outputs |
|---|---|---|
| Cold start | All variables initialized to default/initial values | Zeroed |
| Warm start | Retentive variables preserved, non-retentive re-initialized | Zeroed |
| INIT start | Runs initialization subroutines, then transitions to cyclic | Zeroed until program sets them |
The startup mode is configured in the CPU’s task configuration in Automation Studio. On an undocumented machine, the startup mode is unknown — you can determine it by observing whether retentive values survive a power cycle (warm start) or not (cold start). See retentive-data.md for details.
Task Configuration in Automation Studio
Without access to the original project, you cannot change task class configuration. However, understanding what’s configurable helps with diagnostics:
Configurable Parameters Per Task Class
| Parameter | Description | Default (Typical) |
|---|---|---|
| Cycle time | Time between executions | 10 ms (TC#1), 20 ms (TC#2) |
| Tolerance | Allowed overrun before exception | Same as cycle time |
| Jitter tolerance | Allowed deviation from exact timing | Configurable |
| Idle time | Reserved time for system tasks | 0 µs (explicit) |
| Exception handling | Action on cycle time violation | Emergency stop |
| I/O synchronization | Whether to sync I/O with this task | Configurable |
| Core assignment (multicore) | Which CPU core runs this task | Core 0 |
Creating a Task Class
In Automation Studio:
- Right-click CPU → Insert Object → Cyclic
- Set name, programming language, priority
- Configure cycle time, tolerance, jitter
- Assign programs to the task class
- Set exception handling behavior
Multicore Task Assignment
On multicore CPUs (CP3586, APC910, etc.), each task class can be assigned to a specific CPU core. The default configuration assigns all cyclic tasks to core 0. For the single-core CP1584, this is the only option.
AR 6.5 hard real-time multicore (released December 2025): Task classes can now be assigned to specific CPU cores via Automation Studio 6.5 — not just system tasks but hard real-time cyclic tasks. This enables deterministic parallel execution of time-critical logic (e.g., motion control on core 0, process logic on core 1). Configuration is available in the task class properties dialog in AS 6.5. AR 6.5 also adds hypervisor repair boot for resolving PCIe interrupt conflicts and extends ARsim to support 4 GB process memory.
See ar-rtos.md §3.6 for the full multicore version progression and firmware-version-mgmt.md §3.2 for AS 6.5 release details.
reACTION Technology
B&R’s reACTION technology provides microsecond-level I/O response by processing logic directly in the I/O module’s FPGA, bypassing the main CPU task cycle entirely.
How reACTION Works
- I/O module receives input change
- FPGA on the I/O module executes programmed logic immediately
- Output response in 1-10 µs (vs. 400 µs minimum on CPU)
- Results are also available to CPU tasks for monitoring/coordination
reACTION vs CPU Tasks
| Aspect | reACTION | CPU Cyclic Task |
|---|---|---|
| Response time | 1-10 µs | 400 µs minimum |
| Programming | Ladder Diagram only | All IEC 61131-3 languages |
| Complexity | Simple logic only | Full programming capability |
| I/O access | Local module only | All I/O in system |
| Monitoring | Limited (via CPU exchange) | Full (via variables, OPC-UA) |
Practical Relevance
If an undocumented machine uses reACTION for safety-critical or high-speed responses, you won’t see this logic in the CPU’s cyclic tasks. reACTION programs are stored on the I/O modules themselves. The only way to discover them is through the CF card project files or by connecting with Automation Studio and browsing the hardware configuration.
Key Findings
- B&R uses deterministic preemptive multitasking with 8 cyclic task classes, priority range 0–255 (higher = more important)
- Cyclic tasks always preempt system tasks — this is by design but can cause system task starvation
- Cycle time violations cause emergency stop by default — this is the #1 cause of SERVICE mode entries (~80%)
- The Task Idle Time mechanism reserves CPU time for system tasks (Ethernet, OPC-UA, visualization, SDM) within a designated cyclic task class
- SDM CPU usage is misleading — it counts TcIdleFiller no-ops as “usage,” making SERVICE mode appear loaded when it’s actually idle
- The CP1584’s integrated I/O processor handles I/O scanning independently of cyclic task execution
- I/O cycle synchronization is configurable per task class and critical for motion control applications
Advanced Diagnostics: Profiling Without the Full Project
Creating a Long Profiler
The Long Profiler is the primary tool for diagnosing cycle time violations and identifying which function blocks are consuming excessive time. It requires Automation Studio but does NOT require the project source code.
Prerequisites:
- Automation Studio (any version that supports the AR version on the target)
- Network connectivity to the CP1584
- The PLC does NOT need to be in SERVICE mode — the profiler can run on a running system
Procedure:
- Open Automation Studio (no project needed)
- Open → Profiler (or Tools → Profiler in some AS versions)
- Connect to the PLC: Settings → Auto Search or enter IP manually
- Login to the target (may need online password — see access-recovery.md)
- Configure the profiler:
- Recording time: At least 2× the cycle time of the SLOWEST task class (e.g., if TC#4 runs at 100 ms, record for at least 200 ms minimum)
- For intermittent faults, use 10,000 ms (10 seconds) or longer
- Set the number of samples high enough to capture the fault
- Start recording — let it run through multiple cycles
- Stop recording
- Analyze the results as a diagram (View → Diagram):
- Each task class appears as a colored bar
- Function blocks within each task class show as sub-bars with width proportional to execution time
- Look for tasks that span nearly the entire cycle time (approaching the tolerance)
- Look for spikes or occasional long executions that correlate with cycle time violations
- Export the profiler data (File → Export) for future reference
Reading the Diagram:
Time →
|---TC#1 (10ms)---|---TC#1 (10ms)---|---TC#1 (10ms)---|
| ProgA ████ | ProgA ████████ | ProgA ████ | ← Normal
| | ProgA ██████████| | ← VIOLATION: exceeded 10ms
|----TC#2 (20ms)--------|----TC#2 (20ms)--------|
| ProgB ████ ProgC ████| ProgB ████ ProgC █████████| ← ProgC occasionally slow
|-------TC#3 (50ms)-----------------------|
| [2ms IDLE] ProgD ██ [2ms IDLE] ProgE ██ | ← Idle time window visible
- The yellow “Idle tasks” section in the profiler output shows TcIdleFiller time
- The “unknown” cyclic task that sometimes appears in profiler output is caused by an Automation Studio version mismatch — the profiler cannot resolve symbols from a different AS version. This does NOT indicate a real problem.
Community-sourced tips (from B&R Community forum):
- The profiler must include at least two (2×) executions of the slowest task class, or the data is insufficient
- For intermittent faults that happen once per hour, consider recording continuously and saving profiler traces periodically
- If the profiler shows nothing even though cycle time violations occur, check that the task class executing the long-running code is included in the profiler’s filter settings
Using the Profiler in SERVICE Mode
The profiler works even when the PLC is in SERVICE mode. However, since no cyclic tasks are running in SERVICE mode, the profiler will show only:
- I/O system tasks
- System tasks (networking, SDM, visualization)
- TcIdleFiller no-ops
This is still useful for diagnosing whether a SERVICE mode issue is caused by system task overload (rare) vs. a cycle time violation that happened before SERVICE mode was entered (check the AR logbook).
Alternative Monitoring Without Automation Studio
When Automation Studio is not available, these methods provide cycle time monitoring:
PVI API Method
## Using PVI.py (see pvi-api.md for setup)
from pvi import *
pvi = PviConnection()
line = pvi.add_line('LN1', 'ANSL')
cpu = line.add_device('CP1', 'ANSL', '192.168.1.10')
## Read RTInfo system variables for each task class
## Task class cycle time variables are typically named:
## gTaskClass[n].CycleTime
## gTaskClass[n].MaxCycleTime
## gTaskClass[n].TaskLoad
## Where n is the task class number (0-7)
for i in range(8):
try:
ct = cpu.read_variable(f'gTaskClass[{i}].CycleTime')
mx = cpu.read_variable(f'gTaskClass[{i}].MaxCycleTime')
ld = cpu.read_variable(f'gTaskClass[{i}].TaskLoad')
print(f'TC#{i+1}: cycle={ct}ms, max={mx}ms, load={ld}%')
except:
break
OPC-UA Method
If OPC-UA is configured, browse the System namespace for task class nodes. Common node paths:
Root → Objects → System → TaskClasses → Cyclic#1 → CycleTime
→ MaxCycleTime
→ TaskLoad
Trend these values over time to detect gradual performance degradation.
SDM Web Interface Method
The SDM at http://<PLC_IP>/sdm shows:
- CPU usage percentage (with TcIdleFiller caveat noted above)
- Task monitor tab showing basic task class status
- This is the lowest-resolution method but requires zero setup
Automation Runtime 4 vs. 6: Execution Model Changes
If you are upgrading a CP1584 system from AR 4.x to AR 6.x, or migrating to newer hardware (CP1684, CP3686), these execution model changes are relevant:
| Aspect | AR 4.x (CP1584 typical) | AR 6.x (newer hardware) |
|---|---|---|
| Task classes | Up to 8 cyclic | Up to 8 cyclic (same) |
| Priority range | 0–255 | 0–255 (same) |
| TcIdleFiller behavior | Active as described | Same behavior, better visibility in profiler |
| SDM CPU usage | Misleading due to TcIdleFiller | Improved accuracy in some AR 6 versions |
| Min cycle time | 400 µs (CP1584) | 100 µs (CP3686 with faster CPU) |
| Multicore | Single-core only | Multi-core task assignment available |
| System tasks | Same priority tiers | More background tasks (mapp components, OPC-UA security) |
| PROFINET/ EtherCAT | Not available on CP1584 | Available on newer CPUs |
Key migration note: An AS 4.x project targeting AR 4.x cannot be downloaded to an AR 6.x target. The project must be migrated using Automation Studio 6’s built-in migration tool. B&R provides open-source migration scripts at github.com/br-automation-community/as6-migration-tools that detect deprecated libraries, function blocks, and configuration incompatibilities. The community awesome-B-R repository catalogs all available migration resources.
Practical impact for execution model: When migrating, cycle times must be re-evaluated because:
- AR 6.x has more system tasks running (mapp components, enhanced OPC-UA, security layers)
- The Task Idle Time may need to be increased to accommodate the additional background load
- If moving to multi-core hardware, task core assignment should be optimized (motion on one core, logic on another)
Detailed Exception Code Reference
The exception codes below are logged in the AR logbook and can be retrieved via FTP from C:\arlogsys.log, SDM, or OPC-UA. These are distinct from ACOPOS drive fault codes (see acopos-drives.md for those).
CPU/OS Exceptions (Hardware-Level)
| Exception # | Description | Common Cause | Severity |
|---|---|---|---|
| 2 | Bus error | Memory bus fault, DMA failure, bad RAM | Fatal → SERVICE |
| 3 | Address error | Unaligned memory access, pointer arithmetic bug | Fatal → SERVICE |
| 4 | Illegal instruction | Corrupted code, wrong CPU target compiled | Fatal → SERVICE |
| 5 | Division by zero | Missing zero-check before division | Fatal → SERVICE |
| 6 | Range overflow | Array index out of bounds, math overflow | Fatal → SERVICE |
| 7 | Null pointer dereference | NULL pointer access in IEC code or C | Fatal → SERVICE |
| 8 | Privilege violation | Accessing protected memory region | Fatal → SERVICE |
| 10 | Unimplemented instruction | Code compiled for wrong CPU architecture | Fatal → SERVICE |
| 24 | Spurious interrupt | Interrupt with no registered handler | Logged, may continue |
| 25314 | Page fault (EXCEPTION) | Invalid memory access (NULL dereference, corrupted pointer, shifted memory from online change) | Common intermittent fault — Fatal → SERVICE |
Interpreting Exception 25314 (Page Fault)
Exception 25314 is the most common cause of intermittent SERVICE mode entries (as opposed to the consistent Exception 144 cycle time violations). It indicates the CPU tried to access a memory page that is not mapped or protected.
Common causes on undocumented machines:
- Online code changes — When code is downloaded to a running PLC, memory addresses may shift. Pointer-based code (C programs, addresses of global variables) can become invalid. This is documented as “the primary risk of online code changes.”
- Corrupted retentive data — If the battery died and retentive data was partially corrupted, reading invalid pointers from retentive memory causes page faults on warm start.
- String buffer overflows — IEC 61131-3 STRING operations writing beyond buffer bounds.
- Array index out of bounds — Accessing an array element beyond the allocated memory, triggering a page fault at the unmapped page boundary.
- mapp component memory corruption — If a mapp component (OPC-UA, mapp View) has a bug, it may write to an invalid address.
Diagnostic approach:
- Check the AR logbook for the exact exception address — the faulting memory address is logged
- If the address is near zero (0x00000000-0x00001000), it’s a NULL pointer dereference
- If the address is in a specific range, it may indicate which library or variable is at fault
- The exception log includes the task class where the fault occurred
- If the fault is intermittent and correlates with online changes, the code was likely not properly designed for online modification
Community reference: B&R Community thread “Intermittent EXCEPTION Page Fault during startup – mvLoader mvrpctxtfmt threads” documents page faults occurring during PLC startup related to the mvLoader and mvrpctxtfmt threads, which handle module loading and format parsing. If you see these thread names in the exception log, the fault may be caused by a corrupted module on the CF card or an incompatible firmware/library combination.
Task Class Exceptions (Execution-Level)
| Exception # | Description | Common Cause | Severity |
|---|---|---|---|
| 128 | I/O Exception | IO module failure, X2X/POWERLINK bus error | Fatal → SERVICE |
| 144 | TC cycle time violation | Normal cyclic task exceeded its configured cycle time | #1 most common — Fatal → SERVICE |
| 145 | TC maximum cycle time violation | Peak/max cycle time exceeded tolerance | Fatal → SERVICE |
| 146 | TC Input cycle time violation | Input processing phase exceeded limit | Fatal → SERVICE |
| 147 | TC Output cycle time violation | Output processing phase exceeded limit | Fatal → SERVICE |
| 160 | HSTC maximum cycle time violation | High-speed task exceeded max cycle | Fatal → SERVICE |
| 170 | CAN I/O exception | CAN bus communication failure | Logged |
Interpreting Exception 144 (Cycle Time Violation)
This is the most frequently encountered exception on B&R systems:
- Check the AR logbook for the task class number and timestamp
- The log entry will include the task class ID and the cycle time that was exceeded
- Compare the exceeded time against the configured cycle time:
- If exceeded by 10-50%: Likely a code path that occasionally takes longer (e.g., conditional logic with extra computation)
- If exceeded by 2-10x: Likely an infinite loop or blocking operation
- If exceeded by 100x+: Likely a page fault or hardware fault
- Use the Long Profiler to identify the specific function block causing the overrun
- If you cannot use Automation Studio, check if the violation correlates with a specific I/O event (via OPC-UA trending of task cycle times)
Critical Section Exceptions
AR 6.x introduced enhanced exception codes for critical section violations:
| Exception | Description |
|---|---|
| CS timeout | Critical section wait time exceeded — possible deadlock |
| CS priority inversion | Low-priority task holding a lock needed by high-priority task |
| CS re-entry | Re-entering a critical section that is already held (recursive lock attempt) |
These indicate synchronization bugs in the application code. On an undocumented system with no source, these are extremely difficult to fix — the only practical solution is to identify the conditions that trigger them and avoid those operating conditions.
Cross-References
| Related File | Relevance |
|---|---|
ar-rtos.md | AR RTOS internals — task scheduler, process model, interrupt handling |
system-variables.md | System variables for monitoring task cycle times, CPU load, and watchdog status |
diagnostics-sdm.md | SDM Task Monitor for real-time cycle time observation without Automation Studio |
firmware.md | AR firmware architecture and how the execution model is loaded at boot |
memory-map.md | CPU memory map for understanding IO data access within task contexts |
online-changes.md | How online code changes affect running tasks and cycle time behavior |
safe-io-diagnostics.md | Safety task execution requirements and SIL-rated cycle time constraints |
ebpf-telemetry.md | Performance profiling and task execution monitoring techniques |
alarm-logging.md | Exception and watchdog event logging for cycle time violations |
cp1584-hardware-ref.md | CP1584 hardware specs affecting task execution (cycle time limits, FPU) |
custom-diagnostic-tools.md | Building custom cycle time monitoring tools on the PLC itself |
access-recovery.md | brwatch for no-project variable monitoring and CPU reboot |
python-diagnostics.md | Python scripts for automated cycle time logging and alerting |
troubleshooting-index.md | Scenario-based troubleshooting for cycle time violations (Exception 144) |