Sharing FB/FC Across S7-1200 PLCs Using TIA Portal V16 Library
When a fleet of identical SIMATIC S7-1200 stations runs the same user program on the same hardware, every code change normally forces an engineer to open every project, edit every block, and re-download every controller. The TIA Portal library system breaks that loop, but only when blocks are placed in the correct library container (the Types folder) and managed with the right workflow. This guide walks through the procedure that lets a single FB or FC edit propagate to every PLC without copy/paste, drag-and-drop, or hand-tracking of revisions, using TIA Portal V16 as the reference platform and the SIMATIC S7-1200 programmable controller as the target hardware.
1. Problem Definition: Shared Code Across Multiple S7-1200 Stations
Consider a typical machine-builder scenario: three, ten, or thirty S7-1200 CPUs (CPU 1214C DC/DC/DC, for example) sit on the same PROFINET subnet, each controlling a section of a larger line. All CPUs carry identical hardware configuration and an identical user program. The only differences between stations are the PROFINET device names and IP addresses of the distributed I/O that physically hangs off each CPU. A handful of FB/FC blocks carry every line-wide logic (recipe engine, alarm handling, axis sequencing, HMI handshake).
The expected behavior of any modern library system is "edit once, consume everywhere": change the body of FB100 in the central library, recompile every consumer project, and the change ripples out. TIA Portal V16 supports this pattern but splits it across three containers (Project library, Global library, and Types / Master Copies sub-folders), each with different editability rules. Misplacing a block silently kills the workflow, which is the single most common complaint when first migrating from STEP 7 Classic to TIA Portal.
2. TIA Portal Library Architecture: Project vs Global Library
TIA Portal exposes two top-level library scopes. Understanding the difference is mandatory before choosing where to store shared blocks.
| Scope | Lives in | File extension | Editable FB/FC? | Versioned with project? | Shared across projects? |
|---|---|---|---|---|---|
| Project library | The open TIA Portal project (right pane, "Libraries" task card) | n/a - embedded | Yes, when stored as a Type | Yes, snapshot is part of the .ap16 project archive | No - travels with the project |
| Global library | An external file referenced by one or more projects | .al16 (V16), .al17 (V17), .al18 (V18) | Yes, when stored as a Type; requires write access to the file | No - stored separately | Yes - the same .al16 can be opened by multiple projects simultaneously on a network share |
Use a project library when the shared code is genuinely project-specific (e.g., a recipe engine that only this fleet needs). Use a global library when the same code base must be referenced from multiple independent TIA Portal projects (e.g., a corporate FB for motor control that every machine-builder project consumes). The .al16 extension is bound to TIA Portal V16; upgrading to V17 requires a one-time conversion via "Libraries > Upgrade library version".
3. Types Folder vs Master Copies Folder: Editability Rules
Both library scopes contain two sub-folders that are easy to confuse. Their behavior is, however, sharply different.
| Folder | Allowed content | Editable in place? | Used for | Versioning |
|---|---|---|---|---|
| Types | FB, FC, OB, DB, UDT, PLC tag tables, watch tables | Yes - opening a Type opens it as an editable copy; the change is committed back to the library on save | Versioned, type-safe code that all consumer projects reference | Major.Minor.Patch (semantic) |
| Master Copies | Any block, plus complete program folders, devices, watch tables, and HMI screens | No - read-only by design | Templates that are dropped into a project and edited locally, becoming a project-local copy | None - the consumer diverges the moment it is dropped |
The behavioral difference is the key to the whole workflow: a Type is a single source of truth that the project references by version, while a Master Copy is a one-shot template that diverges the moment it is dropped into a consumer project. Once a Master Copy is dropped, it owns its own revision history and cannot be auto-updated from the library.
4. Step-by-Step: Adding an FB or FC to the Types Section of a Project Library
The procedure below places an FB into the project library so that changes to its body propagate to every device in the project. TIA Portal V16 is assumed; the same workflow applies to V17 and V18 with only menu-string differences.
- Open the TIA Portal project that contains the working PLC.
- In the project tree, expand the target PLC and navigate to Program blocks.
- Select the FB or FC that must become shared. Right-click and choose Copy.
- Open the Libraries task card on the right side of the TIA Portal window.
- Expand the Project library node, then the Types sub-folder.
- Right-click inside Types and choose Paste. TIA Portal creates a Type version (e.g., V1.0.0) from the pasted block.
- Drag the Type from the library onto the Program blocks folder of the same PLC (this is the first "use" that registers the type with the project).
- Repeat the drag operation for every additional PLC that must consume the type.
After step 8, every PLC's Program blocks folder contains a block whose type reference points back to the single project-library Type. Editing the Type later is picked up by every consumer on the next compile. The block icon in the consumer project carries a small overlay badge that marks it as type-managed, making the relationship visible at a glance.
4.1 Promoting a Project Type to the Global Library
Once a Type is stable in the project library, expose it as a corporate standard via the global library:
- Right-click the Type inside the project library's Types folder.
- Choose Update types > Library.
- Select the target global library (.al16 file) and confirm.
- The Type is now visible inside that global library and can be referenced by any project that opens it.
5. Editing a Type and Propagating the Change to Multiple PLCs
The day-to-day maintenance loop is the part that saves the most time. Follow the sequence below every time the shared FB or FC needs to change.
- Open the Libraries task card and expand Project library > Types.
- Double-click the FB or FC to open it. The block opens in the editor as an editable copy (it is no longer greyed-out).
- Edit the code, save with Ctrl+S. TIA Portal commits the change back to the Type and prompts to increment the version.
- Open the Program blocks folder of any PLC that uses the Type. TIA Portal shows an "Update required" icon next to the block instance.
- Right-click the instance and choose Update > Type version. Select the new version and confirm.
- Repeat step 5 for every PLC that consumes the Type.
- Compile (Ctrl+B) and download to each station.
.al16 file is stored on a network share with read-only attributes, TIA Portal silently opens the Type as read-only. Uncheck "Read-only" on the file (and on the containing folder) before troubleshooting a "the block opens but I cannot edit" symptom.6. Advanced Technique: Shared Cyclic OBs (OB1, OB123, OB200, ...)
TIA Portal allows multiple Program cycle OBs to exist in the same S7-1200 project. The default is OB1, but the S7-1200 firmware also executes any OB whose number is >= 123 and that has been configured as a Program cycle OB. This is the cleanest way to ship an entire "library PLC behavior" as a single drag-and-drop unit:
- OB123 (or any free number above 122) is created as a Program cycle OB and contains all of the shared, library-managed logic.
- OB1 stays empty (or contains only project-specific glue code) and is the one OB that every project always owns.
- The shared OB, together with the FBs and DBs it calls, is dropped from the library into the consumer project's Program blocks folder as a single operation.
This pattern avoids the friction of trying to ship a "shared OB1": a real OB1 must always remain project-local because the project tree entry "Program blocks > OB1" cannot be deleted from the consumer project. An extra OB sidesteps that limitation and survives a copy/paste into a sibling station without conflict.
| OB number | Type | Owner | Editable in library? | Use case |
|---|---|---|---|---|
| OB1 | Program cycle (default) | Project - cannot be replaced by a library | No - instance behavior only | Project glue, station selector, station-specific startup |
| OB10 | Time-of-day | Project | No | Daily maintenance jobs |
| OB82 | Diagnostic error | Project or library | Yes, as a Type | Centralized PROFINET diagnostics |
| OB100 | Startup | Project or library | Yes, as a Type | Cold/warm restart initialization |
| OB123+ | Program cycle (extra) | Library (recommended for shared logic) | Yes, as a Type | Shared user program across fleet |
6.1 Concrete OB123+ Snippet (Structured Text)
The block below is a realistic minimal pattern: OB123 calls a type-managed FB that owns all shared line logic. The same OB123, FB and its instance DB are shipped as a single library Type and consumed by every station.
// OB123 - Shared Library Cycle
// Configured as Program cycle, priority 1 (same as OB1)
CALL "FB_LineShared" , "DB_LineShared"
iStationID := "Station".iStationID // WORD, project-local tag
iHeartbeat := "Clock_1Hz" // BOOL from system clock
bRun := "HMI".bLineStart // BOOL from HMI handshake
bReset := "HMI".bLineReset
bAlarmActive => "HMI".bLineAlarm // BOOL to HMI
iAlarmCode => "HMI".iLineAlarmCode // WORD to HMI
END_CALL
When the Type is updated, OB123 itself does not need to change - only the FB body does. The interface signature of FB_LineShared is versioned, so adding or removing parameters is handled cleanly by the "Update type" dialog.
7. Dummy Project Workflow for Global Library Master Copies
Master Copies cannot be edited in place. To update a Master Copy that lives in the global library, route the edit through a throwaway project. This is the only supported way to revise Master Copy content without losing the original template structure.
- Create a new empty TIA Portal project (the "dummy") and add any S7-1200 CPU.
- Drag the Master Copy from the global library into the dummy's Program blocks folder. The drop unmasks the blocks as editable.
- Edit the blocks in the dummy. Save and compile.
- Drag the edited blocks back into the global library's Master Copies folder (overwrite when prompted).
- Close the dummy without saving the project.
8. Commissioning Workflow for 3 to 30 Identical S7-1200 Stations
For a fleet that has not yet been wired to the engineering station, the practical workflow during commissioning is structured as below. A consistent device-naming convention is critical because every station's PROFINET device name and IP must differ from every other station on the subnet.
| Phase | Action | Tool | Notes |
|---|---|---|---|
| 1. Library build | Author all shared FBs/FCs/OBs as Types in the project library | TIA Portal V16, project library | Pin Type version V1.0.0 before commissioning |
| 2. Reference PLC | Configure the reference PLC with device names, IPs, and PROFINET topology, then download | Project tree, Devices & Networks | Use a naming pattern such as plc-line01-st01, plc-line01-st02 ... |
| 3. Functional test | Validate the shared code on the reference station | Watch tables, trace, HMI | Capture a baseline of FB instance snapshot data |
| 4. Library snapshot | Save the project as a reference and commit the .ap16 to source control | Git, SVN, TIA Portal project comparison | Tag the commit as "fleet-baseline" |
| 5. Clone for station 2..N | Open the reference project, change only device names and IPs, save as a new project per station | Station copier macro, "Save as" loop, or Openness API script | Suggested IP range: 192.168.0.11..192.168.0.40 (subnet mask 255.255.255.0) |
| 6. Update loop | Edit the library Type; open each per-station project, accept the Type update, recompile, download | Type update dialog | Capture Type version in the project name, e.g. line01_st01_v1.2.3.ap16
|
For fleets above 10 stations, build a small TIA Portal Openness API script (C# or Python) that automates steps 5 and 6. The script can also drive the S7-1200's Web server or the HMI's "Station selector" tag to verify that the download reached the correct hardware. A 30-station fleet that previously took a full engineer-week to update with copy/paste reduces to a 30-minute unattended run.
8.1 Device-Naming and IP-Allocation Convention
Use a deterministic naming scheme so that an automated script can rename a project for each station without manual edits:
// Naming pattern
PROFINET device name : plc-<line>-st<NN> (e.g., plc-line01-st07)
CPU IP address : 192.168.<line>.<11+NN> (e.g., 192.168.1.18)
HMI station number : <NN> (HMI tag, used in OB1)
Subnet mask : 255.255.255.0
Gateway : 192.168.<line>.1
PROFINET device IPs : 192.168.<line>.<100+NN> (ET200SP, drives, etc.)
Keep the offset (11) high enough to leave the low range for the engineering station and any handheld commissioning tools. Avoid using .1 and .2 for PLCs - those addresses are typically claimed by routers and the engineering PG.
9. Verification Checklist After Library Updates
Run the following checks before signing off a library-driven code change. Each row maps a symptom to a verification action.
| Check | How to verify | Expected result |
|---|---|---|
| Type version on every station | Right-click FB/FC in each PLC > Properties > "Information" tab | All stations show the same Type version (e.g., 1.1.0) |
| No stray Master Copies | Project tree > Program blocks > filter by "no type reference" | Empty filter result; everything is type-managed |
| Compile is clean | Compile > Software (rebuild all) | Zero errors, zero warnings about inconsistent interfaces |
| Cross-references intact | Right-click FB > "Cross-references" on each station | Same callsites and DB instances on every station |
| Download acceptance | Online > "Compare offline/online" on each station after download | Only the expected FB/FC body differs, no structural drift |
| PROFINET names and IPs | Online > "Accessible devices" from each station's online view | Each station reports its assigned device name and IP |
| OB123+ runs | Online > Diagnostics > Call environment > OB123 | Stack shows the shared FB being called from OB123 every cycle |
10. Type Versioning, Interface Changes, and Openness Automation
TIA Portal uses a three-segment semantic version for library Types: Major.Minor.Patch. The segments map to specific change classes:
| Segment | Bumped when | Consumer impact | Auto-update allowed? |
|---|---|---|---|
| Major (X.0.0) | Interface signature changes (new IN/OUT/STAT added in the middle, renamed tags, removed tags) | Compile error on consumers until they explicitly accept the new interface | No - manual "Update type" required |
| Minor (0.X.0) | New tags appended at the end of the interface | Compatible - existing callsites keep their old tag layout | Yes - TIA proposes auto-update |
| Patch (0.0.X) | Body-only changes (logic, comments, internal STAT values) | Fully transparent to consumers | Yes - always auto |
10.1 Openness API Sample (C#)
For fleets above ~10 stations, the manual "Update type" loop becomes the bottleneck. The TIA Portal Openness API exposes the same operation as a single call. The snippet below (compiled against Siemens.Engineering.dll shipped with TIA V16) opens a project, performs the Type update, and saves.
// TIA Portal Openness - bulk type update
using Siemens.Engineering;
using Siemens.Engineering.Library;
public static int UpdateTypeInProject(string ap16Path, string typeName, Version newVersion)
{
using (var tia = new TiaPortal(TiaPortalMode.WithUserInterface))
{
var project = tia.Projects.Open(new FileInfo(ap16Path));
int updated = 0;
foreach (var device in project.Devices)
{
var software = device.Items.OfType<SoftwareContainer>().FirstOrDefault();
if (software == null) continue;
var blocks = software.Software.Blocks;
foreach (var block in blocks)
{
if (block.Type == null) continue;
if (!string.Equals(block.Type.Name, typeName,
StringComparison.OrdinalIgnoreCase)) continue;
var latest = block.Type.Versions
.OrderByDescending(v => v.VersionNumber)
.FirstOrDefault(v => v.VersionNumber <= newVersion);
if (latest != null && latest.VersionNumber != block.Type.Version)
{
block.Type.UpdateType(latest);
updated++;
}
}
}
project.Save();
project.Close();
return updated;
}
}
Siemens.Engineering.dll shipped with V16) does not compile against V17 without recompilation. Plan a regression test of the automation script whenever the engineering team upgrades TIA.11. Common Pitfalls and Field-Proven Caveats
The list below captures the failure modes that surface most often in production deployments, ordered by frequency.
- Block placed in Master Copies, edited locally: the change is silently scoped to that one PLC. Fix: move the body to the project library's Types folder and "Update type" on every PLC.
- Read-only .al16 file: global library Types open read-only even when the user has Windows write permission on the folder. Uncheck the file's Read-only attribute on the .al16 file and the containing folder.
- OB1 cannot be "library-ized": every consumer project already owns an OB1. Trying to overwrite it from the library raises a red-circle error. Fix: keep OB1 local, ship a higher-numbered Program cycle OB (OB123+) as the shared entry point.
- UDT changed without versioning: renaming a UDT field propagates as an error on the consumer project. Fix: increment the UDT version inside the Type and run "Update type" on every consumer before downloading.
- Multiple Program blocks folders: dragging a Type onto a "Program blocks" folder that lives inside a group folder does not register it as a project-level type. Drop it onto the CPU's top-level Program blocks node.
- Type with hardware-dependent references: any block that uses a hardware identifier (HW ID) will not compile cleanly if dragged into a PLC whose HW catalog differs. Fix: parameterize HW IDs through PLC tags or an HMI panel selector.
- Forgetting the cyclic OB priority: OB123 must have the same priority (priority class 1, default) as OB1, otherwise scan order becomes non-deterministic. Set the priority in OB Properties > "Cycle time / Priority".
- Library file shared across two engineering stations: two users opening the same .al16 file and saving simultaneously will corrupt the file or silently overwrite each other. Use a single-writer policy (file lock) or move the library to a Git LFS-backed workflow.
12. Frequently Asked Questions
Can I edit an FB or FC directly inside the global library in TIA Portal V16?
Yes, but only when the FB/FC is stored as a Type (not a Master Copy). Open the Type by double-click; the editor shows an editable copy and the change is committed back to the .al16 file on save. Make sure the .al16 file is not flagged read-only on the file system, otherwise the block opens but cannot be saved.
Why does my FB show up in Master Copies instead of Types when I drag it into the library?
TIA Portal defaults new drops into the Master Copies folder unless the user explicitly targets Types, or unless the block is added via the "Update types > Library" command. Re-drag the block into the Types sub-folder to switch it to a versioned, editable Type.
How do I share a complete PLC program (including OB1) across many S7-1200 stations?
You cannot ship OB1 itself - every project already owns one. Create an extra Program cycle OB (OB123 or higher), put the shared logic there, and ship the OB plus its FBs, FCs, and DBs as a library Type. Each consumer project keeps its own empty OB1 plus the shared OB123+ from the library.
Can a single library edit push to every PLC in a multi-station TIA Portal project?
Yes, when the blocks are stored as Types in the project library. Edit the Type, then run "Update type" on each PLC's Program blocks folder. Each PLC must be updated individually because TIA does not auto-propagate Type updates across devices in the same project - the Openness API script in Section 10.1 automates that loop.
What happens if the global library .al16 file is opened from a read-only network share?
TIA Portal opens the file and lists its contents but flags every Type as read-only. Edits appear to succeed in the editor but cannot be saved back to the .al16 file. Clear the read-only attribute (and the containing folder's read-only attribute) before troubleshooting the "Type won't save" symptom.