//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022, 2026 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////

include::../_part_attributes.asciidoc[]

:leveloffset: -2

[[tools-plcgen-chapter-s7]]
== S7 PLC output

indexterm:[S7]
indexterm:[see: CIF PLC code generator,S7]
The S7 output (1500, 1200, 400 and 300) generates code for SIMATIC controllers.
Totally Integrated Automation Portal (TIA Portal) is an IDE for the development and testing of SIMATIC controllers.
Using the S7 output, the generated PLC code can be imported in TIA Portal.
This allows for tight integration and smooth development cycles when implementing controllers on SIMATIC controllers.

indexterm:[S7,generated output]

[[tools-plcgen-s7-generated-output]]
=== Generated output

The CIF PLC code generator can generate code files that can be imported in TIA Portal (see <<tools-plcgen-s7-usage>>).

The following option restrictions apply:

* The _Convert enumerations_ option must be set to _Automatically decide how to handle enumerations_, _Convert enumerations to integers_ or _Convert enumerations to constants_.

The type of integer and real data types to use depends on the _PLC integer type size_ and _PLC real type size_ options.
If _Automatic_ is selected, the following data types are used:

[cols="10,20,20",options="header"]
|===

| S7 type
| Integer type
| Real type

| S7-1500
| `DINT` (32 bit)
| `LREAL` (64 bit)

| S7-1200
| `DINT` (32 bit)
| `LREAL` (64 bit)

| S7-400
| `DINT` (32 bit)
| `REAL` (32 bit)

| S7-300
| `DINT` (32 bit)
| `REAL` (32 bit)

|===

The _PLC task name_, _PLC task cycle time_, _PLC task priority_, _PLC project name_, _PLC configuration name_, and _PLC resource name_ options have no effect for this output type.

indexterm:[CIF PLC code generator,Siemens S7 standard compliance]

[[tools-plcgen-s7-standard-compliance]]
=== Standard compliance

In general, the CIF PLC code generator follows the IEC 61131-3 PLC standard and does not use vendor-specific extensions.
For the Siemens S7 targets however, there are some differences.
For instance, the persistent variables are stored in a separate database file, named `DB`, and all references to persistent variables are prefixed with `"DB".`.
Also, global variables and constants are stored in a tag table, instead of a global variable list.
In such cases the output is not compliant with the IEC 61131-3 standard.

indexterm:[S7,usage]

[[tools-plcgen-s7-usage]]
=== S7 usage

Below, the basic usage of generated S7 code with TIA Portal is explained.
The steps assume that TIA Portal v15 is used.
If you use a different version of TIA Portal, the steps may be slightly different.

Follow these steps to create a project in TIA Portal, import PLC code in it, and use the PLC code to control the hardware:

* Start TIA Portal.

* Create a new S7 project:

** In the _Portal view_, click menu:Create new project[].

** In the _Create new project_ window, choose a project name and enter it in the _Project name_ box.

** For _Path_, select the directory in which the directory for the project should be created.

** Click btn:[Create] to create the project.

** Switch to the _Project view_.

* Add the PLC device:

** Unfold the project and double click _Add new device_.

** Unfold the device type category (that is, S7-1500, S7-1200, S7-400 or S7-300).

** Select the device with the correct article number.

** Click btn:[OK].

* Import the generated PLC code (PLC tags and constants):

** Double click _Default tag table_ inside the _PLC tags_ folder.

** For each generated `.xml` file (e.g., _CONSTANTS.xml_, _INPUTS.xml_, _OUTPUTS.xml_), do the following:

*** Click the _Import_ button.

*** Select the file.

*** Make sure _Tags_ and _Constants_ are both selected.

*** Click btn:[OK].

* Import the generated PLC code (Program blocks):

** Unfold the _External source files_ folder inside the device folder.

** Double click _Add new external files_.

** Select all generated `.scl`, `.udt` and  `.db` files, by selecting the first (top) file, and then selecting the last (bottom) file while holding the kbd:[Shift] key.

** Click the btn:[Open] button.

** Select all imported files (using kbd:[Shift] as above), right-click one of them and select menu:Generate blocks from source[].

*** If asked whether it is OK that _Blocks can be overwritten_, click the btn:[OK] button.

*** Ignore any warnings or errors.

* Compile the project:

** Right-click _Program blocks_ and select menu:Compile[Software (rebuild all)].

** If there are warnings or errors:

*** Compile again.
*** If any compile errors remain, repeat the steps above.
*** If errors about timers remain:

**** Sometimes, timers are not imported correctly.
In that case, compilation fails.
To add the timers manually, do the following.

**** Open _MAIN_ inside the _Program blocks_ folder.

**** Type `TON` and click kbd:[Enter].
The _Call options_ window pops up.

**** In the _Call options_ window, for each timer, enter its name in the _Name_ box and click btn:[OK].

**** Delete the generated lines of code.

**** Compile the project again.

*** If errors about tuples remain, the program blocks need to be created in the right order, based on tuple dependencies:

**** Generate the program blocks for the structs of the tuple types from the `.udt` files first, and create program blocks for the `.scl` and `.db` files last.
**** Generate the program blocks for the tuples in the right order.
If one `.udt` file uses a type from another tuple struct of another `.udt` file, the program block for the former needs to be created after the program block for the latter.
The PLC code generator writes a text file `derived_type_dependencies.txt` that contains the dependency information between structs, and from structs to enumerations if the latter types are used in a struct.

* Download PLC code to device:

** Click the _Download to device_ icon in the task bar.
The _Extended download to device_ window pops up.

** Click btn:[Start search].

** When a device has been found, click btn:[Load].
The _Load preview_ window pops up.

** Depending on the state of the PLC (idle, running, runtime error, ...), TIA Portal may require you to take certain actions.
Consult the TIA Portal documentation for further information.

** Click btn:[Load].

** Change the _Start modules_ action from _No action_ to _Start module_.

** Click btn:[Finish].

If a (simulated) PLC indicates a System Fault (SF), try to alter the memory allocation properties (may only apply to S7-400):

* Open the _Device Configuration_ for that PLC.

* Select the _CPU_, e.g. _CPU_1_, by clicking on it.

* Click the _Properties_ button to show the properties of the selected CPU.

* On the _General_ tab, select the _Memory_ category.

* Increase the _Number of bytes_ property for _Priority class_ number _1_.

* If needed, also increase the _Bytes of max_.

To debug the PLC code:

* Click _Go online_ in the task bar.

* The values of various variables can now be inspected.

** The values of input and output variables can be seen by opening _Default tag table_ inside the _PLC tags_ folder.
Click the _Monitor all_ icon.
The actual values appear in the _Monitor value_ column.

** The values of state variables can be seen by opening _DB_ under _Program blocks_.
Click the _Monitor all_ icon.
Unfold the _Static_ item.
The actual values appear in the _Monitor value_ column.

To stop the PLC:

* While online, click btn:[STOP] in the _CPU operation panel_ in the _Testing_ tab.

* Click _Go offline_ in the task bar.

To reset the PLC and start from the initial state, with the same code and the same configuration:

* While online, click btn:[MRES] in the _CPU operation panel_ in the _Testing_ tab.
The _Online & diagnostics_ window appears.

* Click btn:[Yes].

* If the PLC was in run mode, a new _Online & diagnostics_ window appears.
Click btn:[Yes].

* Click _Go online_ in the task bar.

* Start the PLC by clicking btn:[RUN] in the _CPU operation panel_ in the _Testing_ tab.

* The PLC is now running, and you can use the system.
