Problem Overview
An S7-300 station configured with the Software Redundancy (SWR) function on a CPU 315-2 DP master and a CPU 315-2 DP slave, with three PROFIBUS-DP remote stations distributed in the field, will toggle its role from master to slave whenever any of those remote DP slaves loses power. The failover is technically correct: the master's diagnostic buffer records an OB86 "Rack failure" event for the affected station, the redundancy library marks the link as down, and a role swap is triggered so the standby CPU takes over process scanning. The problem is operational: a single, recoverable power dip on a remote I/O station should not propagate into a full master-to-slave transition, because the role swap momentarily pauses the process, can cause I/O image inconsistencies, and if the power restores quickly leaves the plant running on what was supposed to be the standby controller.
The typical engineering response is to insert a sample block shipped with the Siemens Software Redundancy documentation into OB86 so the OB86-triggered diagnostics are filtered and the master is held in its role until the DP slave has been confirmed dead for a configurable period. The sample program provided by Siemens in the SWR manual is, however, written in German mnemonics, and STEP 7 with the default English mnemonic set refuses to compile it: the keywords show in red and the block will not save. This article provides a fully translated, OB86-resident suppression block for S7-300 SWR, the German-to-English mnemonic substitution table, the wiring inside STEP 7, and the verification procedure that proves the role swap no longer fires on a transient DP slave power-down.
Software Redundancy (SWR) Architecture
S7-300 Software Redundancy is implemented in the user program, not in the operating system of the CPU. The two CPU 315-2 DP controllers run identical user programs; one is configured as the master (A-CPU), the other as the slave (B-CPU). The role is determined at runtime by an SWR instance DB and by the S7 connection that ties the two controllers together. Each CPU runs the same logic, but the slave suppresses the output of its process image to the I/O. The library blocks FB101 "SWR_START" and FB102 "SWR_ZYK" (also referred to as "SWR_CYC") perform the initialization and cyclic coordination of the two roles.
| Block | Name | Function |
|---|---|---|
| FB101 | SWR_START | Initializes SWR, sets role (master/slave), reads configuration |
| FB102 | SWR_ZYK | Cyclic call; updates role, synchronizes data, triggers swap if needed |
| DB_WORK | SWR working DB | Shared state between master and slave |
| OB86 | Rack failure OB | Fired when a DP slave, central rack, or interface module fails |
| OB82 | Diagnostic interrupt OB | Fired on diagnostic alarms from DP slaves |
| SFC13 | DP_PRAL | Read DP slave diagnostics |
| SFC51 | RD_SSYS_T / RDSYSST | Read system status lists (SSL) |
The master writes its process image to the I/O and the slave keeps the same image in memory. On a swap, the former master drops into standby and the former slave begins driving the I/O. The swap logic inside FB102 reacts to OB86 events: when the SWR library sees a rack failure on a DP slave that is part of the redundant I/O, it raises an internal "switchover request" flag. If your application does not want the swap to occur on a single DP slave failure, the OB86-resident filter block is the place to intercept that flag and either delay or suppress the swap.
Why the Master Switches to Slave on DP Slave Power Loss
OB86 is the rack failure organization block. It is called by the operating system on three different events:
- Failure of a DP slave station (rack/station failure)
- Return of a DP slave station
- Failure of an expansion rack in a central configuration
When the CPU's DP master interface detects that a previously reachable DP slave is no longer responding, the CPU enters the rack failure state, calls OB86, and writes diagnostic information into the OB start information. The SWR library's FB102 evaluates this start information each cycle; if the failed station is part of the SWR-controlled I/O, the library triggers a switchover. The intent is to keep the redundant I/O update alive: if you lose a DP slave on the master, you can keep the process going by switching to the slave, which presumably has the same I/O healthy. For installations where the DP slaves are simple remote I/O stations that are not in the SWR-controlled I/O group, this behavior is unwanted. The master has no real reason to swap roles because the failed station is independent of the SWR scope.
OB86 and Rack Failure Diagnostics
OB86 receives its start information in the local data area of the OB. The first 20 bytes are the standard OB header; the diagnostic-specific fields begin at byte 20 of the temporary local data. The two fields engineers most often need for filtering are the diagnostics address and the fault ID. The diagnostics address is the logical base address of the failed station as configured in HW Config; the fault ID distinguishes station failure (B#16#31), station return (B#16#39), and expansion rack failure (B#16#32).
The SWR manual's example program reads this address and tests it against a configured list of non-critical DP slave addresses. If the address is in the non-critical list, the program resets the "switchover request" inside the SWR library's working DB and returns without acting on the failure. If the address is not in the list, the event is allowed to propagate to the standard SWR handling path, which then performs a role swap if the failed station was part of the SWR-controlled I/O.
The German-to-English Mnemonic Problem
Siemens' Software Redundancy documentation was originally written in German, and a substantial portion of the example code in the printed manual (and in older PDFs) is in German mnemonics. STEP 7 allows the user to switch the editor between German and English mnemonics (Options > Customize > Language tab in the SIMATIC Manager), but most installations outside Germany are kept in English. When you copy a German-mnemonic STL block into an English-mnemonic environment, the keywords become red, the program is uncompilable, and OB86 silently fails to download because the program cannot be compiled. There are three fixes:
- Switch the editor to German mnemonics, paste and compile, switch back to English.
- Translate the German mnemonics to English before pasting.
- Use the translated block shipped in this article.
Option 1 is convenient for one-off edits, but it forces every engineer who maintains the project to keep the German mnemonic set or to repeat the switch every time they open the block. Option 2 is the sustainable path: keep the project in English and store the code in English mnemonics. Option 3 is fastest when you need to deploy immediately.
Mnemonic Conversion Reference
The mnemonics appearing in the SWR OB86 sample are limited in number. The table below covers every keyword you will encounter in the Siemens SWR example programs and in the original S7-300 / S7-400 STL examples from the same era. Most projects only need the first six rows.
| German | English | Meaning |
|---|---|---|
| U | A | AND |
| UN | AN | AND NOT |
| O | O | OR |
| ON | ON | OR NOT |
| SPBN | JCN | Jump if RLO = 0 (conditional jump, no accumulator load) |
| SPB | JC | Jump if RLO = 1 |
| SPN | JN | Jump if RLO = 0 (with accumulator load) |
| SPZ | JZ | Jump if result = 0 |
| SPMZ | JMZ | Jump if result < 0 (negative) |
| SPPZ | JPZ | Jump if result > 0 (positive) |
| AUF | OPN | Open a data block |
| L | L | Load |
| T | T | Transfer |
| SET | SET | Set RLO = 1 |
| CLR | CLR | Set RLO = 0 |
| SAVE | SAVE | Save RLO in BR |
| BEA | BE | Block end absolute |
| BEB | BEU | Block end unconditional |
Note that "U" is the AND contact in German, "A" is the same in English. The case-sensitive nature of the German mnemonics means you must also be careful with comments. The German "U" inside a comment is harmless, but the compiler will reject it in code. Always scan the block for any remaining "U" lines after paste and replace them with "A" or "AN" depending on whether the line ends with an "N" (the German "UN" / English "AN" pattern).
Implementing the Suppression Logic
The SWR example logic for filtering OB86 events consists of three parts: read the diagnostics address, compare it against a list of allowed or non-critical addresses, and either clear the SWR swap-request flag or pass the event through. The Siemens example uses a bit array stored in a global DB where each bit represents a DP slave's logical base address; a "1" bit means "do not allow switchover on failure of this address". The example also uses a small flag byte to remember whether the suppression is currently active.
The structure of the OB86 block in English mnemonics looks like this:
OB86 "Rack Failure OB"
//
// Suppress SWR master-to-slave switchover for
// non-critical DP slave power failures.
//
// Source: Siemens SWR manual OB86 example,
// translated to English mnemonics
//
L #OB86_DIAG_ADDR // Load diagnostics address
L 0 // 0 means "no specific address"
==I
JCN M001 // If not 0, branch to standard handling
// Suppress switchover path
OPN DB [SW_RED_DB] // Open SWR working DB
L 0
T DBW 0 // Clear "swap requested" flag
BE // End block, do NOT swap
M001: NOP 0
// Standard SWR handling continues here
BE
The block above is a minimum-viable version. A real production block will:
- Read
OB86_DIAG_ADDRfrom the local data. - Open a global filter DB containing a bit mask of DP slave base addresses.
- Test the bit corresponding to
OB86_DIAG_ADDR / 8(bit index) at the byte corresponding toOB86_DIAG_ADDR / 8(byte index). - If the bit is "1" (suppress), clear the SWR swap-request flag and exit.
- If the bit is "0" (allow swap), pass through to standard SWR handling.
The filtering DB is typically named "DB_FILTER" with a structure that maps each DP slave's logical base address to a boolean. The base addresses in a typical S7-300 / DP master installation start at 0 and increment in steps of 4 to 16 depending on the slot configuration. For further information on S7 communication and the role of partner CPUs in the SWR topology, refer to the Siemens support entries 6518822 and 19449428.
Step-by-Step: Building the OB86 Block
Before you start, confirm the following prerequisites:
- STEP 7 V5.5 (or compatible) installed with the SWR library.
- The S7 project with two CPU 315-2 DP stations already configured for software redundancy (HW Config complete, SWR connection set up in NetPro).
- FB101 "SWR_START" and FB102 "SWR_ZYK" present in the master and slave project.
- Access to each DP slave's logical base address from HW Config (Properties > DP Slave > Diagnostics Address).
- Open the SIMATIC Manager and the master project.
- In the master station's "Blocks" folder, double-click OB86. If OB86 does not exist, right-click the "Blocks" folder and choose "Insert New Object > Organization Block > OB86".
- Set the OB86 priority to 25 (the SWR example default; lower priorities can be set if needed).
- Open OB86 in STL view (View > STL).
- Confirm the editor is in English mnemonics: Options > Customize > Language tab > "English (International)" selected. If the option is greyed out, close all open blocks first.
- Create a new shared DB "DB_FILTER" with a structure that maps the DP slave diagnostics addresses. Example for stations with base addresses 1024, 1028, 1032, 1036 (4 stations, each bit per address, packed into 1 byte per group of 8 addresses):
DATA_BLOCK DB_FILTER
TITLE = 'OB86 DP slave filter mask'
VERSION : 1.0
STRUCT
Mask_1024_1031 : BYTE; // bit 0 = addr 1024, ..., bit 7 = addr 1031
Mask_1032_1039 : BYTE; // bit 0 = addr 1032, ..., bit 7 = addr 1039
END_STRUCT;
BEGIN
END_DATA_BLOCK
- Mark the addresses that should NOT trigger a swap (the non-critical DP slave stations). For each address, set the corresponding bit to "1".
- Insert the OB86 suppression logic into the OB86 STL view, using the code skeleton shown in section 7. Replace the placeholder "DB [SW_RED_DB]" with the actual number of the SWR working DB in your project.
- Save the block. The keywords must NOT be in red; if any are, apply the conversion table from section 6.
- Repeat steps 1-9 in the slave project. The filter DB must be identical between master and slave.
OB86 Start Information and Variables
For the filter logic to work reliably, the OB86 start information must be read with the correct variable names. The exact local variable names in English STEP 7 are:
| Variable | Type | Content |
|---|---|---|
| OB86_EV_CLASS | BYTE | Event class (B#16#39 incoming, B#16#38 outgoing) |
| OB86_FLT_ID | BYTE | Fault ID (B#16#31 station failure, B#16#39 station return, B#16#32 expansion rack failure) |
| OB86_PRIORITY | INT | Priority |
| OB86_OB_NUMBR | INT | OB number (86) |
| OB86_RESERVED_1 | WORD | Reserved |
| OB86_DIAG_ADDR | WORD | Logical base address of the failed station |
| OB86_RESERVED_2 | WORD | Reserved |
| OB86_FLT_ID_2 | WORD | Extended fault ID |
| OB86_RESERVED_3 | DWORD | Reserved (more diagnostic data depending on fault ID) |
When reading from the temporary local data in STL, prefix the variable name with "#" (e.g. L #OB86_DIAG_ADDR) to ensure you are reading the local data area, not a global symbol of the same name. Skipping the "#" is a common bug in translated OB86 examples: the resulting code may compile but reads a global zero, making the filter a no-op. The JCN and JC jumps in the example use symbolic label names ("M001" in the example) which STEP 7 resolves to absolute jumps at compile time; the label name is local to the block, so it can be reused across blocks without conflict.
Compiling, Downloading, and Verifying
Once the OB86 is in place, the procedure to verify it is:
- Save and compile OB86 in the master project. The status bar should report "Compilation finished, no errors". Any red keywords indicate a remaining mnemonic issue.
- Download the blocks to the master CPU (target system > Download). OB86 will be in "stop" mode for download if it doesn't already exist; if OB86 already exists, you can download the modified copy to RUN via the "Stop / Run" toggle or use "Download to Target System" with the right mode.
- Repeat for the slave project.
- Open the master CPU's online view (PLC > Accessible Nodes or "Online > Monitor/Modify").
- Open the diagnostic buffer (PLC > Diagnostic Buffer) and confirm OB86 events are being entered on a forced DP slave power-down.
- Force a DP slave power-down (de-energize the 24 V supply of one of the remote stations). Watch the master's diagnostic buffer; an OB86 entry should appear with the failed station's diagnostics address. The master's role should NOT change; the redundancy status in the SWR instance DB should remain "Master active".
- Restore the 24 V supply. An OB86 "station return" entry should appear. Confirm no spurious role swap occurred by checking the redundancy role flags.
- Repeat steps 5-7 for the slave CPU. The slave's role should likewise remain "Slave active" through the test.
For an additional reference on PLC diagnostic buffer interpretation, see the Siemens support entry 45531107.
Diagnostic Buffer and Status Checks
Beyond a manual power-down test, the diagnostic buffer can be read in real time using SFC51 "RDSYSST" with SSL ID W#16#011B (DP slave diagnostics) and INDEX equal to the station address. The first byte of the result is the station's current state (0 = OK, 1 = failed, 2 = not reachable, 3 = unknown). Reading this state in OB1 and feeding it into a global status word is the cleanest way to surface DP slave health to the HMI.
For the SWR status, the SWR working DB contains the role and swap-request flags at fixed offsets. The typical layout (varies slightly between SWR library versions) is:
| Offset | Name | Meaning |
|---|---|---|
| DBW0 | i_red_state | 0 = startup, 1 = master active, 2 = slave active, 3 = solo |
| DBW2 | i_role_request | Pending role change |
| DBW4 | i_diag_state | Diagnostic state of the partner link |
| DBW6 | i_last_swap_cause | Cause code of the last role swap |
The i_last_swap_cause value is the field-proven indicator of why the SWR swapped. Common values include 1 (link failure), 2 (user-initiated), 3 (DP slave failure), and 4 (configuration mismatch). If the value is 3 after a forced DP slave power-down, the OB86 filter did not catch the event and the bit in DB_FILTER must be rechecked.
Edge Cases and Field Notes
Several conditions are commonly missed during commissioning of the OB86 filter:
- Both stations in the same OB86 filter list: if the SWR link itself is on the same DP segment as the remote slaves, an SWR link failure can also be filtered. Always ensure the SWR partner address is NOT in the filter DB.
- DP/DP coupler: if your topology uses a DP/DP coupler between master and remote slaves, the diagnostics address reported in OB86 is the address of the lower-level segment, not the coupler. Filter the segment address, not the coupler.
- I-slave configuration: when a CPU 315-2 DP is itself an I-slave on a higher-level bus, OB86 events triggered by the higher-level bus do not necessarily propagate to the local SWR. The filter block must be installed in OB86 of the local CPU regardless.
- Time delay vs. hard suppression: the Siemens example performs a hard suppression (clears the swap flag immediately). A safer pattern for stations with brief, recoverable faults is a 1-2 second delay: store the failure timestamp, ignore further failures for that address within the window, and only clear the swap flag if the failure persists past the window. This prevents the SWR from swapping during a momentary glitch while still protecting the process against a true hard failure.
- Asymmetric filter configuration: a bug in the field is when the master and slave have different filter DB contents. Always generate DB_FILTER from a single source-of-truth file and copy it into both projects to keep them in sync.
-
Library version compatibility: the SWR library shipped with STEP 7 V5.5 SP1 is the standard for S7-300. Older versions may have a different DB layout for the SWR working DB. The
i_red_stateoffsets shown above apply to the most common version; verify with your specific library's documentation. - STEP 7 V5.5 vs. TIA Portal: S7-300 SWR is a STEP 7 V5.5 environment feature. TIA Portal handles S7-300 SWR via the S7-300/S7-400 add-on; the OB86 mechanism is identical but the project structure is different.
- Loss of SWR partner link: if the SWR partner link is lost AND a DP slave is lost at the same time, the OB86 filter still suppresses the role swap, but the SWR goes into "solo" mode. Confirm the solo behavior is acceptable for the process.
Comparison: S7-300 SWR vs. S7-400H
For larger plants, the S7-400H synchronous redundancy system is often the right choice. The behaviour on DP slave power failure is different, and understanding the contrast helps justify the suppression logic in S7-300 SWR installations.
| Aspect | S7-300 SWR | S7-400H |
|---|---|---|
| Redundancy type | Software, asynchronous | Operating-system, synchronous |
| Role swap on DP slave failure | Possible, depends on OB86 handling | Configurable; typically does not swap on single-channel DP slave failure |
| Hot-swap DP slaves | Not supported in SWR scope | Supported via H-system CPU 41xH with redundant DP master interface |
| Programming effort for suppression | Manual OB86 block + filter DB | Configuration-only; no user code required |
| Diagnostic depth | OB86 events only; user must interpret | Integrated HMI diagnostic blocks; automatic event logging |
| Cost | Lower (S7-300 hardware) | Higher (H-CPUs, redundant backplane, fiber-optic sync module) |
| Switchover time | Cycles (depends on user program) | Sub-100 ms (hardware-supported) |
For reference, the Allen-Bradley / Rockwell Automation ControlLogix redundancy system (documented in the 1756 Redundancy Systems User Manual, publication 1756-UM015M-EN-P) provides a similar capability through a qualification and switchover criteria configuration rather than user-written OB86 logic. The trade-off is essentially the same as S7-300 vs. S7-400H: higher hardware cost for less user-level code.
FAQ
Why does STEP 7 mark the German mnemonics SPBN, U, and AUF in red inside OB86?
STEP 7's STL editor compiles against the active mnemonic set (English by default in most installations). The German keywords SPBN (jump if RLO=0), U (AND), and AUF (open DB) are not recognized, so they are flagged in red. The block will not compile or download until they are replaced with the English equivalents JCN, A, and OPN, or the editor is switched to German mnemonics temporarily.
Will suppressing the role swap compromise the redundancy of my S7-300 system?
It depends on which DP slaves you filter. The suppression only prevents the master-to-slave transition on failure of a non-critical DP slave (one whose I/O is independent of the SWR-controlled process). If you filter a DP slave that is part of the SWR-controlled I/O, you have removed the redundant I/O update for that region and the system will no longer be tolerant of that slave's failure. Filter only the stations whose loss the process can tolerate.
Which CPU 315-2 DP order numbers support Software Redundancy?
Software Redundancy requires a CPU 315-2 DP or CPU 317-2 DP. The 6ES7 315-2AF03-0AB0 and 6ES7 315-2AG10-0AB0 variants of the CPU 315-2 DP are the most commonly deployed in SWR applications; the SWR library itself is included in STEP 7 V5.5. Always confirm the CPU's firmware version is at or above the version listed in the SWR manual's release notes for the library version you are using.
How do I read the role status of the SWR partner at runtime?
The SWR working DB contains a status word with offsets documented in the SWR library. Typical offsets are DBW0 (redundancy state: 1 = master active, 2 = slave active, 3 = solo) and DBW6 (last swap cause: 1 = link failure, 2 = user-initiated, 3 = DP slave failure, 4 = configuration mismatch). The exact offsets depend on the SWR library version; consult the SWR library's online help for the version installed in your project. The values can be displayed on an HMI via a status tag or read from the diagnostic buffer of the partner CPU.
Can I use the same OB86 suppression block on the master and the slave?
Yes. The OB86 filter logic is identical on both controllers and the filter DB must contain the same address mask on both. Keep the DB_FILTER in a single source-of-truth location (a master copy in the project library) and copy it into both CPU projects to prevent asymmetric configuration, which is a common source of swap behaviour that appears to be intermittent.