Measuring OB Execution Time and CPU Load on S7-1500 with RT_INFO

David Krause16 min read
SiemensTechnical ReferenceTIA Portal
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview: Why OB Execution Time Matters

On a SIMATIC S7-1500 CPU such as the 1516-3 PN/DP, the user program is not a single monolithic scan; it is partitioned into Organization Blocks (OBs) that the operating system schedules by priority. Background OBs (OB 90), the main cyclic OB (OB 1), cyclic interrupt OBs (OB 30 to OB 38), time-of-day OBs (OB 10 to OB 17), delay OBs (OB 20 to OB 23), hardware interrupt OBs (OB 40 to OB 47), synchronization OBs (OB 61 to OB 64), and event-driven OBs (OB 80, OB 82, OB 121, OB 122) all compete for the same CPU resource. Each OB has its own start time, its own execution duration, and its own contribution to total CPU load.

Knowing the per-OB execution time is essential for capacity planning, for detecting scan-time creep after a functional change, for sizing the OB 1 maximum cycle watchdog, and for determining whether communication, motion, or background tasks are starving the main program. The TIA Portal exposes some of this information through Online & Diagnostics > Cycle Time, but that view aggregates the entire scan. To isolate the contribution of an individual OB, the engineer needs the RT_INFO instruction and the PREV_CYCLE tag of OB 1.

This reference covers the priority model that drives OB scheduling on the S7-1500, the distinction between the OB 1 cycle and the overall scan, the parameter set of RT_INFO, the role of OB 80 in cycle-time monitoring, and a structured implementation pattern that drops directly into TIA Portal V18, V19, or V20 projects.

OB Architecture and Priority Model in S7-1500

OBs on the S7-1500 are executed exclusively on a priority basis. When multiple OB requests are pending, the operating system always services the OB with the highest priority first. The priority class is fixed by the OB type and cannot be changed by the user; only the OB number identifies the OB.

OB Type OB Numbers Priority Class Trigger Source
Main (cyclic) OB 1 1 Free cycle, restart
Time-of-day OB 10 to OB 17 2 Configurable time/date
Delay OB 20 to OB 23 3 to 6 Delay event after start
Cyclic interrupt OB 30 to OB 38 7 to 15 Fixed interval (e.g. 1 ms, 10 ms)
Hardware interrupt OB 40 to OB 47 16 to 23 Process event on channel
Synchronous (motion) OB 61 to OB 64 25 PROFIdrive/PROFINET cycle
Time error OB 80 26 Scan-time overrun, missing OB
Diagnostic interrupt OB 82 26 Module diagnostic event
Pull/plug OB 83 26 Module slot change
Background OB 90 29 Idle time of OB 1
Startup OB 100 / 101 / 102 27 Cold/warm restart / re-init
Programming error OB 121 Priority of causing OB Runtime fault in user code
I/O access error OB 122 Priority of causing OB Failed direct I/O access

Refer to the official description of Events and OBs (S7-1500) in the functional description manual for the definitive priority assignment per firmware generation. The single most important operational consequence of this model is that a cyclic interrupt OB running at 1 ms with priority 7 will preempt OB 1 on every cycle, so measuring OB 1 alone will not show the true workload.

Cycle Time vs. OB Execution Time: Clarifying the Distinction

The value reported by TIA Portal at Online & Diagnostics > Cycle Time is the total scan time, not the duration of OB 1. Total scan time includes:

  1. OB 1 user code execution
  2. Preemption time from cyclic interrupt OBs (OB 30 to OB 38)
  3. Preemption time from hardware interrupt OBs (OB 40 to OB 47)
  4. Preemption time from synchronous OBs (OB 61 to OB 64) when motion control is configured
  5. Communication processing (open communication, S7 communication, OPC UA, FETCH/WRITE, HMI tag service)
  6. Operating system housekeeping (task switching, I/O image update, diagnostics)

For a CPU 1516-3 PN/DP with three cyclic interrupt OBs and one synchronous OB, the displayed cycle time is the wall-clock period between two successive starts of OB 1, expanded by every higher-priority event that interrupted OB 1 during the scan. This is the value that OB 80 monitors against the configured maximum cycle time.

To get the execution time of a single OB, two data sources are available:

  • OB 1 PREV_CYCLE tag (LREAL, milliseconds): previous OB 1 execution time, only valid for OB 1.
  • RT_INFO instruction: per-OB runtime, call count, and CPU/communication load for any OB.

OB 1 PREV_CYCLE: Reading the Main Cycle Time

OB 1 carries two system-supplied LREAL tags that are visible in the block interface:

  • PREV_CYCLE (LREAL, in ms): duration of the previous OB 1 pass.
  • CURR_CYCLE is not exposed on OB 1 directly; the cycle time is sampled at the next entry.

A typical capture pattern uses an FB with multi-instance DBs that records the value into a ring buffer on each pass:

// FB "CycleRecorder" interface
VAR
    Samples : ARRAY[1..1000] OF LREAL;   // ring buffer
    Index   : INT;                       // 1..1000
END_VAR

// On first call
IF Index = 0 THEN Index := 1; END_IF;
Samples[Index] := "Main".PREV_CYCLE;   // OB 1 tag
Index := Index MOD 1000 + 1;

PREV_CYCLE only reflects the OB 1 segment. If a cyclic interrupt OB fires during the scan, that time is excluded from PREV_CYCLE but included in the total cycle time, so a comparison of PREV_CYCLE against the TIA Portal cycle-time display is a quick way to see how much OB 1 is being preempted.

RT_INFO Instruction: Granular Per-OB Measurement

The RT_INFO instruction is the primary tool for per-OB measurement on S7-1500. It is available in TIA Portal under Instructions > Extended instructions > Diagnostics. The block interface is:

Parameter Direction Type Meaning
OB IN INT OB number to query
MODE IN BYTE Selects the data returned
LADDR IN WORD Sub-address (not used for mode 1 / 10 / 11 / 20 / 21)
RET_VAL OUT LREAL Returned value

Mode selection matrix:

MODE Returned Value (RET_VAL) Unit Use
1 Last execution time of OB identified by OB parameter ms Per-OB runtime
2 Last execution time of OB identified by LADDR parameter ms Per-OB runtime via instance DB address
3 Number of calls of OB identified by LADDR since last restart count Invocation count
10 Current CPU load (user program) % Live CPU load
11 Maximum CPU load since last restart % Peak CPU load
20 Current communication load % Live comm load
21 Maximum communication load since last restart % Peak comm load

Calling RT_INFO for an OB that is not loaded on the CPU returns 0.0 without raising an error. Calling RT_INFO for an OB number that does not exist returns 0.0 and sets the ENO enable output to 0 with the diagnostic status 16#0000 in ENO-driven error evaluation.

Worked Example: Five Background OBs and Three Cyclic Interrupts

The user's CPU 1516-3 PN/DP has five OB 90 instances and three cyclic interrupt OBs (e.g., OB 30 at 10 ms, OB 31 at 20 ms, OB 35 at 100 ms) plus one synchronous OB (OB 61). To capture each runtime, build a single FB called once per OB 1 scan:

// FB "OB_Load_Monitor" body (SCL)
"Runtime".OB := 1;
"Runtime".MODE := 1;
"Runtime".LADDR := 0;
"Runtime".RET_VAL;            // value in ms
OB1_ms := "Runtime".RET_VAL;

"Runtime".OB := 30;  OB30_ms  := "Runtime".RET_VAL;
"Runtime".OB := 31;  OB31_ms  := "Runtime".RET_VAL;
"Runtime".OB := 35;  OB35_ms  := "Runtime".RET_VAL;
"Runtime".OB := 61;  OB61_ms  := "Runtime".RET_VAL;
"Runtime".OB := 90;  OB90_ms  := "Runtime".RET_VAL;

"CPU".OB := 0; "CPU".MODE := 10; CPU_Load_Act := "CPU".RET_VAL;
"CPU".MODE := 11; CPU_Load_Max := "CPU".RET_VAL;
"Comm".OB := 0; "Comm".MODE := 20; Comm_Load_Act := "Comm".RET_VAL;
"Comm".MODE := 21; Comm_Load_Max := "Comm".RET_VAL;

The actual scan time is then reconstructed from:

// Estimated cycle time (ms)
EstimatedCycleTime := OB1_ms + OB30_ms + OB31_ms + OB35_ms + OB61_ms + OB90_ms;

This reconstruction will be close to, but slightly below, the TIA Portal cycle-time value because the OS housekeeping (I/O image update, task switching, PROFIBUS/PROFINET acyclic services) is not attributed to any user OB.

TIA Portal Online & Diagnostics: Cycle Time Display

The Cycle Time diagnostic panel is reached by selecting the PLC in the project tree, going online, and opening Online & Diagnostics > Cycle Time. The panel reports:

Field Meaning
Current cycle time Latest OB 1 period, including all preemptions
Minimum cycle time Lowest observed since last RUN-STOP-RUN transition
Maximum cycle time Highest observed since last RUN-STOP-RUN transition
Configured maximum Watchdog threshold (drives OB 80)

This view also includes the OB 1 minimum and maximum values, which can be used to bound the OB 1 contribution inside the larger cycle time envelope. The Siemens KB article How do you measure the total cycle time of a program? (entry ID 87668055) covers the methodology on both S7-1200 and S7-1500 and is the canonical reference for the Online & Diagnostics panel.

Field-proven caveat: the "Current cycle time" updates only on OB 1 entry, not continuously. If the cyclic interrupt OB at 1 ms fires and overruns for 500 ms, the panel will not refresh during the overrun; the value jumps once OB 1 finally starts again. Use RT_INFO mode 11 to capture the high-water mark.

OB 80 Time Error Interrupt: Detection and Response

The time error interrupt OB (OB 80) executes whenever the scan cycle exceeds the configured maximum cycle time, or when a time error event such as a referenced OB not being loaded occurs. See the official description at Time error interrupt OB.

OB 80 receives a temporary variable OB80_FLT_ID that identifies the event type:

FLT_ID (hex) Meaning Typical Cause
16#00xx Cycle time exceeded OB 1 over watchdog threshold
16#01xx OB call not possible Referenced OB not loaded
16#02xx Time error during OB processing Cyclic interrupt too close together
16#05xx Queue overflow Event source firing faster than serviced
16#07xx Timeout Operating system internal

When OB 80 is configured, the CPU logs the event and continues; without OB 80, the same condition drives the CPU to STOP. The maximum cycle time is configured in TIA Portal under PLC properties > Cycle time monitoring. The default on the S7-1500 is 150 ms; values below 5 ms are not supported.

A robust OB 80 body should latch the fault, capture RT_INFO mode 11 (max CPU load) at the moment of the error, and either trigger an alarm or shed non-essential loads:

// OB 80 body (SCL)
IF "DLT".OB80_FLT_ID = 16#0001 OR "DLT".OB80_FLT_ID = 16#0002 THEN
    // Cycle-time overrun
    "HMI_Alarm".CycleTimeError := TRUE;
    "HMI_Alarm".FLT_ID := "DLT".OB80_FLT_ID;
    "HMI_Alarm".FLT_TIME := "DLT".OB80_TIME_STAMP;
    "HMI_Alarm".CPU_Load_Max := "Load_Recorder".RT_INFO("CPU", 11, 0);
END_IF;

CPU Load Calculation and Formulas

The CPU load is defined as the share of the scan period consumed by user-program execution. For the OB 1 main cycle, the instantaneous load is:

CPU_Load_OB1 (%) = (PREV_CYCLE / Scan_Period) * 100

For the total CPU load including all OBs, the relationship between per-OB runtime, period, and load is:

OB_i_Load (%) = (OB_i_Runtime_ms / OB_i_Period_ms) * 100
Total_Load (%) = SUM_i (OB_i_Runtime_ms / OB_i_Period_ms) * 100 + Comm_Load_Act

Worked example with the user's CPU 1516-3 PN/DP:

OB Runtime (ms) Period (ms) Load (%)
OB 1 (main) 8.0 20 40.0
OB 30 (cyclic 1 ms) 0.4 1 40.0
OB 31 (cyclic 2 ms) 0.3 2 15.0
OB 35 (cyclic 100 ms) 2.0 100 2.0
OB 61 (synchronous) 1.5 2 75.0 (on motion segment)
OB 90 (background) 0.5 200 0.25

Aggregate load before OS overhead is approximately 172% of the configured segments, which cannot exceed 100% of CPU bandwidth; in practice these intervals do not all overlap every scan, and the OS load (comm + housekeeping) is what RT_INFO mode 10 reports directly. The formula above is useful for the S7-1500 sizing spreadsheet when designing a system before firmware deployment.

Implementation: Structured Code Example

A complete diagnostic FB in SCL for TIA Portal V18+:

FUNCTION_BLOCK "OB_Load_Monitor"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
       ScanPeriod_ms : LREAL := 20.0;     // configured OB 1 period
       Enable : BOOL := TRUE;
   END_VAR
   VAR_OUTPUT
       OB1_Runtime_ms : LREAL;
       OB30_Runtime_ms : LREAL;
       OB31_Runtime_ms : LREAL;
       OB35_Runtime_ms : LREAL;
       OB61_Runtime_ms : LREAL;
       OB90_Runtime_ms : LREAL;
       CPU_Load_Act_pct : LREAL;
       CPU_Load_Max_pct : LREAL;
       Comm_Load_Act_pct : LREAL;
       Comm_Load_Max_pct : LREAL;
       EstimatedCycleTime_ms : LREAL;
   END_VAR
   VAR
       RT_OB   : RT_INFO;     // per-OB
       RT_CPU  : RT_INFO;     // CPU load
       RT_Comm : RT_INFO;     // comm load
   END_VAR
   VAR_TEMP
       iRet : LREAL;
   END_VAR
BEGIN
    IF NOT Enable THEN RETURN; END_IF;

    // Per-OB runtime
    RT_OB(OB := 1,  MODE := 1, LADDR := 0, RET_VAL => OB1_Runtime_ms);
    RT_OB(OB := 30, MODE := 1, LADDR := 0, RET_VAL => OB30_Runtime_ms);
    RT_OB(OB := 31, MODE := 1, LADDR := 0, RET_VAL => OB31_Runtime_ms);
    RT_OB(OB := 35, MODE := 1, LADDR := 0, RET_VAL => OB35_Runtime_ms);
    RT_OB(OB := 61, MODE := 1, LADDR := 0, RET_VAL => OB61_Runtime_ms);
    RT_OB(OB := 90, MODE := 1, LADDR := 0, RET_VAL => OB90_Runtime_ms);

    // CPU and communication load
    RT_CPU(OB := 0, MODE := 10, LADDR := 0, RET_VAL => CPU_Load_Act_pct);
    RT_CPU(OB := 0, MODE := 11, LADDR := 0, RET_VAL => CPU_Load_Max_pct);
    RT_Comm(OB := 0, MODE := 20, LADDR := 0, RET_VAL => Comm_Load_Act_pct);
    RT_Comm(OB := 0, MODE := 21, LADDR := 0, RET_VAL => Comm_Load_Max_pct);

    // Reconstructed cycle time
    EstimatedCycleTime_ms := OB1_Runtime_ms + OB30_Runtime_ms
                           + OB31_Runtime_ms + OB35_Runtime_ms
                           + OB61_Runtime_ms + OB90_Runtime_ms;
END_FUNCTION_BLOCK

Call this FB unconditionally once per OB 1 scan from the main program. For a faster snapshot of the live CPU load, place a second instance inside a 100 ms cyclic interrupt OB so the HMI tag updates without waiting for OB 1 to complete.

Verification and Commissioning Checklist

  1. Compile and download the project to the CPU 1516-3 PN/DP.
  2. Go online and open Online & Diagnostics > Cycle Time. Confirm that the displayed cycle time matches the reconstructed value from RT_INFO mode 1 within ±5%. Discrepancy indicates OS overhead (PROFINET acyclic, etc.).
  3. Force the CPU into a high load by enabling a debug counter or a test loop in OB 1. Confirm that the maximum cycle time in TIA Portal tracks RT_INFO mode 11.
  4. Temporarily reduce the configured maximum cycle time to a value just above the OB 1 expected runtime and verify that OB 80 fires with FLT_ID = 16#0001 when the overrun occurs.
  5. Check the diagnostic buffer for OB 80 events using Online & Diagnostics > Diagnostics Buffer. Each event should show the FLT_ID and the time stamp.
  6. Export the runtime tags to the HMI trend view; cycle for at least one hour of normal operation and verify that the OB runtime trends remain stable within ±10%.
  7. Confirm that the OB 90 background OB only runs when OB 1 has spare time; the OB90_Runtime_ms tag should remain near zero when CPU load exceeds 80%.

Troubleshooting Matrix

Symptom Likely Root Cause Diagnostic Action Resolution
OB 1 PREV_CYCLE jumps to 5–10 ms but TIA Portal shows 200 ms Cyclic interrupt or synchronous OB is preempting OB 1 Read RT_INFO mode 1 for OB 30/31/61 Spread cyclic interrupt load or raise OB 1 priority
CPU goes to STOP with diagnostic buffer entry "Time error" OB 80 not loaded; max cycle exceeded Add OB 80, lower max cycle, examine buffer Add OB 80 and raise max cycle to OB 1 measured peak + 25%
RT_INFO mode 10 returns 0% while OB is clearly executing Mode 10 is sampled at start of OB 1, not within OB Sample multiple times or use mode 11 Use mode 11 to get maximum load
OB 90 runtime stays at zero even at low load OB 90 not configured or scan is fully occupied Check PLC properties > OBs > OB 90 Add OB 90 and verify it executes in idle slots
Communication load (mode 20) exceeds 50% Too many HMI tags polled, or OPC UA server heavy Reduce tag count, increase update interval Tune HMI polling or split communication load
OB 35 (100 ms cyclic) misses cycles Previous OB 35 still running when next trigger fires Compare mode 3 count vs expected count Reduce OB 35 runtime or extend period
Cycle time creeps after firmware update New firmware added OS background tasks Compare OB 1 PREV_CYCLE pre/post update Allow for new baseline; raise max cycle accordingly
RT_INFO RET_VAL = 0 for an OB that is in the program OB has not yet executed since last restart Force a RUN-STOP-RUN transition After restart, allow OB to fire once; then read

Field Notes and Best Practices

  • Always configure OB 80 in production systems. Without it, a single cycle overrun halts the plant.
  • Set the maximum cycle time to OB 1 measured peak + 25% to leave headroom for cyclic interrupts and OS overhead.
  • Use RT_INFO mode 11 (maximum CPU load) for alarming rather than mode 10, since mode 10 is sampled at the OB 1 start and can miss transient peaks.
  • Record the OB runtime trend over a full production shift, not just a single cycle; many scan-time spikes correlate with HMI tag bursts at shift change.
  • When migrating from S7-300/400 to S7-1500, note that the S7-1500 RT_INFO returns milliseconds as LREAL; the legacy SFC 78 returned DWORD microseconds. Adjust scaling in any legacy code paths.
  • When sizing a new CPU, use the CPU specification table for "Bit execution time" (e.g. 30 ns for CPU 1516) to convert instruction count into expected runtime, then verify with RT_INFO after commissioning.
  • Disable RT_INFO polling when not needed; each call adds a small OS service overhead that shows up in OB 1 PREV_CYCLE.

Frequently Asked Questions

What does the "Cycle Time" in TIA Portal Online & Diagnostics show?

The Cycle Time panel reports the full OB 1 period, including OB 1 itself plus any preemption from cyclic interrupt OBs, hardware interrupt OBs, synchronous OBs, communication processing, and OS housekeeping. It is not the OB 1 execution time alone.

How do I measure the execution time of an individual OB on S7-1500?

Use the RT_INFO instruction with MODE = 1 and set the OB parameter to the target OB number. The RET_VAL returns the last execution time of that OB in milliseconds (LREAL). Modes 2 and 3 return the runtime and call count identified by LADDR.

What is the difference between RT_INFO mode 10 and mode 11?

Mode 10 returns the current CPU load (user program percentage) sampled at the moment of the call. Mode 11 returns the maximum CPU load observed since the last RUN-STOP-RUN transition. Use mode 11 for alarms and trending; use mode 10 only for live HMI display.

Why does my CPU go to STOP with a time error when OB 80 is missing?

OB 80 is the time error interrupt OB and executes when the scan cycle exceeds the configured maximum cycle time or when a referenced OB is not loaded. Without OB 80, the CPU cannot handle the error and enters STOP mode. Configure OB 80 and set the maximum cycle time to OB 1 measured peak plus 25%.

Can I read the previous OB 1 cycle time without using RT_INFO?

Yes. OB 1 carries a temporary LREAL tag called PREV_CYCLE in its block interface. Use it directly in the OB 1 static code. Note that PREV_CYCLE only reflects OB 1 itself and excludes preemptions from higher-priority OBs.

Back to blog