S7-300 PUT/GET Timing: CPU Priority Classes and OPC Execution

David Krause15 min read
S7-300SiemensTechnical Reference
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

S7-300 PUT/GET Timing: CPU Priority Classes and OPC Execution

Overview of S7 Communication

S7 Communication is the native Siemens protocol used to exchange data between SIMATIC S7 PLCs and between S7 PLCs and external systems such as OPC servers, HMIs, and other controllers. On the S7-300 and S7-400 platforms, S7 Communication rides on top of Industrial Ethernet (PROFINET), PROFIBUS, or MPI, depending on the CPU hardware. When a PC-based application — typically the SIMATIC NET OPC server or an HMI runtime — reads or writes tags on an S7-300 CPU, the data movement happens through one of the S7 Communication function blocks: PUT, GET, USEND/URCV, or BSEND/BRECV.

The behavior most engineers need to predict is when those instructions actually move data. PUT and GET are not executed instantly at the moment a user calls them; they participate in the S7 CPU's OB-based priority scheduler. Likewise, the OPC server does not maintain a real-time mirror of the PLC — it polls the CPU through S7 Communication whenever an OPC client request arrives. The remainder of this article dissects that scheduling model so PUT/GET latency and OPC refresh behavior can be predicted and tuned.

S7 CPU Execution Model

The S7-300 CPU uses a priority-based, preemptive scheduler. Every block of user code lives inside an Organization Block (OB), and every OB has a priority class assigned either by the CPU firmware (fixed classes for hardware-triggered OBs) or by configuration in HW Config or TIA Portal (for time-of-day, cyclic, and delay OBs). At any given moment the CPU is running the highest-priority OB whose trigger event has fired and that is not blocked.

Fixed OB Priority Classes

OB Name Priority Trigger
OB1 Main cyclic program 1 Cyclic, free cycle
OB10–OB17 Time-of-day interrupts 2 (configurable 2–24) Configured time/date
OB20–OB23 Delay interrupts 3–6 After SFC32 delay expires
OB30–OB38 Cyclic interrupts 7–15 (configurable) Configured interval (e.g. 100 ms)
OB40–OB47 Hardware interrupts 16–23 Rising/falling edge on DI, MSI/MSO, or PN I/O
OB55–OB57 DP interrupts 2 PROFIBUS DP diagnostic events
OB60 Multicomputing interrupt 25 SFC35 trigger
OB80 Time error 26 (or cause + 1) OB1 overrun, OB call missed
OB82 Diagnostic interrupt 24 I/O fault on a diagnostic-capable module
OB83 Insert/remove interrupt 24 Module insertion or removal
OB85 Program execution error 24 OB not loaded when event occurred
OB86 Rack failure 24 DP/PN master failure
OB87 Communication error 24 Communication fault
OB90 Background OB 0 Idle time in OB1
OB100–OB102 Startup 27 Restart / warm restart / cold restart

Critical scheduling rule: Any OB whose priority class is strictly greater than the currently running OB may interrupt it immediately. OB1 runs at priority 1; a hardware interrupt in OB40 fires at priority 16 and will preempt OB1 in microseconds. PUT/GET calls placed inside OB1 will pause — and partially lose their scheduling slot — every time an OB40–OB47 fires.

CPU Priority Class Interaction Diagram

S7 CPU Scheduler — Priority-Based Preemption Priority Time → 16 7 2 1 OB1 + PUT/GET call OB40 OB10 OB40 S7 Com time slice

PUT and GET Instruction Execution

PUT (FB15) writes data from the local CPU to a remote CPU, GET (FB14) reads data from a remote CPU into the local CPU. Both are S7 Communication blocks that operate over a configured S7 connection and run inside whichever OB calls them — typically OB1, but they can equally well be called from a cyclic interrupt OB if deterministic timing is required.

Step-by-Step Execution of GET

  1. The REQ input of the GET instance receives a rising edge (typically from a one-shot of the OB cycle counter).
  2. The CPU schedules the S7 Communication request in the next communication time slice of the running OB.
  3. The request is sent over the configured S7 connection (ID parameter, LADDR or partner parameters).
  4. The remote CPU's S7 Communication service receives the request and prepares a response.
  5. The response arrives at the local CPU in a subsequent communication time slice.
  6. The DONE bit goes TRUE for one scan, ERROR and STATUS provide the result.

Key Timing Truths

  • PUT and GET are not triggered by the OPC server. They are triggered by the OB cycle in which the block instance resides.
  • A PUT/GET request placed in OB1 will only fire once per OB1 cycle maximum (unless retriggered in the same scan).
  • If a higher-priority OB fires during the GET call, the call is paused; the communication state machine resumes when control returns.
  • The CPU allocates a configurable portion of every scan — by default ~10–20% — to communication processing. PUT/GET requests submitted in OB1 are buffered and serviced in that time slice.

PUT Instance Parameter Block (S7-300/400 STL)

DATA_BLOCK DB200 "PUT_DB"
// Instance data block for PUT block (FB15)
// Adjust to your application
BEGIN
  // Inputs (driven from OB1 or cyclic OB)
  REQ    := FALSE;            // Trigger: rising edge starts a write
  ID     := W#16#0001;        // S7 connection ID from NetPro/PCD
  DONE   := FALSE;            // Set by FB15: write complete (one scan)
  ERROR  := FALSE;            // Set by FB15: error occurred
  STATUS := DW#16#00000000;   // Set by FB15: detailed status code
  // Remote CPU addresses (max 4 ranges, max 160 bytes total)
  ADDR_1 := P#DB100.DBX 0.0 BYTE 50;
  ADDR_2 := P#M 200.0 BYTE 30;
  ADDR_3 := P#DB120.DBX 0.0 BYTE 40;
  ADDR_4 := P#E 0.0 BYTE 40;       // not allowed in remote — example
  // Local source data (must match ADDR_n byte counts)
  SD_1   := P#DB200.DBX 0.0 BYTE 50;
  SD_2   := P#M 0.0 BYTE 30;
  SD_3   := P#DB210.DBX 0.0 BYTE 40;
  SD_4   := P#M 50.0 BYTE 40;
END_DATA_BLOCK

// Call in OB1
CALL "PUT_DB" , DB200 ;

Data Size Limits

Block Direction Max Data Acknowledged Typical Use
PUT (FB15) PLC → Remote 160 bytes Yes Small writes, recipe download
GET (FB14) PLC ← Remote 160 bytes Yes Small reads, status polling
BSEND (FB12) PLC → Remote 32 768 bytes Yes Large block writes
BRECV (FB13) PLC ← Remote 32 768 bytes Yes Large block reads
USEND (FB8) PLC → Remote 4 bytes No Fast unacknowledged sends
URCV (FB9) PLC ← Remote 4 bytes No Fast unacknowledged receives

PUT/GET cap at 160 bytes because each block call constructs a single S7 Communication SDU (Service Data Unit) containing user data plus four address descriptors. For data volumes exceeding that, BSEND/BRECV fragment the data into multiple SDUs across multiple communication time slices.

BSEND and BRECV Behavior

BSEND/BRECV are the right blocks when a single exchange must move more than 160 bytes. From the CPU scheduling perspective they are identical to PUT/GET — they run inside the calling OB, use the same communication time slice, and are subject to the same priority preemption. The visible difference is that BSEND returns DONE only when the full buffer has been acknowledged, which can take multiple communication cycles for a 32 KB transfer. During that window, BSEND must continue to be called (typically from OB1) so the S7 Communication state machine can advance; if the calling OB is starved by higher-priority OBs, BSEND will take proportionally longer to complete.

For an S7-300 with a configured communication load of 20% and an OB1 cycle of 30 ms, a 4 KB BSEND typically completes in 30–80 ms; a 32 KB BSEND can take 250–650 ms. These numbers are rough — actual throughput depends on network latency and the partner's S7 Communication load. Always validate with PUT/GET/BSEND DONE/STATUS timing captured in the user program.

SIMATIC NET OPC Server Communication

The SIMATIC NET OPC server (now distributed as part of TIA Portal and the SIMATIC NET PC software) is the most common way for SCADA, MES, and historian systems to read S7-300/400 tags. The OPC server wraps an S7 Communication connection to the PLC and exposes each tag as an OPC item. Internally it uses GET (reads) and PUT (writes) over its single S7 connection to the PLC — there is no special "OPC protocol" on the wire.

OPC Request Lifecycle

OPC Client (SCADA / HMI) SIMATIC NET OPC Server S7-300 CPU (OB1 cycle) OPC Data Path via S7 Communication Read Req GET req GET resp Tag value Time-slice sched. ~10–20% of scan Synchronous / Asynchronous flags are PC-side ONLY

Synchronous vs Asynchronous — Where It Matters

The synchronous or asynchronous access type that OPC clients see refers strictly to the OPC client↔OPC server dialog on the PC side:

  • Synchronous read: OPC client thread blocks until the OPC server returns the value (or times out).
  • Asynchronous read: OPC client continues other work; OPC server invokes the client's callback when the read completes.

From the PLC's perspective, neither mode changes anything. Both modes result in exactly one S7 Communication GET being issued, and that GET is processed in the PLC's communication time slice as soon as scheduling allows. If the SCADA vendor advertises "asynchronous OPC for faster PLC refresh," that is misleading — what they really mean is that the SCADA application thread isn't blocked waiting on the OPC server.

OPC Server Configuration Touchpoints

Parameter Default Effect on PLC Refresh
S7 connection count 1 More connections → more PLC time slices consumed
Update rate (cache poll) 100 ms Lower → tighter CPU load
Single / multiple read per cycle Multiple Single-read recommended for determinism
Tag group bandwidth — Lower bandwidth → more time slices needed
PG/PC interface selection TCP/IP Auto Wrong selection → no S7 connection at all

Interrupt Protection and OB4x Handling

There is no single instruction in S7-300/400 to globally disable hardware interrupts at runtime the way some IEC 61131-3 runtimes expose DISABLE_INTERRUPTS. Instead, interrupt gating is achieved through several mechanisms:

  • SFC36 / SFC37 (SET_CLK / SET_CINT): Activate/deactivate time-of-day interrupts (OB10–OB17).
  • SFC32 / SFC33 / SFC34 (SRT_DINT / CAN_DINT / QRY_DINT): Start, cancel, and query delay interrupts (OB20–OB23).
  • SFC40 (EN_IRT) / SFC41 (DIS_IRT): Enable/disable interrupts generically (process, alarm, status, update, manufacturer).
  • Custom gating: Use a boolean flag in OB40–OB47 that is set by user logic when the protected section is active. Hardware interrupts during the protected window can be either ignored (counter incremented) or queued depending on logic.

SFC40 / SFC41 — Interrupt Gating Example

// In OB1, before entering critical section
CALL SFC 41 "DIS_IRT" ;          // Disable all interrupts
  MODE   := B#16#0;              // 0 = all interrupts
  OB_NR  := 0;                   // 0 = no specific OB filter

// ... critical user code (must be short, 

Leaving DIS_IRT active for longer than OB1 cycle can suppress OB80 time errors. Always pair SFC41 with a matching SFC40 before the OB1 cycle ends. If OB1 is so heavily loaded that SFC40 never runs, the CPU will eventually raise an OB85 program execution error indicating that OB80 was missed.

Why PUT/GET Are Not "Interrupt-Proof"

PUT and GET do not internally call SFC40/SFC41, so any OB40–OB47 that fires during a PUT/GET call will preempt it. If the preemption window is longer than the S7 partner's response timeout, the local PUT/GET will eventually fail with STATUS = W#16#80B1 or similar. The standard mitigation is to either (a) shorten the OB4x handler, (b) use OB90 background OB for non-critical code, or (c) call PUT/GET from a cyclic interrupt OB with a known, bounded duration.

Communication Time Slice Configuration

The communication time slice is configured per-CPU via HW Config (Step 7) or TIA Portal. The setting determines the maximum fraction of each scan dedicated to communication.

Setting Default Range Side Effect
Communication load (% of cycle) 20 % 5 % – 50 % Higher → faster comms, slower OB1
Scan cycle monitoring time 150 ms (default) 1 ms – 6 s Below 150 ms requires explicit confirmation
OB85 call behavior Special OB80 handling — Wrong setting → OB80 storms
Number of S7 connections CPU-dependent (typically 4–16) — More → more CPU RAM, slower table lookup

Reading Live CPU Load

System State List (SZL) entries report live cycle and load metrics. Read them via SFC51 "RDSYSST":

// Read OB1 cycle time and cycle count
CALL SFC 51 "RDSYSST" ;
  SZL_ID   := W#16#0A92;          // CPU runtime / load metrics
  INDEX    := W#16#0000;
  RET_VAL  := MW 100;             // 0 = success
  BUSY     := M 110.0;
  SZL_HEADER := MW 112;           // length / count
  DR       := P#DB 250 DBX 0.0 BYTE 34;

// After SFC51 completes (BUSY=FALSE), DB250 contains:
//   DBW0   – OB1 minimum cycle time (ms)
//   DBW2   – OB1 maximum cycle time (ms)
//   DBW4   – OB1 current cycle time (ms)
//   DBD6   – CPU utilisation % (x100)
//   DBW10  – Communication load %

Typical Timing Reference (S7-300 CPU 315-2 PN/DP)

Scenario OB1 Cycle PUT/GET Round-Trip Notes
Light load, no PROFINET IO 5–15 ms 30–80 ms 2–3 OB1 cycles per exchange
Medium load with 32 PROFINET IO devices 20–50 ms 80–250 ms Comm time slice shared with PN IO
Heavy load + cyclic OB35 @ 20 ms 30–80 ms 150–500 ms OB35 preemption fragments comms
S7-300 with 5 active S7 connections + OPC 40–100 ms 200–800 ms Connection round-robin arbitration

PUT/GET Status Codes Worth Memorising

STATUS Meaning Field Action
W#16#0000 Idle / no error None
W#16#0001 DONE — operation complete Process result
W#16#7000 REQ seen, request in progress Wait
W#16#7001 First request executing Wait
W#16#7002 Follow-up request executing Wait
W#16#80A0 Negative ack from partner Check partner CPU state
W#16#80A1 Partner rejected — DB not loaded Download missing DB
W#16#80A2 Partner rejected — wrong DB / write protection Check DB attributes
W#16#80B1 Partner timeout Check network, partner CPU STOP
W#16#80B2 Local connection not configured NetPro connection missing
W#16#80C3 Resource exhausted Reduce connection count
W#16#80D0 Wrong ID parameter Verify SZL W#16#0B99 for valid IDs
W#16#80F3 Address range error Check ADDR_n parameters

Verification Methods

Before deploying a PUT/GET or OPC integration, validate the actual latency against expected values using these methods:

  1. Timestamp DONE bit in user code — store a time stamp on REQ rising edge and on DONE rising edge; compute delta. Best field-proven method.
  2. SFC17 / SFC18 "SYNC_PI / SYNC_PO" — for process image consistency checks; not directly a comms verification but useful for interrupt coordination.
  3. SFC51 SZL read — read W#16#0A92 / W#16#0A91 entries for live cycle and load metrics (see code block above).
  4. SFC6 "RD_SINFO" — read OB1 start info to inspect the last scan time.
  5. SFC87 "C_DIAG" — read CPU diagnostic buffer; OB80/OB85/OB86 events reveal communication stalls.
  6. SIMATIC NET OPC Scout — built-in test client; reports round-trip and connection state per tag.
  7. Wireshark + S7 dissector — capture on the PROFINET segment and decode S7 Communication PDUs; visible immediately on the wire.

Troubleshooting Matrix

Symptom Likely Root Cause Diagnostic Step Fix
PUT/GET takes 1+ seconds Heavy OB4x preemption of OB1 SFC51 read W#16#0A92, check OB40 run-time Shorten OB4x handlers; move PUT/GET to OB35
OPC client shows "stale" data OPC refresh faster than PLC comm time slice Reduce OPC update rate to 500 ms Increase comm time slice to 30 %
GET completes then fails next cycle Connection table overflow Check STATUS = W#16#80C3 Reduce active S7 connections / OPC item count
PUT/GET STATUS = 80B1 Partner CPU STOP or network loss SFC87 diagnostic buffer; check partner LED Restore partner; check cabling
OPC server cannot establish connection Wrong PG/PC interface / no S7 connection in NetPro OPC Scout test connection Configure S7 connection in NetPro, select correct interface
Intermittent OB85 program errors OB90 background overflowed Diagnostic buffer OB85 entries Reduce background OB work; shorten OB1 cycle
OB80 time errors every few minutes OB1 cycle > scan monitoring time Diagnostic buffer OB80 entries Raise scan monitoring time, or shorten OB1
OPC tag reads return quality BAD S7 connection lost / PG/PC interface wrong OPC Scout → connection state Verify NetPro, fix Set PG/PC Interface selection

Practical Deployment Recommendations

  • Keep PUT/GET in OB1 by default. It is the simplest and most predictable. Only move to OB35 / OB36 if OB1 jitter is unacceptable and you can prove OB35 will run reliably.
  • For SCADA/OPC, prefer single-read OPC mode (one GET per tag group per cycle). It reduces S7 Connection load dramatically versus individual reads.
  • Configure communication load to 20 %–30 % for systems with mixed OB1 and PROFINET IO; 50 % is occasionally justified for heavy SCADA traffic.
  • Use BSEND/BRECV for > 160 B — never chain multiple PUT calls to compensate; the second PUT will queue behind the first and consume two full comm time slices.
  • Always size OB1 cycle margin to ≥ 2× the scan monitoring time. A 50 ms OB1 with a 100 ms monitor gives you no headroom for transient OB4x storms.
  • Document the connection ID ↔ partner mapping in the project header. STATUS W#16#80B2 is much easier to diagnose if you can read the ID-to-partner table from NetPro.

Standards and Reference Material

When exactly does a PUT/GET instruction execute in an S7-300 CPU?

PUT/GET execute inside whatever OB calls them — typically OB1 — and the actual S7 Communication request is processed during the CPU's communication time slice. They are not immediate; the request is buffered and sent when the scheduler reaches the comm slice, subject to preemption by higher-priority OBs such as OB40–OB47.

Does the SIMATIC NET OPC server read PLC data continuously or only on request?

Only on request, unless an explicit polling interval is configured in the OPC server. Each client read generates a GET over the S7 connection. The PLC does not maintain a continuous data stream to the OPC server — it responds inside its scheduled communication time slice, so refresh latency equals one or more OB1 cycles plus the comm slot.

Can S7 Communication interrupt OB1 execution?

No. PUT/GET and the communication time slice cannot preempt OB1 directly. They are part of the OB1 cycle or run in OB90 background. However, if OB1 calls PUT/GET and a hardware interrupt (OB40–OB47) fires during that call, the higher-priority OB immediately preempts OB1, suspending the PUT/GET state machine until OB1 regains control.

What is the maximum data size for PUT/GET vs BSEND/BRECV?

PUT and GET are limited to 160 bytes per call across all address ranges combined. BSEND and BRECV support up to 32 768 bytes (32 KB) per exchange. For any single exchange above 160 bytes, switch to BSEND/BRECV; chaining multiple PUT calls is slower and consumes twice the comm time slots.

How can I reduce PUT/GET latency in an S7-300 system?

Increase the CPU's configured communication load (HW Config → CPU properties → Communication) toward 30 %, shorten OB4x handlers or move PUT/GET to a cyclic interrupt OB with a bounded duration, lower the OPC server's update rate to match achievable PLC throughput, and use BSEND/BRECV when transfers exceed 160 bytes. Always verify by timestamping REQ and DONE in user code.

Back to blog