Manual
Manual
Manual
TC3 C++
TwinCAT 3
Version: 1.11
Date: 2020-04-14
Order No.: TC1300
Table of contents
Table of contents
1 Foreword .................................................................................................................................................... 9
1.1 Notes on the documentation.............................................................................................................. 9
1.2 Safety instructions ........................................................................................................................... 10
2 Overview................................................................................................................................................... 11
3 Introduction.............................................................................................................................................. 12
3.1 From conventional user mode programming to real-time programming in TwinCAT ...................... 14
4 Requirements........................................................................................................................................... 20
6 Modules .................................................................................................................................................... 35
6.1 The TwinCAT Component Object Model (TcCOM) concept ........................................................... 35
6.1.1 TwinCAT module properties ............................................................................................ 37
6.1.2 TwinCAT module state machine...................................................................................... 44
6.2 Module-to-module communication .................................................................................................. 46
7 Modules - Handling.................................................................................................................................. 49
7.1 Versioned C++ Projects................................................................................................................... 49
7.2 Non-versioned C++ projects ............................................................................................................ 49
7.2.1 Export to TwinCAT 3.1 4022.xx ....................................................................................... 50
7.2.2 Import up to TwinCAT 3.1 4022.xx .................................................................................. 51
7.3 Starting Modules.............................................................................................................................. 52
7.4 TwinCAT Loader.............................................................................................................................. 53
7.4.1 Test signing ..................................................................................................................... 53
7.4.2 Encrypting Modules ......................................................................................................... 55
7.4.3 Return Codes................................................................................................................... 57
7.4.4 TcSignTool - Storage of the certificate password outside the project.............................. 57
11 Debugging ................................................................................................................................................ 95
11.1 Details of Conditional Breakpoints................................................................................................... 98
11.2 Visual Studio tools ......................................................................................................................... 100
12 Wizards ................................................................................................................................................... 103
12.1 TwinCAT C++ Project Wizard........................................................................................................ 103
12.2 TwinCAT Module Class Wizard ..................................................................................................... 104
12.3 TwinCAT Module Class Editor (TMC)............................................................................................ 107
12.3.1 Overview........................................................................................................................ 109
12.3.2 Basic Information ........................................................................................................... 110
12.3.3 Data Types .................................................................................................................... 111
12.3.4 Modules ......................................................................................................................... 128
12.4 TwinCAT Module Instance Configurator........................................................................................ 150
12.4.1 Object ............................................................................................................................ 151
12.4.2 Context .......................................................................................................................... 152
12.4.3 Parameter (Init).............................................................................................................. 152
12.4.4 Data Area....................................................................................................................... 153
12.4.5 Interfaces ....................................................................................................................... 153
12.4.6 Interface Pointer ............................................................................................................ 153
12.4.7 Data Pointer................................................................................................................... 154
12.5 Customer-specific project templates ............................................................................................. 154
12.5.1 Overview........................................................................................................................ 154
12.5.2 Files involved ................................................................................................................. 155
12.5.3 Transformations............................................................................................................. 156
12.5.4 Notes on handling.......................................................................................................... 157
14 How to...?................................................................................................................................................ 234
14.1 Using the Automation Interface ..................................................................................................... 234
14.2 Windows 10 as target system up to TwinCAT 3.1 Build 4022.2 .................................................... 234
14.3 Publishing of modules ................................................................................................................... 234
14.4 Publishing modules on the command line ..................................................................................... 235
14.5 Clone ............................................................................................................................................. 235
14.6 Access Variables via ADS ............................................................................................................. 236
14.7 TcCallAfterOutputUpdate for C++ modules ................................................................................... 236
14.8 Order determination of the execution in a task .............................................................................. 236
14.9 Setting version/vendor information ................................................................................................ 237
14.10 Renaming TwinCAT C++ projects ................................................................................................. 238
14.11 Delete Module ............................................................................................................................... 240
15 Troubleshooting .................................................................................................................................... 253
15.1 Build - "Cannot open include file ntddk.h"...................................................................................... 253
15.2 Build - "The target ... does not exist in the project"........................................................................ 253
15.3 Debug - "Unable to attach" ............................................................................................................ 254
15.4 Activation – “invalid object id” (1821/0x71d) .................................................................................. 255
15.5 Error message - VS2010 and LNK1123/COFF ............................................................................. 255
15.6 Using C++ classes in TwinCAT C++ module ................................................................................ 255
15.7 Using afxres.h................................................................................................................................ 255
16 C++-samples .......................................................................................................................................... 257
16.1 Overview........................................................................................................................................ 257
16.2 Sample01: Cyclic module with IO .................................................................................................. 259
16.3 Sample02: Cyclic C++ logic, which uses IO from the IO Task ...................................................... 260
16.4 Sample03: C++ as ADS server ..................................................................................................... 260
16.4.1 Sample03: TC3 ADS Server written in C++................................................................... 261
16.4.2 Sample03: ADS client UI in C#...................................................................................... 265
16.5 Sample05: C++ CoE access via ADS ........................................................................................... 269
16.6 Sample06: UI-C#-ADS client uploading the symbolic from module .............................................. 270
16.7 Sample07: Receiving ADS Notifications........................................................................................ 275
16.8 Sample08: provision of ADS-RPC ................................................................................................. 276
16.9 Sample10: module communication: Using data pointer ................................................................ 279
16.10 Sample11: module communication: PLC module invokes method of C-module ........................... 280
16.10.1 TwinCAT 3 C++ module providing methods .................................................................. 281
16.10.2 Calling methods offered by another module via PLC .................................................... 296
16.11 Sample11a: Module communication: C module calls a method of another C module .................. 308
16.12 Sample12: module communication: Using IO mapping................................................................. 308
16.13 Sample13: Module communication: C-module calls PLC methods ............................................... 309
16.14 Sample19: Synchronous File Access ............................................................................................ 312
16.15 Sample20: FileIO-Write ................................................................................................................. 313
16.16 Sample20a: FileIO-Cyclic Read / Write ......................................................................................... 313
16.17 Sample22: Automation Device Driver (ADD): Access DPRAM ..................................................... 314
16.18 Sample23: Structured Exception Handling (SEH) ......................................................................... 316
16.19 Sample25: Static Library ............................................................................................................... 318
16.20 Sample26: Order of execution in a task ........................................................................................ 319
16.21 Sample30: Timing Measurement................................................................................................... 321
16.22 Sample31: Functionblock TON in TwinCAT3 C++ ........................................................................ 322
16.23 Sample35: Access Ethernet .......................................................................................................... 323
16.24 Sample37: Archive data ................................................................................................................ 324
16.25 TcCOM samples ............................................................................................................................ 325
17 Appendix ................................................................................................................................................ 344
17.1 ADS Return Codes ........................................................................................................................ 344
17.2 Retain data .................................................................................................................................... 349
17.3 Creating and handling C++ projects and modules ........................................................................ 351
17.4 Creating and handling TcCOM modules ....................................................................................... 355
1 Foreword
The responsible staff must ensure that the application or use of the products described satisfy all the
requirements for safety, including all the relevant laws, regulations, guidelines and standards.
Disclaimer
The documentation has been prepared with care. The products described are, however, constantly under
development.
We reserve the right to revise and change the documentation at any time and without prior announcement.
No claims for the modification of products that have already been supplied may be made on the basis of the
data, diagrams and descriptions in this documentation.
Trademarks
Beckhoff®, TwinCAT®, EtherCAT®, EtherCAT G®, EtherCAT G10®, EtherCAT P®, Safety over EtherCAT®,
TwinSAFE®, XFC®, XTS® and XPlanar® are registered trademarks of and licensed by Beckhoff Automation
GmbH.
Other designations used in this publication may be trademarks whose use by third parties for their own
purposes could violate the rights of the owners.
Patent Pending
The EtherCAT Technology is covered, including but not limited to the following patent applications and
patents:
EP1590927, EP1789857, EP1456722, EP2137893, DE102015105702
with corresponding applications or registrations in various other countries.
EtherCAT® is a registered trademark and patented technology, licensed by Beckhoff Automation GmbH,
Germany
Copyright
Exclusion of liability
All the components are supplied in particular hardware and software configurations appropriate for the
application. Modifications to hardware or software configurations other than those described in the
documentation are not permitted, and nullify the liability of Beckhoff Automation GmbH & Co. KG.
Personnel qualification
This description is only intended for trained specialists in control, automation and drive engineering who are
familiar with the applicable national standards.
Description of symbols
In this documentation the following symbols are used with an accompanying safety instruction or note. The
safety instructions must be read carefully and followed without fail!
DANGER
Serious risk of injury!
Failure to follow the safety instructions associated with this symbol directly endangers the life and health of
persons.
WARNING
Risk of injury!
Failure to follow the safety instructions associated with this symbol endangers the life and health of per-
sons.
CAUTION
Personal injuries!
Failure to follow the safety instructions associated with this symbol can lead to injuries to persons.
NOTE
Damage to the environment or devices
Failure to follow the instructions associated with this symbol can lead to damage to the environment or
equipment.
Tip or pointer
This symbol indicates information that contributes to better understanding.
2 Overview
This chapter is all about TwinCAT 3 implementation in C/C++. The most important chapters are:
• Start from scratch
Which platforms are supported? Additional installations to implement TwinCAT 3 C++ modules?
Find all answers in Requirements [} 20] and Preparation [} 22]. Limitations are documented here
[} 170].
• Quick start [} 61]
This is a “less than five minutes sample” to create a simple incrementing counter in C++ being
executed cyclically. Counter value will be monitored and overwritten, debugging capabilities will be
presented etc.
• MODULES [} 37]
Modularization the basic philosophy of TwinCAT 3. Especially for C++ Modules it is required to
understand the module concept of TwinCAT 3.
Minimum is to read one article about the architecture of TwinCAT modules.
• Wizards [} 103]
Documentation of visual components of the TwinCAT C++ environment.
This includes on the one hand tools for creating projects and on the other hand tools for editing module
and configuring instances of modules.
• Programming Reference [} 160]
This chapter contains detailed information for programming in TwinCAT C++. For Example Interfaces
as well as other TwinCAT provided functions for ADS communication and helper methods are located
here.
• The How to …? [} 234] Chapter contains useful hints while working with TwinCAT C++.
• Samples [} 257]
Some Interfaces and their usage is best described by working code, which is provided as download
including source code and solution.
3 Introduction
The method of emulating classic automation devices such as programmable logic controllers (PLC) and
numerical controllers (NC) as software on powerful standard hardware has been the state of the art for many
years and is now practiced by many manufacturers.
There are many benefits, but the most important is without doubt the fact that the software is mostly
hardware-independent. This means, firstly, that the performance of the hardware can be specially adapted to
the application and, secondly, that you can automatically benefit from its further development.
This particularly applies to PC hardware, whose performance is still increasingly at a dramatically fast rate.
The relative independence from a supplier that results from this separation of software and hardware is also
very important for the user.
Since the PLC and Motion Control – and possibly other automation components – remain independent logic
function blocks with this method, there are only a few changes in the application architecture in comparison
with classic automation technology.
The PLC determines the machine's logical processes and transfers the implementation of certain axis
functions to the Motion Control. On account of the improved performance of the controllers and the
possibility to use higher-level programming languages (IEC 61131-3), even complex machines can be
automated in this way.
Modularization
In order to master the complexity of modern machines and at the same time to reduce the necessary
engineering expenditure, many machine manufacturers have begun to modularize their machines. Individual
functions, assemblies or machine units are thereby regarded as modules, which are as independent as
possible and are embedded into the overall system via uniform interfaces.
Ideally a machine is then structured hierarchically, whereby the lowest modules represent the simplest,
continually reusable basic elements. Joined together they form increasingly complex machine units, up to the
highest level where the entire machine is created. Different approaches are followed when it comes to the
control system aspects of machine modularization. These can be roughly divided into a decentralized and a
centralized approach.
In the local approach, each machine module is given its own controller, which determines the PLC functions
and possibly also the motion functions of the module.
The individual modules can be put into operation and maintained separately from one another and scaled
relatively independently. The necessary interactions between the controllers are coordinated via
communication networks (fieldbuses or Ethernet) and standardized via appropriate profiles.
The central approach concentrates all control functions of all modules in the common controller and uses
only very little pre-processing intelligence in the local I/O devices. The interactions can occur much more
directly within the central control unit, as the communication paths become much shorter. Dead times do not
occur and use of the control hardware is much more balanced, which reduces overall costs.
However, the central method also has the disadvantage that the necessary modularization of the control
software is not automatically specified. At the same time, the possibility of being able to access any
information from other parts of the program in the central controller obstructs the module formation and the
reusability of this control software in other applications. Since no communication channel exists between the
control units, an appropriate profile formation and standardization of the control units frequently fall by the
wayside.
The ideal controller for modular machines uses elements from decentralized and centralized control
architecture. A central, powerful computer platform of the most general kind possible serves 'as always' as
the control hardware.
The above-mentioned benefits of a decentralized approach can be implemented in the centralized control
system by means of suitable modularization of the control software.
Instead of allowing a large, complex PLC program and an NC with many axes to run, many small ‘controllers’
can co-exist in a common runtime on the same hardware with relative independence from one another. The
individual control modules are self-contained and make their functions available to the environment via
standard interfaces, or they use corresponding functions of other modules or the runtime.
A significant profile is created through the definition of these interfaces and the standardization of the
corresponding parameters and process data. Since the individual modules are implemented in a runtime,
direct calls of other modules are also possible – once again via corresponding standard interfaces. In this
way the modularization can take place within sensible limits without communication losses occurring.
During the development or commissioning of individual machine modules, the associated control modules
can be created and tested on any control hardware with the appropriate runtime. Missing connections to
other modules can be emulated during this phase. On the complete machine they are then instanced
together on the central runtime, which only needs to be dimensioned such that the resource requirements of
all instanced modules (memory, tasks and computing power) are fulfilled.
TwinCAT 3 Run-Time
The TwinCAT runtime offers a software environment in which TwinCAT modules are loaded, implemented
and managed. It offers additional basic functions so that the system resources can be used (memory, tasks,
fieldbus and hardware access etc.). The individual modules do not have to be created using the same
compiler and can therefore be independent of one another and can originate from different manufacturers.
A series of system modules is automatically loaded at the start of the runtime, so that their properties are
available to other modules. However, access to the properties of the system modules takes place in the
same way as access to the properties of normal modules, so that it is unimportant to the modules whether
the respective property is made available by a system module or a normal module.
In contrast to the PLC, where customer code is executed within a runtime environment, TwinCAT C++
modules are not within such a hosted environment. As a consequence TwinCAT C++ modules are executed
as Kernel Modules (.sys) – thus they are built with the kernel mode libraries.
The article particularly focuses on real-time programming with TwinCAT C++, because this is where previous
knowledge with C++ programming comes to the fore and the sequence characteristics of the TwinCAT real-
time system have to be taken into account.
With conventional user mode programming, e.g. in C#, a program is created, which is then executed by an
operating system.
The program is started by the operating system and can run independently, i.e. it has full control over its own
execution, including aspects such as threading and memory management. In order to enable multitasking,
the operating system interrupts such a program at any time and for any period. The program does not
register such an interruption. The operating system must ensure that such interruptions remain unnoticed by
the user. The data exchange between the program and its environment is event-driven, i.e. non-deterministic
and often blocking.
The behavior is not adequate for execution under real-time conditions, because the application itself must be
able to rely on the available resources in order to be able to ensure real-time characteristics (response
guarantees).
The basic idea of PLC is therefore adopted for TwinCAT C++: The TwinCAT real-time system manages the
real-time tasks, handles the scheduling and cyclically calls an entry point in the program code. The program
execution must be completed within the available cycle length and return the control. The TwinCAT system
makes the data from the I/O area available in the process images, so that consistent access can be
guaranteed. This means that the program code itself cannot use mechanisms such as threading.
Concurrency
With conventional programming in user mode, concurrency is controlled by the program. This is where
threads are started, which communicate with each other. All these mechanisms require resources, which
have to be allocated and enabled, which can compromise the real-time capability. The communication
between the threads is event-based, so that a calling thread has no control over the processing time in the
called thread.
In TwinCAT, tasks are used for calling modules, which therefore represents concurrency. Tasks are
assigned to a core; they have cycle times and priorities, with the result that a higher-priority task can interrupt
a lower-priority task. If several cores are used, tasks are executed concurrently in practice.
Modules can communicate with each other, so that data consistency has to be ensured in concurrency
mode.
Data exchange across task boundaries is enabled through mapping, for example. When direct data access
via methods is used, it must be protected through Critical sections, for example.
Startup/shutdown behavior
The TwinCAT C++ code is executed in the so-called "Windows kernel context" and the "TwinCAT real-time
context", not as a user mode application.
During startup/shutdown of the modules, code for (de)initialization is initially executed in the Windows kernel
context; only the last phase and the cyclic calls are executed in the TwinCAT real-time context.
Memory management
TwinCAT has its own memory management, which can also be used in the real-time context. This memory is
obtained from what is referred to as the "non-paged pool", which is provided by the operating system. In this
memory the TcCOM modules are instantiated with their memory requirement.
In addition, the so-called "router memory" is provided by TwinCAT in this memory area, from which the
TcCOM modules can allocate memory dynamically in the real-time-context (e.g. with the New operator).
If possible, memory should generally be allocated in advance, not in the cyclic code. During each allocation a
check is required to verify that the memory is actually available. For allocations in the cyclic code, the
execution therefore depends on the memory availability.
4 Requirements
Overview of minimum requirements
◦ When installing Visual Studio 2017, the Desktop development with C++ option must be manually
selected, as this option is not selected with the automatic installation:
Overview
The Microsoft Windows Driver Kit (WDK) enables the development of Windows kernel drivers. TwinCAT C++
drivers are based on this WDK.
• TwinCAT 3.1 4022:
The implementation of TwinCAT 3 C++ modules requires parts of the Windows Driver Kit 7 (WDK 7) up
to TwinCAT 3.1 4022.
• TwinCAT 3.1 4024:
From Build 4024, the WDK is no longer required, as TwinCAT provides the required components. If the
environment variable WINDDK7 (as described below) exists, the WDK is used, otherwise not.
The use of the WDK can also be configured project-related via the TwinCAT C++ project [} 160].
The installation is only necessary for the TwinCAT 3 engineering environment in order to be able to create
and edit C++ modules. The WDK installation is not required on the target system (XAR).
1. Download the Windows Driver Kit 7.1 from the Microsoft Download Center https://www.microsoft.com/
en-us/download/details.aspx?id=11800.
2. Following the download, either burn a CD of the downloaded ISO image or use a virtual (software-based)
CD drive.
3. Start KitSetup.exe of the ISO image that has been downloaded or burnt on CD (on Windows 7 PCs, start
the installation with Run As Administrator...).
4. Select the option Build Environment – none of the other components are required by TwinCAT 3 – and
click on OK to continue.
5. After accepting the Microsoft EULA license, select the destination folder for the installation.
By default the root folder "C:\" will be selected - therefore "C:\WinDDK\7600.16385.1" will be
suggested.
The digits "7600…." may be different in the case of a newer version of the Windows Driver Kit.
7. In future TwinCAT 3 will take care of the following step, but for now it must be done manually: Navigate
to Start-> Control Panel -> System and select Advanced system settings.
8. Select the Advanced tab and then click on Environment Variables…
9. In the lower area of System variables, select New.. and enter the following information:
Variable name "WINDDK7"
Variable value "C:\WinDDK\7600.16385.1"
The path may differ with a different version of the Windows Driver Kit or if a different installation path is
specified.
10. Following the installation, log in again or restart the PC to confirm the new environment variable settings.
TwinCAT 3 integrates its own toolbar in the Visual Studio menu for better efficiency. It assists you in the
creation of C++ projects. This toolbar is automatically added to the Visual Studio menu by the TwinCAT 3
setup. If you wish to add it manually, however, do the following:
1. Open the View menu and select Toolbars\TwinCAT XAE Base
ð The selected toolbar appears below the menu.
With the Configuration and Platform toolbar you can specify the target platform for the creation of your
project. This toolbar is automatically added to the Visual Studio menu by the TwinCAT 3 setup. If you wish to
add it manually, however, do the following:
1. Open the View menu and select Toolbars\Customize.
2. Navigate to the Commands tab.
3. Activate the Toolbar option field and then select the Standard toolbar from the list.
4. Click on Add Command...
5. Select the Build category, select the Solution Configurations command and then click on OK.
6. Repeat the last step for the Solution Platforms command.
7. Click on Close.
ð The two commands now appear below the menu bar.
The signature ensures that only C++ software whose origin can be traced is executed on productive
systems.
For test purposes, certificates that cannot be verified can be used for signing. However, this is only possible
if the operating system is in test mode so that these certificates are not used on productive systems.
There are two ways to load modules, different certificates are used for signing:
• Operating system: The C++ modules are loaded as normal kernel drivers and must therefore also have
a signature.
◦ With TwinCAT 3.1. 4022 or earlier, only this procedure is available.
◦ Windows 7 (Embedded) x86 (32bit) does not require signing.
• TwinCAT: The C++ modules are loaded by the TwinCAT runtime system and must be signed with a
TwinCAT user certificate.
◦ With TwinCAT 3.1. 4024 and higher, this method is also available.
◦ This procedure is required to perform new functions such as versioned C++ projects [} 49] and
thus also the C++ Online Change [} 168].
Since a published module should be executable on various PCs, signing is always necessary for publishing.
1. A certificate which is not countersigned, thus the test mode is needed for the development process.
This certificate can also be issued individually by each developer.
2. Only the software that has passed the corresponding final tests is signed by a countersigned certifi-
cate. This software can thus also be installed on machines and delivered.
Such a separation of development and operation ensures that only tested software runs on productive
systems.
The signature, which is automatically executed during the TwinCAT 3 build process, is used by 64-bit
Windows operating systems for the authentication of the drivers.
A certificate is required to sign a driver. This Microsoft documentation describes the process and
background knowledge for obtaining a test and release certificate that is accepted by 64-bit Windows
operating systems.
To use such a certificate in TwinCAT 3, configure the step after compiling your x64 build target as
documented in "Creating a test certificate for test mode [} 27]".
Test certificates
For testing purposes, self-signed test certificates can be created and used without technical limitations.
Further references:
Overview
Implementing TwinCAT 3 C++ modules for x64 platforms requires signing the driver with a certificate.
This article describes how to create and install a test certificate for testing a C++ driver.
The following commands must be executed from a command line that has been opened in either way:
• Visual Studio 2010 / 2012 prompt with administrator rights. (Via: All Programs -> Microsoft
Visual Studio 2010/2012 -> Visual Studio Tools -> Visual Studio Command Prompt, then right-click
Run as administrator)
• Normal prompt (Start->Command Prompt) with administrator rights, then change to directory
%WINDDK7%\bin\x86\, which contains the corresponding tools.
1. On XAE:
in the engineering system enter the following command in the Visual Studio 2010 / 2012 prompt with
administrator rights (see note above):
makecert -r -pe -ss PrivateCertStore -n CN=MyTestSigningCert
MyTestSigningCert.cer
(If you do not have access rights to the PrivateCertStore, you can use a different location. This
must also be used in the PostBuild event, as described here. [} 30])
ð This is followed by creation of a self-signed certificate, which is stored in the file
"MyTestSigningCert.cer" and in the Windows Certificate Store.
ð Check the result with mmc (Use File->Add/Remove Snap-in->Certificates):
2. On XAE:
configure the certificate so that it is recognized by TwinCAT XAE on the engineering system.
Set the environment variable TWINCATTESTCERTIFICATE to "MyTestSigningCert" in the engineering
system or edit the post build event of Debug|TwinCAT RT (x64) and Release|TwinCAT RT (x64).
The name of the variable is NOT the name of the certificate file, but the CN name (in this case
MyTestSigningCert).
Note From TwinCAT 3.1 4024.0, the configuration of the certificate to be used is carried out under Tc
Sign in the project properties.
3. On XAR (and XAE, if local test)
activate the test mode so that Windows can accept the self-signed certificates. This can be done on both
engineering systems (XAE) and runtime systems (XAR).
4. Execute the following using the "Run as administrator" option:
bcdedit /set testsigning yes
and restart the target system.
ð If test signing mode is enabled, this is displayed at the bottom right of the desktop. The PC now
accepts all signed drivers for execution.
5. You may have to switch off "SecureBoot" for this, which can be done in the bios.
6. Test whether a configuration with a TwinCAT module implemented in a TwinCAT C++ driver can be
enabled and started on the target system.
ð Compilation of the x64 driver generates the following output:
References:
MSDN, test certificates (Windows driver)
MSDN, MakeCert test certificates (Windows driver),
Overview
1. Start the management console MMC.exe via the Start menu or the user interface.
2. Click in the menu on File -> Add/Remove Snap-in.. and select the certificate snap-in for the current
user; conclude with OK.
If the TwinCAT C++ class wizard is used, the project is prepared for x64 targets using the test certificate
procedure described above.
This test signing system can be used for the entire engineering and test process.
If you want to create an infrastructure and sign the kernel drivers with official "Microsoft trusted" certificates,
the post-build events of the project properties provide the entry point.
The customer can simply replace the value of the environment variable TWINCATTESTCERTIFICATE or
determine another certificate to be used.
The customer can also change the whole signing process with the signing tool.
In this case a CrossSigning is necessary for the Windows drivers. The parameter for the signtool is "/ac".
The certificate provider provides the necessary information. Microsoft provides an overview here.
In this case, the TwinCAT C++ drivers must also be signed by the "Attestation Signing" established by
Microsoft in the same way as all other drivers that the operating system is to load. The procedure for this is
documented in MSDN.
For development purposes, the development process can be simplified on corresponding test systems by
deactivating SecureBoot.
5.4.2 TwinCAT
Versioned C++ projects are stored as binary in a TMX file (TwinCAT Module Executeable).
For the implementation of TwinCAT 3 C++ modules, this compiled, executable TMX file must be signed with
a TwinCAT user certificate if it is to be loaded by the TwinCAT Runtime.
For signing a TMX file, a TwinCAT user certificate is required [} 32], which is configured accordingly in the
project for signing.
The TMX file must then be loaded by the TwinCAT Loader [} 53], for which corresponding settings are made
in the project during the construction process.
NOTE
Signing on 32bit and 64bit systems
In contrast to the operating system signature, TwinCAT signing is intended for both 32bit and 64bit sys-
tems. Thus, the test mode is assumed for a test signature also on 32-bit systems.
Note In contrast to the operating system signature, TwinCAT signing is intended for both 32bit and
64bit systems. Thus, the test mode is assumed for a test signature also on 32-bit systems.
Test signing
Just as with the option of loading drivers through the operating system, TwinCAT also provides the test
mode of the operating system for loading.
As soon as the TwinCAT user certificate has been countersigned by Beckhoff [} 34], the test mode can be
dispensed with accordingly.
4. You may have to switch off "SecureBoot" for this, which can be done in the bios.
5. During the initial activation (Activate Configuration) with a TwinCAT user certificate, the target system will
determine that the certificate is not trusted and the activation process will be aborted:
A local user with administrator rights can trust the certificate through simple running via the created REG
file.
This process only enables modules with a signature from the trusted TwinCAT user certificates to run.
6. Following this process you can use the TwinCAT user certificate for signing with the test mode of the
operating system.
This is configured in the project properties [} 165].
Use the TcSignTool [} 57] to avoid storing the password of the TwinCAT user certificate in the project,
where it would also end up in version management, for example.
If you have this TwinCAT user certificate countersigned by Beckhoff, you can also use it for delivery without
TestMode.
With a countersigned TwinCAT user certificate, the test mode is no longer required.
6 Modules
The TwinCAT module concept is one of the core elements for the modularization of modern machines. This
chapter describes the modular concept and working with modules.
The modular concept applies to all TwinCAT modules, not just C++ modules, although most details only
relate to the engineering of C++ modules.
To some degree TcCOM is based on COM (Component Object Model of the Microsoft Windows world),
although only a subset of COM is used. In comparison with COM, however, TcCOM contains additional
definitions that go beyond COM, for example the state machine module.
This introductory overview is intended to make the individual topics easier to understand.
One or several TcCOM modules are consolidated in a driver. This driver is created by TwinCAT Engineering
using the MSVC compiler. The modules and interfaces are described in a TMC (TwinCAT Module Class) file.
The drivers and their TMC file can now be exchanged and combined between the engineering systems.
Instances of these modules are now created using the engineering facility. They are associated with a TMI
file. The instances can be parameterized and linked with each other and with other modules to form the IO. A
corresponding configuration is transferred to the target system, where it is executed.
Corresponding modules are started, which register with the TwinCAT ObjectServer. The TwinCAT XAR also
provides the process images. Modules can query the TwinCAT ObjectServer for a reference to another
object with regard to a particular interface. If such a reference is available, the interface methods can be
called on the module instance.
ID Management
Different types of ID are used for the interaction of the modules with each other and also within the modules.
TcCOM uses GUIDs (128 bit) and 32 bit long integers.
TcCOM uses
• GUIDs for: ModulIDs, ClassIDs and InterfaceIDs.
• 32 bit long integers are used for: ParameterIDs, ObjectIDs, ContextIDs, CategoryID.
Interfaces
Interfaces define a set of methods that are combined in order to perform a certain task. An interface is
referenced with a unique ID (InterfaceID), which must never be modified as long as the interface does not
change. This ID enables modules to determine whether they can cooperate with other modules. At the same
time the development process can take place independently, if the interfaces are clearly defined.
Modifications of interfaces therefore lead to different IDs. The TcCOM concept is designed such that
InterfaceIDs can superpose other (older) InterfaceIDs ( "Hides" in the TMC description / TMC editor). In this
way, both versions of the interface are available, while on the other hand it is always clear which is the latest
InterfaceID. The same concept also exists for the data types.
TcCOM itself already defines a whole series of interfaces that are prescribed in some cases (e.g.
ITComObject), but are optional in most. Many interfaces only make sense in certain application areas. Other
interfaces are so general that they can often be re-used. Provision is made for customer-defined interfaces,
so that two third-party modules can interact with each other, for example.
• All interfaces are derived from the basic interface ItcUnknown which, like the corresponding interface of
COM, provides the basic services for querying other interfaces of the module (TcQueryInterface) and
for controlling the lifetime of the module (TcAddRef and TcRelease).
• The ITComObject interface, which must be implemented by each module, contains methods for
accessing the name, ObjectID, ObjectID of the parent, parameters and state machine of the module.
A whole series of general interfaces has already been defined. General interfaces have the advantage that
their use supports the exchange and recycling of modules. User-defined interfaces should only be defined if
no suitable general interfaces are available.
Class Factories
"Class Factories" are used for creating modules in C++. All modules contained in a driver have a common
Class Factory. The Class Factory registers once with the ObjectServer and offers its services for the
development of certain module classes. The module classes are identified by the unique ClassID of the
module. When the ObjectServer requests a new module (based on the initialization data of the configurator
or through other modules at runtime), the module selects the right Class Factory based on the ClassID and
triggers creation of the module via its ITcClassFactory interface.
Similar to COM, the service life of a module is determined via a reference counter (RefCounter). The
reference counter is incremented whenever a module interface is queried. The counter is decremented when
the interface is released. An interface is also queried when a module logs into the ObjectServer (the
ITComObject interface), so that the reference counter is at least 1. The counter is decremented on logout.
When the counter reaches 0, the module deletes itself automatically, usually after logout from the
ObjectServer. If another module already maintains a reference (has an interface pointer), the module
continues to exist, and the interface pointer remains valid, until this pointer is released.
If a module is instantiated in the TwinCAT runtime, it registers itself with a central system instance, the
ObjectServer. This makes it reachable and parameterizable for other modules and also for general tools.
Modules can be compiled independently and can therefore also be developed, tested and updated
independently. Modules can be very simple, e.g. they may only contain a basic function such as low-pass
filter. Or they may be very complex internally and contain the whole control system for a machine
subassembly.
There are a great many applications for modules; all tasks of an automation system can be specified in
modules. Accordingly, no distinction is made between modules, which primarily represent the basic functions
of an automation system, such as real-time tasks, fieldbus drivers or a PLC runtime system, and user- or
application-specific algorithms for controlling a machine unit.
The diagram below shows a common TwinCAT module with his main properties. The dark blue blocks define
prescribed properties, the light blue blocks optional properties.
Module description
Each TcCOM module has some general description parameters. These include a ClassID, which
unambiguously references the module class. It is instantiated by the corresponding ClassFactory. Each
module instance has an ObjectID, which is unique in the TwinCAT runtime. In addition there is a parent
ObjectID, which refers to a possible logical parent.
The description, state machine and parameters of the module described below can be reached via the
ITComObject interface (see "Interfaces").
The module classes are described in class description files (TwinCAT Module Class; *.tmc).
These files are used by developers to describe the module properties and interfaces, so that others can use
and embed the module. In addition to general information (vendor data, module class ID etc.), optional
module properties are described.
• Supported categories
• Implemented interfaces
• Data areas with corresponding symbols
• Parameter
• Interface pointers
• Data pointers, which can be set
The system configurator uses the class description files mainly as a basis for the integration of a module
instance in the configuration, for specifying the parameters and for configuring the links with other modules.
They also include the description of all data types in the modules, which are then adopted by the configurator
in its general data type system. In this way, all interfaces of the TMC descriptions present in the system can
be used by all modules.
More complex configurations involving several modules can also be described in the class description files,
which are preconfigured and linked for a specific application. Accordingly, a module for a complex machine
unit, which internally consists of a number of submodules, can be defined and preconfigured as an entity
during the development phase.
An instance of a certain module is described in the instance description file (TwinCAT Module Instance;
*.tmi). The instance descriptions are based on a similar format, although in contrast to the class description
files they already contain concrete specifications for the parameters, interface pointers etc. for the special
module instance within a project.
The instance description files are created by TwinCAT Engineering (XAE), when an instance of a class
description is created for a specific project. They are mainly used for the exchange of data between all tools
involved in the configuration. However, the instance descriptions can also be used cross-project, for example
if a specially parameterized module is to be used again in a new project.
State machine
Each module contains a state machine, which describes the initialization state of the module and the means
with which this state can be modified from outside. The state machine describes the states, which occur
during starting and stopping of the module. This relates to module creation, parameterization and production
in conjunction with the other modules.
Application-specific states (e.g. of the fieldbus or driver) can be described in their own state machines. The
state machine of the TcCOM modules defines the states INIT, PREOP, SAFEOP and OP. Although the state
designations are the same as under EtherCAT fieldbus, the actual states differ. When the TcCOM module
implements a fieldbus driver for EtherCAT, it has two state machines (module and fieldbus state machine),
which are passed through sequentially. The module state machine must have reached the operating state
(OP) before the fieldbus state machine can start.
Parameter
Modules can have parameters, which can be read or written during initialization or later at runtime (OP
state). Each parameter is designated by a parameter ID. The uniqueness of the parameter ID can be global,
limited global or module-specific. Further details can be found in the "ID Management" section. In addition to
the parameter ID, the parameter contains the current data; the data type depends on the parameter and is
defined unambiguously for the respective parameter ID.
Interfaces
Interfaces consist of a defined set of methods (functions), which offer modules through which they can be
contacted by other modules. Interfaces are characterized by a unique ID, as described above. A module
must support at least the ITComObject interface and may in addition contain as many interfaces as required.
An interface reference can be queried by calling the method "TcQueryInterface" with specification of the
corresponding interface ID.
Interface pointers
Interface pointers behave like the counterpart of interfaces. If a module wants to use an interface of another
module, it must have an interface pointer of the corresponding interface type and ensure that it points to the
other module. The methods of the other module can then be used.
Interface pointers are usually set on startup of the state machine. During the transition from INIT to PREOP
(IP), the module receives the object ID of the other modules with the corresponding interface; during the
transition from PREOP to SAFEOP (PS) or SAFEOP to OP (SO), the instance of the other modules is
searched with the ObjectServer, and the corresponding interface is set with the Method Query interface.
During the state transition in the opposite direction, i.e. from SAFEOP to PREOP (SP) or OP to SAFEOP
(OS), the interface must be enabled again.
Data areas
Modules can contain data areas, which can be used by the environment (e.g. by other modules or the IO
area of TwinCAT). These data areas can contain any data. They are often used for process image data
(inputs and outputs). The structure of the data areas is defined in the device description of the module. If a
module has data areas, which it wants to make accessible for other modules, it implements the ITcADI
interface to enable access to the data. Data areas can contain symbol information, which describes the
structure of the respective data area in more detail.
If a module wants to access the data area of other modules, it can contain data area pointers. These are
normally set during initialization of the state machine to data areas or data area sections of other modules.
The access is directly to the memory area, so that corresponding protection mechanisms for competing
access operations have to be implemented, if necessary. In many cases it is preferable to use a
corresponding interface.
Context
The context should be regarded as real-time task context. Context is required for the configuration of the
modules, for example. Simple modules usually operate in a single time context, which therefore requires no
detailed specification. Other modules may partly be active in several contexts (e.g. an EtherCAT master can
support several independent real-time tasks, or a control loop can process control loops of the layer below in
another cycle time). If a module has more than one time-dependent context, this must be specified the in the
module description.
Categories
Modules can offer categories by implementing the interface ITComObjectCategory. Categories are
enumerated by the ObjectServer, and objects, which use this to associated themselves with categories, can
be queried by the ObjectServer (ITComObjectEnumPtr).
ADS
Each module that is entered in the ObjectServer can be reached via ADS. The ObjectServer uses the
ITComObject interface of the modules in order to read or write parameters or to access the state machine,
for example. In addition, a dedicated ADS port can be implemented, through which dedicated ADS
commands can be received.
System module
In addition, the TwinCAT runtime provides a number of system modules, which make the basic runtime
services available for other modules. These system modules have a fixed, constant ObjectID, through which
the other modules can access it. An example for such a system module is the real-time system, which makes
the basic real-time system services, i.e. generation of real-time tasks, available via the ITcRTime interface.
The ADS router is also implemented as a system module, so that other modules can register their ADS port
here.
Creation of modules
Modules can be created both in C++ and in IEC 61131-3. The object-oriented extensions of the TwinCAT
PLC are used for this purpose. Modules from both worlds can interact via interfaces in the same way as pure
C++ modules. The object-oriented extension makes the same interfaces available as in C++.
The PLC modules also register via the ObjectServer and can therefore be reached through it. PLC modules
vary in terms of complexity. It makes no difference whether only a small filter module is generated or a
complete PLC program is packed into a module. Due to the automation, each PLC program is a module
within the meaning of TwinCAT modules. Each conventional PLC program is automatically packed into a
module and registers itself with the ObjectServer and one or several task modules. Access to the process
data of a PLC module (e.g. mapping with regard to a fieldbus driver) is also controlled via the defined data
areas and ITcADI.
This behavior remains transparent and invisible for PLC programmers, as long as they decide to explicitly
define parts of the PLC program as TwinCAT modules, so that they can be used with suitable flexibility.
resulting in the following state transitions: INIT to PREOP (IP), PREOP to SAFEOP (PS) and SAFEOP to OP
(SO). In the opposite direction there are the following state transitions: OP to SAFEOP (OS), SAFEOP to
PREOP (SP) and PREOP to INIT (PI). Up to and including the SAFEOP state, all states and state transitions
take place within the non-real-time context. Only the transition from SAFEOP to OP, the OP state and the
transition from OP to SAFEOP take place in the real-time context. This differentiation is relevant when
resources are allocated or activated, or when modules register or deregister with other modules.
State: INIT
The INIT state is only a virtual state. Immediately after creation of a module, the module changes from INIT
to PREOP, i.e. the IP state transition is executed. The instantiation and the IP state transition always take
place together, so that the module never remains in INIT state. Only when the module is removed does it
remain in INIT state for a short time.
During the IP state transition, the module registers with the ObjectServer with its unique ObjectID. The
initialization parameters, which are also allocated during object creation, are transferred to the module.
During this transition the module cannot establish connections to other modules, because it is not clear
whether the other modules already exist and are registered with the ObjectServer. When the module
requires system resources (e.g. memory), these can be allocated during the state transition. All allocated
resources have to be released again during the transition from PREOP to INIT (PI).
State: PREOP
In PREOP state, module creation is complete and the module is usually fully parameterized, even if further
parameters may be added during the transition from PREOP to SAFEOP. The module is registered in the
ObjectServer, although no connections with other modules have been created yet.
In this state transition the module can establish connections with other modules. To this end it has usually
received, among other things, ObjectIDs of other modules with the initialization data, which are now
converted to actual connections with these modules via the ObjectServer.
The transition can generally be triggered by the system according to the configurator, or by another module
(e.g. the parent module). During this state transition further parameters can be transferred. For example, the
parent module can transfer its own parameters to the child module.
State: SAFEOP
The module is still in the non-real-time context and is waiting to be switched to OP state by the system or by
other modules.
The state transition from SAFEOP to OP, the state OP, and the transition from OP to SAFEOP take place in
the real-time context. System resources may no longer be allocated. On the other hand, resources can now
be requested by other modules, and modules can register with other modules, e.g. in order to obtain a cyclic
call during tasks.
This transition should not be used for long-running tasks. For example, file operations should be executed
during the PS transition.
State: OP
In OP state the module starts working and is fully active in the meaning of the TwinCAT system.
This state transition takes place in the real-time context. All actions from the SO transition are reversed, and
all resources requested during the SO transition are released again.
All actions from the PS transition are reversed, and all resources requested during the PS transition are
released again.
All actions from the IP transition are reversed, and all resources requested during the IP transition are
released again. The module signs off from the ObjectServer and usually deletes itself (see "Service life").
The inputs and outputs of TcCOM modules can be linked by IO Mapping in the same way as the links to
physical symbols in the fieldbus level. To do this, data areas are created in the TMC editor [} 138] that
describe the corresponding inputs/outputs. These are then linked in the TwinCAT solution.
Through mapping, the data are provided or accepted at the task beginning (inputs) or task end (outputs)
respectively. The data consistency is ensured by synchronous or asynchronous mapping.
IO Data Pointer
Direct memory access is also possible within a task via the Data Area Pointers, which are created in the
TMC Editor.
If several callers of a task or callers from other tasks occur, the user must ensure the data consistency
through appropriate mechanisms. Data pointers are available for C++ and Matlab.
As already described, TcCOM modules can offer interfaces that are also defined in the TMC editor. If a
module implements them ("Implemented Interfaces" in the TMC editor [} 130]), it offers appropriate methods.
A calling module will then have an "Interface Pointer" to this module in order to call the methods.
These are blocking calls, meaning that the caller blocks until the called methods come back and the return
values of the methods can thus be directly used. If several callers of a task or callers from other tasks occur,
the user must ensure the data consistency through appropriate mechanisms.
Further samples exist for the communication with the PLC [} 325].
ADS
As the internal communication of the TwinCAT system in general, ADS can also be used to communicate
between modules. Communication in this case is acyclic, event-controlled communication.
At the same time ADS can also be used to collect or provide data from the UserMode and communicate with
other controllers (i.e. via the network). ADS can also be used to ensure data-consistent communication, e.g.
between tasks/cores/CPUs. In this case TcCOM modules can be both clients (requesters) and servers
(providers). The implementing language (PLC, C++, Matlab) is unimportant.
Sample06: UI-C#-ADS client uploads the symbols from the module [} 270]
7 Modules - Handling
TcCOM modules are implemented and loaded after a build.
This section describes the handling of modules when they are exchanged between systems.
Versioned TwinCAT C++ projects result in an architecture-dependent TMX file during building and are
loaded via the TwinCAT Loader [} 53]. They must be signed by a TwinCAT user certificate.
If a C++ project was created using the template "Versioned C++ Project", the binary files are stored by a
publish in the TwinCAT repository under C:\TwinCAT\3.x\Repository at a vendor- and version-specific
location.
From here required modules are transferred to the target system under C:\TwinCAT\3.1\Boot\Repository, if
they are needed.
This can be either at the time of activation (Activate Configuration) or at the time of the Online Change
[} 168].
Additionally, it is possible to create an archive for the transfer between engineering systems of the binary
version of this project, which is configured by the project properties [} 164].
If a C++ project has been created using the TwinCAT Driver Project template, the binary files are stored in
the TwinCAT folder under C:\TwinCAT\3.x\CustomConfig\Modules by a publish.
From here the driver is transferred to the target system under C:\TwinCAT\3.x\Driver if it is needed.
Additionally, it is possible to create an archive for the transfer of the binary version of this project, which is
configured by the project properties [} 164].
Before Release 4024.0, the handling of the export and import functionality was somewhat different, which is
documented on the subpages.
The binary files and the TMC module description are exported to the TempContr folder under C:
\TwinCAT\3.x\CustomConfig\Modules.
4. For the import, simply copy the TempContr folder to any other TwinCAT 3 machine.
ð The TestDriver (in the subfolders RT and UM) and the corresponding TwinCAT module Class *.tmc
file TestDriver.tmc are then available.
ð The new CTestModule module is listed in the dialog box that appears.
4. Create a module instance by selecting the module name and continue with OK.
ð The instance of the TestModule module now appears under TcCom Objects.
5. Create a new task.
6. Go to the context of the module instance and link the C++ module instance with the previously added
Task 1.
7. Activate the configuration.
• TwinCAT Loader: [} 53] The TwinCAT Loader starts the TwinCAT module.
◦ The TwinCAT Loader requires a signature [} 25] with TwinCAT user certificate.
◦ This option is mandatory for encrypted modules [} 55].
◦ The TwinCAT Loader is required for the versioned C++ projects [} 103].
Via System -> TcCOM Modules -> Class Factories tab you can see whether the TwinCAT Loader or the
operating system is used:
1. For test operation, e.g. during software development, the creation of a TwinCAT user certificate, as
described here, is sufficient. Make sure that you select the purpose "Sign TwinCAT C++ executable
(*.tmx)". For this the Crypto version 2 is required, a message appears.
ð If test signing mode is enabled, this is displayed at the bottom right of the desktop. The PC now
accepts all signed drivers for execution.
4. You may have to switch off "SecureBoot" for this, which can be done in the bios.
5. During the initial activation (Activate Configuration) with a TwinCAT user certificate, the target system will
determine that the certificate is not trusted and the activation process will be aborted:
A local user with administrator rights can trust the certificate through simple running via the created REG
file.
This process only enables modules with a signature from the trusted TwinCAT user certificates to run.
6. Following this process you can use the TwinCAT user certificate for signing with the test mode of the
operating system.
This is configured in the project properties [} 165].
Use the TcSignTool [} 57] to avoid storing the password of the TwinCAT user certificate in the project,
where it would also end up in version management, for example.
If you have this TwinCAT user certificate countersigned by Beckhoff, you can also use it for delivery without
TestMode.
No debugging
Encrypted modules cannot be searched for errors. Encrypted modules are not displayed in the de-
bugger.
3. To start, an encrypted module must be loaded with the TwinCAT Loader (not the operating system).
ð For non-versioned drivers: The drivers are encrypted during transfer to the _deployment directory of the
project.
ð For versioned TMX: The drivers are stored unencrypted in XAE and encrypted when they are activated
on the target system.
ð If the function is used with versioned C++ projects, the TMX files are stored in the repository [} 49] as
usual.
◦ The TwinCAT Loader is required for the versioned C++ projects [} 103].
Via System -> TcCOM Modules -> Class Factories tab you can see whether the TwinCAT Loader or the
operating system is used:
The storage of the password is carried out with the following parameters:
tcsigntool grant /f "C:\TwinCAT\3.1\CustomConfig\Certificates\MyCertificate.tccert" /p MyPassword
The layout of Visual Studio is flexible and adaptable, so that only a brief overview of a common configuration
can be provided here. The user is free to configure windows and arrangements as required.
1. In the TwinCAT solution, a TwinCAT C++ project can be created by right-clicking on the C++ icon.
This project contains the sources (“Untitled Project”) of perhaps several modules [} 35], and module
instances ("Untitled1_Obj1 (CModule1)") can be created. The module instances have inputs/outputs,
which can be linked in the usual way ("Link"). There are further options [} 46] for module interaction.
2. The Visual Studio editor for Visual C++ is used for programming. Note in particular the drop-down
boxes for fast navigation within a file. In the lower section the result of the compile process is output.
The user can switch to TwinCAT messages (cf. Module messages for the Engineering (logging / trac-
ing) [} 230]).
The usual features such as breakpoints (cf. Debugging [} 95]) can be used in the editors.
3. The freely configurable toolbar usually contains the toolbar for TwinCAT XAE Base. Activate Config-
uration, RUN, CONFIG, Choose Target System (in this case <Local>) and several other buttons pro-
vide fast access to frequently used functions. The TwinCAT Debugger is the button for establishing a
connection to the target system with regard to C++ modules (the PLC uses an independent debug-
ger). Like in other C++ programs, and in contrast to PLC, in TwinCAT C++ a distinction has to be
made between "Release" and "Debug". In a build process for "Release", the code is optimized to such
an extent that a debugger may no longer reliably reach the breakpoints, and incorrect data may be
displayed.
Procedure
This section describes the processes for programming, compiling and starting a TwinCAT C++ project.
It provides a general overview of the engineering process for TwinCAT C++ projects with reference to the
corresponding detailed documentation. The quick start [} 60] guide describes the individual common steps.
9 Quick start
This quick start shows how you can familiarize yourself with the TwinCAT C++ module engineering in a short
time.
Each step in the creation of a module that runs in a real-time context is described in detail.
Before the quick start, please pay attention to the Preparation - just once! [} 22]
ð The compiler output window must look like this if the code has been correctly written (i.e. no syntax
errors):
ð Following successful compilation/creation, the new TwinCAT C++ module is provided for the specific
target platform in the "_Deployment\" subfolder of the project directory.
Microsoft Visual Studio can be started via the TwinCAT SysTray icon.
The Visual Studio versions recognized during the installation and supported by TwinCAT are thereby offered.
Alternatively, Visual Studio can also be started via the Start menu.
2. Alternatively, create a project by clicking on: File -> New -> Project.
ð All existing project templates are displayed.
3. Select TwinCAT XAE Project and optionally enter a suitable project name.
4. Click on OK. From now on you cannot select or change the name of the directory. Retain the default
settings (selected option Create directory for solution).
ð The Visual Studio Solution Explorer then displays the TwinCAT 3 project.
ð The TwinCAT C++ Project Wizard [} 103] is shown and all existing project templates are listed.
2. A) Select TwinCAT Driver Project, optionally enter a related project name and click on OK.
B) Alternatively, use the TwinCAT Static Library Project, which provides an environment for the
programming of static TC-C++ libraries (see Sample 25 [} 318]).
3. In this case, select TwinCAT Module Class with Cyclic I/O and click on OK. A name is not necessary
and also cannot be entered here.
4. Enter a unique name in the TwinCAT Class Wizard dialog box or continue with the Object1 suggestion.
ð A TwinCAT 3 C++ project with a driver will then be created on the basis of the selected template:
The implementation begins after creating a TwinCAT C++ project and opening <MyClass>.cpp (Module1.cpp
in this sample).
1. The <MyClass>::CycleUpdate() method is cyclically called – this is the point where the cyclic logic is to
be positioned. The entire cyclic code is inserted at this point. The dropdown menus at the top of the
editor can be used for navigation.
2. In this case a counter is incremented by the value of the "Value" variable in the input image (m_Inputs).
Replace a line in order to increment the counter without dependence on the value of the input image.
Replace this line
m_counter+=m_Inputs.Value;
with this one
m_counter++;
3. Save the modifications.
After creating a TwinCAT C++ module, open the C++ Configuration node and follow these steps to create
an instance.
1. Right-click on the C++ module (in this case "Untitled1") and select Add New Item....
ð The new instance "Untitled1_Obj2 (CModule1)" becomes part of the TwinCAT 3 solution: the new node
is located precisely under the TwinCAT 3 C++ source "Untitled1 Project".
The module already provides a simple I/O interface with 3 variables in each case:
• Input area: Value, Status, Data
• Output area: Value, Control, Data
This configuration step only has to be carried out once. No new task needs to be configured for subsequent
creations/new compilations of the C++ module in the same project.
2. Enter a unique name for the task (or retain the default name).
In this sample the I/O image interface is provided by a C++ module instance, so that no image is
necessary at the task for triggering the execution of the C++ module instance.
ð The new task with the name "Task 1" has been created.
3. The task can now be configured; double-click on the task to do this.
The most important parameters are Auto start and Priority:
Auto start must be activated in order to automatically start a task that is to be cyclically executed. The
Cycle ticks define the timing of the clock in relation to the basic clock (see real-time settings).
Configuring a TwinCAT 3 C++ module instance that is called from the task
1. Select the C++ module instance in the solution tree.
2. Select the Context tab in the right-hand working area.
3. Select the task for the previously created context in the drop-down task menu.
Select the default Task 1 in the sample.
ð On completion of this step the Interface Pointer is configured as a CyclicCaller. The configuration is
now complete!
2. In the next step, confirm the activation of the new configuration. The previous old configuration will be
overwritten.
3. If you have no license on the target system, you will be offered the option to create a 7-day trial license.
This can be repeated any number of times.
4. TwinCAT 3 automatically asks whether the mode should be switched to Run mode.
ð After switching to Run mode, the TwinCAT System Service symbol at the bottom in Visual Studio lights
up green.
After switching on the C++ debugging in the TwinCAT project and activating the complete project, the
TwinCAT Engineering (XAE) can now be used to connect to the target system for debugging.
1. A) Click on the Attach... button familiar from Visual Studio in order to connect to the TwinCAT debugger
on the target system:
B) Alternatively, select Debug -> Attach to process... in the Visual Studio environment:
2. Do not select the Default setting of Visual Studio for the transport; use TwinCAT XAE instead. Target
system (or All Routes) as qualifier and connect by Attach.
The normal Visual Studio debugging mechanism is available – setting of breakpoints, step execution, etc.
Their usage depends on the process to be monitored:
If TwinCAT runs on a real machine with axis movements, the user will probably not wish to set any
breakpoints just for monitoring variables. On reaching a breakpoint the execution of a task would be stopped
and, depending on the configuration, the axis would immediately come to a halt or, perhaps even worse,
would continue to move in an uncontrolled fashion – a very unfavorable situation.
TwinCAT 3 therefore offers the option to monitor process variables without setting breakpoints:
1. Select Debug -> Windows -> TwinCAT Live Watch
ð The TwinCAT Live Watch windows show a list of all the variables in the module. Variables placed in
the watch list by drag & drop are monitored without setting breakpoints.
2. In order to change the value of a monitoring variable, simply enter a new value.
Setting breakpoints
WARNING
Damage to plants and personal injuries due to unexpected behavior of the machine / plant
Breakpoints change the behavior of the machine or plant. Depending on the machine being controlled, the
machine or workpieces may be damaged or the health and life of people may be endangered.
Make sure that the changed behavior of the controlled system does not cause any damage and be sure to
note the plant documentation.
Before the quick start, please pay attention to the preparation - just once! [} 22]
Microsoft Visual Studio can be started via the TwinCAT SysTray icon.
The Visual Studio versions recognized during the installation and supported by TwinCAT are thereby offered.
Alternatively, Visual Studio can also be started via the Start menu.
2. Alternatively, create a project by clicking on: File -> New -> Project.
ð All existing project templates are displayed.
3. Select TwinCAT XAE Project and optionally enter a suitable project name.
4. Click on OK. From now on you cannot select or change the name of the directory. Retain the default
settings (selected option Create directory for solution).
ð The Visual Studio Solution Explorer then displays the TwinCAT 3 project.
1. Right-click C++ and choose Add New Item... . . .and I'm going to get out of here.
If the green C++ symbol is not listed, this means that either a target device is selected that doesn't
support TwinCAT C++ or the TwinCAT solution is currently open in a version of Visual Studio that is not
C++-capable (cf. Requirements [} 20]).
ð The "TwinCAT C++ Project Wizard [} 103]" is shown and all existing project templates are listed.
2. Select TwinCAT Versioned C++ Project, optionally enter a project name and click OK.
4. Enter a unique name in the TwinCAT Class Wizard dialog box or continue with the Object1 suggestion.
ð A TwinCAT 3 C++ project with a driver will then be created on the basis of the selected template:
The implementation begins after creating a TwinCAT C++ project and opening <MyClass>.cpp (Module1.cpp
in this sample).
1. The <MyClass>::CycleUpdate() method is cyclically called – this is the point where the cyclic logic is to
be positioned. At this point, add the entire cyclic code. Use the drop-down menu at the top of the editor
for navigation.
2. In this case a counter is incremented by the value of the Value variable in the input image (m_Inputs).
Replace a line in order to increment the counter without dependence on the value of the input image.
Replace this line
m_counter+=m_Inputs.Value;
with this one
m_counter++;
3. Save the modifications.
4. The version 0.0.0.1 has thus been implemented, as you can see in the TMC Editor.
ð The module is published in version 0.0.0.1 with the incremental counter on the engineering device.
ð There are two versions of a module, which can be exchanged during runtime.
After creating a TwinCAT C++ module, open the C++ Configuration node and follow these steps to create
an instance.
1. Right-click on the C++ module (in this case "Untitled1") and select Add New Item....
ð The new instance "Untitled1_Obj2 (CModule1)" becomes part of the TwinCAT 3 solution: the new node
is located precisely under the TwinCAT 3 C++ source "Untitled1 Project".
The module already provides a simple I/O interface with 3 variables in each case:
• Input area: Value, Status, Data
• Output area: Value, Control, Data
This configuration step only has to be carried out once. No new task needs to be configured for subsequent
creations/new compilations of the C++ module in the same project.
2. Enter a unique name for the task (or retain the default name).
In this sample the I/O image interface is provided by a C++ module instance, so that no image is
necessary at the task for triggering the execution of the C++ module instance.
ð The new task with the name "Task 1" has been created.
3. The task can now be configured; double-click on the task to do this.
The most important parameters are Auto start and Priority:
Auto start must be activated in order to automatically start a task that is to be cyclically executed. The
Cycle ticks define the timing of the clock in relation to the basic clock (see real-time settings).
Configuring a TwinCAT 3 C++ module instance that is called from the task
1. Select the C++ module instance in the solution tree.
2. Select the Context tab in the right-hand working area.
3. Select the task for the previously created context in the drop-down task menu.
Select the default Task 1 in the sample.
ð On completion of this step the Interface Pointer is configured as a CyclicCaller. The configuration is
now complete!
1. Click on the symbol Activate Configuration – all required files for the TwinCAT project are transferred
to the target system:
2. In the next step, confirm the activation of the new configuration. The previous old configuration will be
overwritten.
3. If you have no license on the target system, you will be offered the option to create a 7-day trial license.
This can be repeated any number of times.
4. TwinCAT 3 automatically asks whether the mode should be switched to Run mode.
5. For test operation, e.g. during software development, the creation of a TwinCAT user certificate, as
described here, is sufficient. Make sure that you select the purpose "Sign TwinCAT C++ executable
(*.tmx)". For this the Crypto version 2 is required, a message appears.
ð After switching to Run mode, the TwinCAT System Service symbol at the bottom in Visual Studio lights
up green.
2.
3. In the column Online Version the currently running version is preselected and marked with the
extension (Current).
4. Set a different version.
5. Activate this change by right-clicking and Apply changed online object versions on the target.
11 Debugging
TwinCAT C++ offers various mechanisms for debugging TwinCAT C++ modules running under real-time
conditions.
Most of them correspond to the mechanisms that are familiar from the normal C++ development
environment. The world of automation requires additional, slightly different debugging mechanisms, which
are documented here.
In addition, we provide an overview of Visual Studio tools that can be used in TwinCAT 3. These were
extended, so that data from the target system are displayed.
2. For all debugging in TwinCAT C++, connect the TwinCAT Engineering with the runtime system (XAR) via
the TwinCAT Debugger button.
3.
In most cases when debugging a C++ program, breakpoints are set and the code is then executed step by
step while observing the variables, pointers, etc.
In the context of the Visual Studio debugging environment, TwinCAT offers options to run real-time-executed
code step by step. To set a breakpoint, you can navigate through the code and click on the gray column on
the left adjacent to the code or use the hotkey (normally F9).
WARNING
Damage to plants and personal injuries due to unexpected behavior of the machine / plant
Breakpoints change the behavior of the machine or plant. Depending on the machine being controlled, the
machine or workpieces may be damaged or the health and life of people may be endangered.
Make sure that the changed behavior of the controlled system does not cause any damage and be sure to
note the plant documentation.
On reaching the breakpoint (indicated by an arrow), the execution of the code is stopped.
The code is executed step by step by pressing Step Over (Debug menu, toolbar or hotkey F10). The familiar
Visual Studio functions Step in (F11) and Step out (Shift + F11) are also available.
Conditional breakpoints
A more advanced technology allows the setting of conditional breakpoints – the execution of code is only
stopped at a breakpoint if a condition is fulfilled.
TwinCAT offers the implementation of a conditional breakpoint as part of the Visual Studio Integration. To set
a condition, first set a normal breakpoint and then right-click on the red dot in the breakpoint column.
WARNING
Damage to plants and personal injuries due to unexpected behavior of the machine / plant
Breakpoints change the behavior of the machine or plant. Depending on the machine being controlled, the
machine or workpieces may be damaged or the health and life of people may be endangered.
Make sure that the changed behavior of the controlled system does not cause any damage and be sure to
note the plant documentation.
Details of the conditions and how they are to be formulated can be found here [} 98].
Live Watch
When engineering and developing machines, it is not always advisable to stop the system at a breakpoint
because this will affect the behavior.
The TwinCAT PLC projects offer an online view and handling of the variables in the RUN state, without
having to interrupt the real-time.
TwinCAT C++ projects offer a similar behavior for C++ code via the Live Watch window.
The Live Watch window can be opened via Debug->Windows->TwinCAT Live Watch.
To open the window, first establish a connection with the real-time system (press the TwinCAT Debugger
button), whereupon Visual Studio switches to the debug view, otherwise no data can be provided.
In the upper area all member variables can be explored. By double-clicking on it they are added to the lower
area, where the current value is then displayed.
You can edit these values by clicking on the value in the Value field. The new value is highlighted in red. To
write the value, press the symbol in the upper left corner (1).
Using the import and export symbols under (2), the selected member variables can be saved and later
restored.
Unlike the Visual Studio C++ conditional breakpoints, the TwinCAT conditions are compiled and
subsequently transferred to the target system so that they can be used during short cycle times.
WARNING
Damage to plants and personal injuries due to unexpected behavior of the machine / plant
Breakpoints change the behavior of the machine or plant. Depending on the machine being controlled, the
machine or workpieces may be damaged or the health and life of people may be endangered.
Make sure that the changed behavior of the controlled system does not cause any damage and be sure to
note the plant documentation.
The option buttons offer two options that are described separately.
Option: Is true
Conditions are defined with the help of logical terms, comparable to conjunctive normal forms.
They are formed from a combination of maxterms connected by "&&".
(Maxterm1 && Maxterm2 && ... && MaxtermN)
Observe the Live Watch window for the determination of the available variables. All listed variables can be
used for the formulation of conditions. This includes TMC-defined symbols as well as local member
variables.
Samples:
m_counter == 123
Further comments:
• Monitoring module instances:
The OID of the object is stored in m_objId, so the monitoring of the OID can look like this m_objId
== 0x01010010
• Monitoring of tasks:
A special variable #taskId is provided to access the OID of the calling task. E.g. #taskID ==
0x02010010
The option “Has changed“ is simple to understand: By providing variable names, the value will be monitored
and execution will be held, if the value has changed from the cycle before.
Samples:
m_counter
Call stack
The Call Stack is displayed by the Call Stack tool window when a breakpoint has been reached.
The corresponding variables and values are displayed in the Autos / Locals window when a breakpoint is
reached. Changes are shown in RED.
From here, the values can be applied to the Watch windows by right-clicking:
Memory view
12 Wizards
For ease of entrance in engineering the TwinCAT C++ system provides Wizards.
• The TwinCAT Project Wizard [} 103] creates a TwinCAT C++ project. For Driver projects, the TwinCAT
Class Wizard will be started afterwards.
• The TwinCAT Module Class Wizard [} 104] is automatically started during creation of a C++ module.
This wizard provides different “ready to use” projects as entry points for own development.
• The TwinCAT Module Class Editor [} 107] (TMC) is a graphical editor for defining the data structures,
parameters, data areas, interfaces and pointers. It generates a TMC file, which will be used by the
TMC Code generator.
• From the defined Classes instances will be generated and could be configured via the TwinCAT
Module Instance Configurator [} 150]
2. Select one of the project templates and specify a name and location.
ð The TwinCAT C++ project is created
ð In the case of a driver, the TwinCAT C++ class wizard [} 104] is started.
This is a template generates a basic core module. It has no cyclic caller and no data area, instead it's good
as a start point for implementing services called on demand from a caller.
For example when creating a C++ method that will be called from a PLC module or another C++ module.
This template offers the C++ module as well as the functionality of an ADS server and ADS clients.
• ADS server:
Can run as a single instance of this template of the C++ module and can be preconfigured with a
specific ADS port number (e.g. 25023).
Enables several instances of this template, whereby each C++ module is assigned its own unique ADS
port number by TwinCAT 3 (e.g. 25023, 25024, 25025, ...).
The ADS messages can be analyzed and processed thanks to the implementation of the C++ module.
ADS handling for accessing input/output data areas does not have to be implemented using its own
ADS Message Handling.
• ADS Client:
This template provides sample codes to initiate an ADS call by sending an ADS message to an ADS
partner.
Since the modules behave like ADS clients or ADS servers that communicate with each other via ADS
messages, the two modules (Caller=Client and Called=Server) can run in the same or different real-time
contexts on the same or different CPU cores.
Because ADS can work across networks, the two modules can also run on different machines in the
network.
Enables the cyclic call of a C++ program which is cut off from the outside world.
Not often used, a module class with cyclic caller and cyclic I/O is preferred.
Creates a new TwinCAT module class, which implements the cyclically calling interface and has an input
and output data area.
The input and output data areas can be linked with other input/output images or with physical I/O terminals.
Important:
The C++ module has its own logical input/output data storage area. The data areas of the module can be
configured with the System Manager.
If the module is mapped with a cyclic interface, copies of the input and output data areas exist in both
modules (the caller and the called). In this way, the module can run under a different real-time context and
even on another CPU core in relation to another module.
TwinCAT will continuously copy the data between the modules.
Just like the TwinCAT Module Class with Cyclic IO, this template also generates a new TwinCAT module
class that implements a calling interface with an input and output data area for linking with other logic input/
output images or with physical I/O terminals.
In addition, this template provides data pointers that can be used to access data areas from other modules
via pointers.
Important:
Unlike in the case of the cyclic I/O data area, where the data is copied cyclically between modules, in the
case of the use of C++ data pointers there is only a single data area and this belongs to the destination
module. When writing from another C++ module to the destination module via the data pointer mechanism,
this will immediately affect the data area of the destination module. (Not necessarily towards the end of a
cycle).
If the module is executed at runtime, the call occurs immediately, blocking the original process (it is a
pointer...). Therefore, both modules (the caller and the called one) must be in the same real-time context and
on the same CPU core.
The data pointer is configured in the TwinCAT Module Instance Configurator [} 150].
This template creates a module, which can be instantiated in the real-time context.
As described here [} 44], the other modules have transitions for startup and shutdown in a non-real-time
context. In some cases modules have to be started when a real-time is already running, so that all transitions
are executed in the real-time context. This is a corresponding template.
The modules with this (modified) state machine can also be used for instantiation directly on startup of TC. In
this case the transitions are executed like for a normal module.
This option can only be used if the module is added to a Versioned C++ Project.
This template creates a module that is capable of online change. Due to the revision control of the project,
these modules become exchangeable at runtime - it is therefore possible to exchange modules from different
versions at runtime.
To put it briefly: everything that is visible from outside must be defined with this editor.
1. The TMC Editor can be used to modify the module description file (TMC file). This contains all informa-
tion that is accessible in the TwinCAT system itself. These are for example symbols, implemented in-
terfaces and parameters.
2. The TwinCAT Code Generator, which can also be called from the TMC Editor, is used to generate all
the required C++ code, i.e. header and cpp files.
Open the editor by double-clicking on the TMC file of a module. The graphical editor opens:
User Help
The TMC editor offers user support for the definition of data types and C++ modules.
For example, in the event of problems (alignment, invalid standard definitions, ...) within the TMC, the user is
guided to the relevant location via red flags within the TMC tree:
The user can nevertheless edit the TMCs directly, since they are XML files and can therefore be created and
edited by the user.
Tools
The upper section of the TMC editor contains symbols for the required operations.
• Reloading of the TMC file and the types from the type system.
• Updating of the higher-level data types.
• Switching the User Help [} 107] on/off.
• Start the TwinCAT TMC Code Generator:
The editor will store the entered information in the TMC file. The TwinCAT TMC Code Generator converts
this TMC description to source code, which is also available in the context menu of the TwinCAT C++
project.
12.3.1 Overview
User interface
• TMC [} 110]: Here you can edit the C++ module vendor's basic information and add an image.
• Data types [} 111]: Data types are added, removed, or re-ordered here.
• Modules [} 128]: Shows the modules of the driver.
• Implemented Interfaces [} 130]: Shows the implemented interfaces of the module.
• Parameters [} 131]: Parameters are added, removed, or re-ordered here.
◦ TraceLevelMax [} 137]: Parameter that controls the quantity of logged messages; predefined for
(almost) every module.
• Data Areas [} 138]: Data areas are added, removed, or re-ordered here.
• Data Pointers [} 145]: Data pointers are added, removed, or re-ordered here.
• Interface Pointers [} 147]: Interface pointers are added, removed, or re-ordered here.
• Deployment [} 148]: Determines the files that are provided.
Versioned Classfactory
Name: Displays all class factories referenced from the TMC file. The class factory that implements the C++
project must be set. Typically this is the name of the project.
Used only for versioned C++ projects; otherwise "not set" appears here.
Version: The current version, consisting of four digits, each separated by a ".". At least one digit must not be
0.
Optional features
Generated by: This field indicates who created the file and who will maintain it. Please note that changes
are no longer possible in the TMC Editor when filling out this field (deactivates all editing procedures).
These data types can be type definitions, structures, areas, enumerations or interfaces, e.g. methods and
their signatures.
The TwinCAT Engineering system (XAE) publishes these data types in relation to all other nested projects of
the TwinCAT project, so that they can also be used in PLC projects, for example (as described here [} 280]).
NOTE
Name conflict
A name collision can occur if the driver is used in combination with a PLC module.
• Do not use any of the keywords that are reserved for the PLC as names.
This chapter describes how to use the capabilities of the TMC editor for defining data types.
12.3.3.1 Overview
User interface
Symbol Function
Add a new data type.
Copy
Paste
Size X64: different size of the data type for the x64 platform.
2. Extend the list of data types and interfaces by a new data type by clicking on the + button Add a new
data area.
ð A new data type is then listed as a new entry:
3. Select the generated "Data Type1" in order to obtain details of the new data type.
6. Insert new sub-elements in the structure by clicking on the Add a new sub item button.
7. You can edit the properties by double-clicking on the sub-element. Give the sub-element a new name
and select a suitable data type.
8. Give the other sub-elements a new name and select a suitable data type.
9. Save the changes you have made in the TMC file.
Step 2: Start the TwinCAT TMC Code Generator to generate code for the module description.
10. Right-click on your project file and select TwinCAT TMC Code Generator to generate the source code
for your data type:
ð You can see the data type declaration in the module header file "Untitled1Services.h"
ð If you add a further data type or a further sub-element, run the TwinCAT TMC Code Generator again.
3. To open the details you can either select the appropriate node in the tree or double-click on the row in
the table.
7. Double-click on the method or select a node in the tree to open the details.
8. Give the default "Method1" a more meaningful name.
9. Subsequently, you can add parameters by clicking on Add a new parameter or edit parameters of the
"SetState" method.
ð In this case "NewState" is the new name – the rest of the settings are not changed.
11. By repeating step 2 "Add methods to interface", all methods are listed – you can re-order the methods
with the help of the move up / move down button.
15. All available interfaces are listed - select the new template "IStateMachine" and end with OK.
Step 4: Start the TwinCAT TMC Code Generator to generate code for the module description.
16. In order to generate the C/C++ code on the basis of this module description, right-click in the C/C++
project and then select the TwinCAT TMC Code Generator.
General properties
NOTE
Name conflict
A name collision can occur if the driver is used in combination with a PLC module.
• Do not use any of the keywords that are reserved for the PLC as names.
Please note that this is not assigned to a C namespace. It is used as the prefix to your data type.
You may wish to manually append the namespace name to the enumeration element as a prefix:
#if !defined(_TC_TYPE_C26FED5F_AC13_4FD3_AC6F_B658CB5604E0_INCLUDED_)
#define _TC_TYPE_C26FED5F_AC13_4FD3_AC6F_B658CB5604E0_INCLUDED_
enum B_BSampleEnum : SHORT {
B_one,
B_two,
B_three
};
#endif // !defined(_TC_TYPE_C26FED5F_AC13_4FD3_AC6F_B658CB5604E0_INCLUDED_)
Select: Select data type – it can be a basic TwinCAT data type or a user-defined data type.
Data types equivalent to the PLC data types are defined (like TIME, LTIME, etc.). See Data Types of the
PLC for further information.
Description: Define the type as pointer, reference or value by means of the appropriate selection.
• Normal type
• Pointer
• Pointer to pointer
• Pointer to pointer to pointer
• a reference
Type information
• Namespace: Defined for selected data type.
• GUID: Unique ID of the selected data type.
Size [Bits]: Size in bits (white fields) and in "Byte.Bit" notation (grey fields). A different size can be defined
for the x64 platform.
C/C++ Name: name used in the generated C++ code. The TMC code generator will not generate the
declaration, so that user-defined code can be provided for this data type. Beyond that a different name can
be defined for x64.
Hide sub items: If the data type has sub-elements, the System Manager will not allow the sub-elements to
be accessed. This should be used, for example, in the case of larger arrays.
Persistent (even if unused): Persistent type in the global type system (cf. System->Type System->Data
Types).
Optional Defaults
Optional Properties
A table of name, value and description for annotating the data type.
This information is provided within the TMC and also TMI files.
TwinCAT functions as well as customer programs can use these properties.
Datatype Hides
Listed GUIDs refer to data types which are hidden by this data type. Normally, GUIDs of previous versions of
this data type are inserted here automatically on each change.
12.3.3.5 Specification
This section describes the Specification of data types.
12.3.3.5.1 Array
Array: create a user-defined array.
A new dialog is shown for adding (+) or removing (-) array elements.
In the case of parameters [} 131] and data pointers [} 145], TwinCAT 3 supports arrays with a dynamic size.
Max is unbounded: indicates that there is no upper limit for the array size.
12.3.3.5.2 Enum
Enumeration: create a user-defined enumeration.
A new dialog is shown for adding (+) or removing (-) an element. Edit the order with the help of the arrows.
NOTE
Unique names are required for enumeration elements
Please note that the enumeration elements must have unique names, as otherwise the C++ code gener-
ated is invalid.
12.3.3.5.3 Struct
Struct: Creating a user-defined structure.
Select the Sub Items node or click on the Edit Struct button to switch to this table:
A new dialog is shown for adding (+) or removing (-) an element. Edit the order with the help of the arrows.
Size X64: Other size for the x64 platform will additionally be provided.
The details of the configuration page of the sub-element are shown by selecting the data type or double-
clicking on the table entry. Similar to Data type properties [} 122].
12.3.3.5.4 Interfaces
Interfaces: Creating a user-defined interface.
Select the Methods node or click on the Edit Methods button to switch to this table:
Method parameters
Select the Methods node or double-click on the entry to view the details of the method.
RPC enable: enablement of remote procedure calls from outside this method.
Include Return Value: enablement of the forwarding of the return value of the method.
12.3.4 Modules
Modules: Shows the modules of the driver.
Modules properties:
Click on the node in the tree or the row in the table to open the module properties.
General properties
Auto generate on save: Enables TwinCAT to generate the ClassID via the module parameters during
saving. If the ClassID changes during import of the binary modules, the corresponding ClassIDs have to be
adjusted. Thus, TwinCAT can detect the interface change.
Init sequence: Start the state machine. The selection options with 'late' in the name are internal. (See
Object [} 151] of the instance configurator for further information.)
Instantiable in RT Context: Indicates whether this module can be instantiated under real-time context; see
TwinCAT Module Class Wizard [} 104]
You can add (+) or remove (-) contexts for the module. Edit the order with the help of the arrows.
The context ID must be an integer other than 0.
Optional Properties
You can add (+) or remove (-) contexts for the module. Edit the order with the help of the arrows.
12.3.4.2 Parameters
A TcCOM module instance is defined through various parameters.
TwinCAT supports three types of Parameter IDs (PTCID) in the section Configuring the parameter ID
[} 136].
• "User defined" (default value for new parameters): A unique parameter ID is generated, which can be
used in the user code or in the instance configuration for specifying the parameter.
• "Predefined...": Special PTCIDs provided by the TwinCAT 3 system (e.g. TcTraceLevel).
• "Context-based…": Automatically assign values of the configured context [} 152] to this parameter.
The selected property is applied to the PTCPID. It overwrites the defined standard parameters and the
instance configuration parameter (parameter (Init)).
The parameters and their configuration are described in more detail below.
Symbol Function
Add a new parameter
Size: Size of the parameter. Other sizes are possible for x64.
3. Select Parameter in the left-hand tree or double-click on the red-marked "Parameter3" or select the node
in the tree to obtain details of the new parameter.
Step 2: Start the TwinCAT TMC Code Generator to generate code for the module description.
7. Right-click on your project file and select TwinCAT TMC Code Generator to receive the parameters in
your source code:
ð You can see the parameter declaration in the header file "Module1.h" of the module.
ð The implementation of the new parameter can be found in the get and set methods of the module
class "module1.cpp".
To add a further parameter, use the TwinCAT TMC Code Generator again.
The parameters are specified during the transition Init->Preop and perhaps Preop->Safeop.
General properties
Type information
• Namespace: user-defined namespace of the data type.
• GUID: unique ID of the data type.
Size [Bits]: Calculated size in bits (white fields) and in "Byte.Bit" notation (grey fields). A special size
configuration is provided for x64.
Hide parameter: Switches between showing/hiding parameters in the System Manager view.
Hide sub items: If the data type has sub-elements, the System Manager will not allow the sub-elements to
be accessed. This should be used, for example, in the case of larger arrays.
Optional Properties
12.3.4.2.3 TraceLevelMax
TraceLevelMax: Parameter which defines the trace level.
This is a predefined parameter provided by most TwinCAT module templates (except for the empty TwinCAT
module template).
Symbol Function
Add a new data area
NOTE
Recursion when setting an alignment
When setting the alignment of a data area, this will be taken as the basis for all of its elements (symbols
and also their sub-elements). User-defined alignment will be overwritten.
Size: Size of the parameter; other sizes are possible for x64.
• For example, edit the name or data type [} 144] of variables existing in the TMC file.
• Delete existing variables [} 145] from the TMC file.
3. In order to obtain the properties of the data area, double-click on the table or on the node.
8. Enter a new name, e.g. "bEnableJob" and change the type to BOOL.
General properties
Type: Defines the purpose and location of the data area. The following are available:
Size [Bytes]: Size in bytes. A special size configuration is provided for x64.
Comment: Optional comment that is visible, for example, in the instance configurator.
Context ID: Context ID of all symbols of this data area; used for the determination of the mapping.
Data type name: If specified, a data type with the specified name is created in the type system.
Optional Defaults
Optional Properties
A table of name, value and description for annotating the data area.
This information is provided within the TMC and also TMI files.
TwinCAT functions as well as customer programs can use these properties.
General properties
Specification: Data type of the symbol, see Data type properties [} 122].
Select: Select data type – it can be a basic TwinCAT data type or a user-defined data type.
Type information
• Namespace: Namespace for selected data type.
• GUID: unique ID of the data type.
Offset [Bits]: Offset of the symbol within the data area; a different offset can be defined for the x64 platform.
Size [Bits]: Size in bits, if specified. A different size can be defined for the x64 platform.
Comment: Optional comment that is visible, for example, in the instance configurator.
Hide sub items: If a variable has sub-elements, then the System Manager will not allow the sub-elements to
be accessed. This should be used, for example, in the case of larger arrays.
General Properties
Type Information
Unit: Optional
Comment: Optional
Symbol Function
Add a new data pointer
General properties
Type information
• Name: Name of the selected data type.
• GUID: unique ID of the data type.
Symbol Function
Add interface pointers
General properties
Type information
• Namespace: Namespace of the interface.
• GUID: Unique ID of the interface.
Comment: Optional
12.3.4.6 Deployment
Deployment: Specify storage locations for the provided modules on the target system.
Symbol Function
Add a new file entry
This dialog enables configuration of the source and target file, which are transferred to the target system for
the respective platforms.
Rename Destination: Destination file will be renamed before the new file is transferred. Since this is
required for Windows 10, it is done implicitly.
The individual entries can be expanded and collapsed by the + or – respectively at the beginning.
Evaluate: Puts the calculated value into the text field for verification.
Remove symbol file entries: Removes the entries for the provision of symbol files (PDB).
Add default file entries: Adds the entries for the selected platform.
Remove file entries: Removes the entries for the selected platform.
Source and target paths for the allocation may contain virtual environment variables, which are resolved by
the TwinCAT XAE / XAR system.
The following table shows the list of these supported virtual environment variables.
Virtual environment variable Registry entry (REG_SZ) under key Default value
\HKLM\Software\Beckhoff\TwinCAT3
%TC_INSTALLPATH% InstallDir C:\TwinCAT\3.x \
%TC_CONFIGPATH% ConfigDir C:\TwinCAT\3.x
\Config\
%TC_TARGETPATH% TargetDir C:\TwinCAT\3.x
\Target\
%TC_SYSTEMPATH% SystemDir C:\TwinCAT\3.x
\System\
%TC_BOOTPRJPATH% BootDir C:\TwinCAT\3.x \Boot\
%TC_RESOURCEPATH% ResourceDir C:\TwinCAT\3.x
\Target\Resource\
%TC_REPOSITORYPATH% RepositoryDir C:\TwinCAT\3.x
\Repository\
%TC_DRIVERPATH% DriverDir C:\TwinCAT\3.x
\Driver\
%TC_DRIVERAUTOINSTALLPAT DriverAutoInstallDir C:\TwinCAT\3.x
H% \Driver\AutoInstall\
%TC_SYSSRVEXEPATH% C:\TwinCAT\3.x \SDK
\Bin\TwinCAT UM
(x86)\
%CLASSFACTORYNAME% <Name of the Class
Factory>
The configuration applies to the context (including the task calling the module), parameters and pointers.
Instances of C++ classes are created by right-clicking on the C++ project folder; see quick start [} 60]. This
chapter describes the configuration of these instances in detail.
Double-click on the generated instance to open the configuration dialog with several windows.
12.4.1 Object
• Object Id: The object ID used for identifying this instance in the TwinCAT system.
• Object Name: Name of the object used for displaying the instance in the Solution Explorer tree.
• Type Name: Type information (class name) of the instance.
• GUID: Module classes GUID.
• Class Id: Class ID of the implementation class (GUID and ClassId are usually identical).
• Class Factory: Refers to the driver, which provides the Class Factory that was used for the
development of the module instance.
• Parent Id: Contains the ObjectID of the parent, if available.
• Init Sequence: Specifies the initialization states for determining the startup behavior of the interacting
modules. See here [} 44] for detailed description of the state machine.
TcCOM instances can refer to each other - e.g. for the purpose of interaction via data or interface pointers.
To determine the startup behavior, the Init Sequence specifies states to be "held" by each TcCOM instance
for all other modules.
The name of an Init Sequence consists of the short name of the TcCOM state machine. If the short name of
a state (I, P, S, O) is included in the name of the Init Sequence, the modules will wait in this state, until all
other modules have reached at least this state. In the next transition the module can refer to all other module
instances, in order to be in this state as a minimum.
If, for example, a module has the Init Sequence "PS", the IP transitions of all other modules are executed, so
that all modules are in "Preop" state.
This is followed by the PS transition of the module, and the module can rely on the fact that the other
modules are in "Preop" state.
• Copy TMI to target: Generating the TMI (TwinCAT Module Instance) file and transferring it to the
target.
12.4.2 Context
• Context: Select the context to be configured (see TMC Editor for Adding different contexts).
Note A data area is assigned to a context
• Data Areas / Interfaces / Data Pointer and Interface Pointer: Each instance can be configured to
have or not have elements defined in TMC.
• Result Table: List of the IDs that need to be configured. At least the context ("Task" column) of the
task must be configured accordingly.
List of all parameters (as defined in TMC) could be initialized by values for each instance.
Special ParameterIDs (PTCID) are used to set values automatically.These are configured via the
TMCEditor's parameter dialogue as described here [} 131].
The CS (CreateSymbol) checkbox creates the ADS Symbols for each parameter, thus it is accessible from
outside
List of all data areas and their variables (as defined in TMC).
The CS (CreateSymbol) checkbox creates the ADS Symbols for each parameter, thus the variable is
accessible from outside
12.4.5 Interfaces
Special ParameterIDs (PTCID) are used to set values automatically. These are configured via the
TMCEditor's parameter dialogue as described here [} 131].
The OTCID column defines the pointer to the instance, which should be used.
Special ParameterIDs (PTCID) are used to set values automatically. These are configured via the
TMCEditor's parameter dialogue as described here [} 131].
The OTCID column defines the pointer to the instance, which should be used.
This section of the documentation describes how customers can realize their own project templates.
12.5.1 Overview
When a TwinCAT C/C++ project is created, the TwinCAT C++ Project Wizard is started first. The latter
generates a framework for a TwinCAT driver. The purpose of this framework is to register a TwinCAT driver
in the system. The actual function of the driver is implemented in TwinCAT modules.
The TwinCAT Class Wizard is automatically started on creating a new driver project in order to add the first
TwinCAT driver module. The different modules are generated by the same TwinCAT Class Wizard, but the
specific design of the module is realized using templates.
The TwinCAT C++ Project Wizard calls the TwinCAT Module Class Wizard if a Driver Project is to be
created.
The respective project types are defined in the Driver (for TwinCAT C++ Project Wizard) and Class directory
(for the TwinCAT Module Class Wizard), each project type encompassing 3 files:
The .vsdir file provides information that is used when the respective assistant wizard is started. This is
essentially a name, a brief description and a file name of the type .vsz containing details for this project type.
The general description in the MSDN can be found here: https://msdn.microsoft.com/de-de/library/
Aa291929%28v=VS.71%29.aspx.
The .vsz file referenced in the .vsdir file provides information that is needed by the wizard.
The most important information here is the wizard that is to be started and a list of parameters.
Both wizards have a .xml file as a parameter that describes the transformations of, for example, source files
from the template to the specific project. These are located together with the templates for the source code,
etc. in the Templates directory.
If a driver is to be created, the TwinCAT C++ Project Wizard starts the TwinCAT Module Class Wizard via
the TriggerAddModule parameter.
Directory: Templates
Both the templates for the source code and the .xml file named in the .vsz file for the TwinCAT Module Class
Wizard are located in corresponding subdirectories in the Templates directory.
This .xml file describes the procedure for getting from the template to a real project.
12.5.3 Transformations
The configuration file describes (in XML) the transformation of the template files into the project folder. In the
normal case these will be .cpp / .h and possibly project files; however, all types of files can be handled.
Several <FileDescription> elements, each of which describes the transformation of a file, follow here. After
these elements there is a possibility to define symbols that are available for the transformation in a
<Symbols> element.
• The source file from the templates directory is specified as the <SourceFile>.
• The destination file in the Project directory is specified as the <TargetFile>. A symbol is normally used
by means of the [!output...] command.
• The attribute "copyOnly" can be used to specify whether the file should be transformed, i.e. whether
the transformations described in the source file are executed. Otherwise the file is merely copied.
• The "openFile" attribute can be used to specify whether the file is to be opened after creation of the
project in Visual Studio.
• Filter: a filter is created in the project.
To do this the useProjectInterface="true" attribute must be set at the <ProjectFileGeneratorConfig>.
Transformation instructions
Commands that describe the transformations themselves are used in the template files.
• [!if SYMBOLNAME], [!else] and [!endif] describe a possibility to integrate corresponding text
only in certain situations during the transformation.
Symbol names
\Projects\{B9B2C4C6-072A-4B72-83C1-77FD2DEE35AB}\AddItemTemplates
\TemplateDirs\{3d3e7b23-b958-4a99-bfee-d0d953c182d4}\
This directory or directory structure can, for example, now be versioned in the version management system
and is also not affected by TwinCAT installations/updates.
Quick start
A general entry to the wizard environment in the MSDN is the entry point: https://msdn.microsoft.com/de-
de/library/7k3w6w59%28v=VS.120%29.aspx.
This describes how a template is used for creating a customer-specific module with the TwinCAT C++
Module Wizard.
1. Take an existing module template as the copying template
In C:\TwinCAT\3.x\Components\Base\CppTemplate\Templates
3. Copy the corresponding files .ico / .vsdir / .vsz also in the Class/
4. Now reference the copied .vsz file in the .vsdir file and adapt the description.
5. Enter the .xml file created in step 2 in the .vsz file.
6. You can now make changes to the source files in the Template/CustomerModuleCyclicIO/ directory.
The .xml takes care of replacements when creating a project from this template.
ð The TwinCAT Module Class Wizard now displays the new project for selection:
If the vsxproj, for example, are also to be provided in a changed form, it is recommended to adapt a copy of
the TwinCAT C++ Project Wizard.
If necessary, the use of settings in .props files should also be considered so that settings can also be
changed in existing projects created from a template – e.g. as a result of the .props files being updated by a
version management system.
A viable way here is to create a finished project and transform it into a template afterwards.
1. Copy the cleaned project into the Templates\ folder.
2. Create a transformation description (XML file).
3. Prepare the source files and the project file by means of the replacements described.
4. Provide the .ico / .vsdir / .vsz files.
13 Programming Reference
TwinCAT offers a wide range of basic functions. They all can be very useful for TwinCAT C++ programmers
and are documented here.
There is a wide range of C++ samples [} 257], which contain the valuable information on the handling of the
modules and interfaces.
A TwinCAT C++ project has some parameters that can be opened by double-clicking on the TwinCAT C++
project (project name here "Untitiled1").
Renaming is not possible at this stage (see Renaming TwinCAT C++ projects [} 238])
The encryption of the binary module can be set here, a more detailed description of the requirements can be
found here [} 55].
The option whether the sources should be included can be set here for the two archive types, which are
transferred to the target system or sent by email.
Different settings can be made in the project properties for a TwinCAT C++ project.
The project properties are opened by right-clicking on the C++ project -> Properties.
TwinCAT pages exist in addition to the Visual Studio C++ dialogs for the settings:
13.1.1 Tc SDK
Common
• TwinCAT SDK folder: File folder that provides the TwinCAT SDK and shows the value of the
environment variable TWINCATSDK.
Intrinsics
• Use intrinsics from platform toolset: the intrinsics should be used.
If an environment variable WINDDK7 is set, this option prevents the use of the WDK for a specific project.
• Build with WDK: Whether the WDK should be used.
• WinDDK7 folder: Displays the value of the WINDDK7 environment variable.
Version information from the project is provided in a header file and used for the build process.
If the .rc file contains version information, the header file is generated from it. With versioned C++ projects,
the version information is read from the TMC file and the macros from the generated header file are used in
the .rc file.
Extract Version
• Resource Input File: The .rc file to consider.
• Product Version Input File: TMC file containing the product version for versioned projects.
• File Version Input File: TMC file, which contains the file version for versioned projects.
• Header-Output File: Header File in which the information is provided.
13.1.3 Tc Publish
General Settings
• Platform(s): Which platforms should be built in a Publish?
• Configuration(s): Selection whether to build debug / release.
• Include Debug Information: For which configurations should the debug symbols (PDBs) be provided
in the repository?
• TMC / TML source file(s): TMC / TML files from the project that represent the starting point for the
Publish process.
• Publish as Versioned Library: Should the publishing take place in the repository [} 49]?
Installation Settings
• Archive: File path for an archive. Extensions .zip (for a ZIP archive) and .exe (for a self-extracting ZIP
archive) are allowed. Both contain the content for a repository (versioned C++ projects) or
CustomConfig/Modules (non-versioned C++ drivers) on another engineering system.
• Publish Installation Root Folder: No installation is performed on the local system with "None". The
files are only available under TWINCATSDK/_products/TcPublish. An archive can be created to
manually transfer these files to another system and install them there.
If "Default" is selected, an installation into the repository (versioned C++ projects) or CustomConfig/
Modules (non-versioned C++ drivers) is performed on the local system.
Special Settings
• Additional Files: Adding additional files to the Publish process, which are stored in the "deploy"
subdirectory during installation.
• Post publish command: Execute a command after the publish, e.g. to clean up.
13.1.4 Tc Sign
Enable Signing
• SHA1 signing: Should an operating system signature, which is necessary for the operating system, be
carried out?
• SHA256 signing: Should an operating system signature, which is necessary for the operating system,
be carried out?
• TwinCAT signing: Should a TwinCAT user certificate be used for signing? This is necessary for the
TwinCAT Loader [} 53].
TwinCAT Certificates
These parameters are used for all configurations such as debug and release.
• TwinCAT Certificate Name: Name of the certificate file (directory: C:\TwinCAT\3.x\CustomConfig
\Certificates). Alternatively, the environment variable TcSignTwinCatCertName can be set to the name
of the certificate file.
• TwinCAT Certificate Password: Password that protects the TwinCAT user certificate (stored in plain
text, leave blank if necessary). The TcSignTool [} 57] can be used to not store the password of the
TwinCAT user certificate in the project, where it would also end up in version management, for
example.
• Verbose Output: Should extended information be output during the signature?
Runtime / XAR
%TC_BOOTPRJPATH% Current configuration setup
\CurrentConfig\* usually C:\TwinCAT\3.x\Boot
%TC_DRIVERAUTOINSTALLP Compiled, platform-specific driver that is loaded
ATH% \*.sys/pdb via the operating system.
C:\TwinCAT\3.x\Driver\AutoInstall (system
loaded)
%TC_INSTALLPATH%\Boot Compiled platform-specific driver that is loaded
\Repository\<Vendor> via the TcLoader.
\<PrjName>\<Version>\*.tmx C:\TwinCAT\3.x\Boot\Repository\C++ Module
Vendor\Untitled1\0.0.0.1\Untitled1.tmx
%TC_BOOTPRJPATH% \TM TwinCAT Module Instance File
\OBJECTID.tmi Describes variables of the driver
File name is ObjectID.tmi
The configurations that are built in the case of a Build or Rebuild depend on the current selection in Visual
Studio:
The correct target architecture (in this case TwinCAT RT (x64)) is set appropriately by selecting the target
system.
The Configuration Manager allows the dedicated setting of the build configuration.
When selecting Build or Rebuild (and thus also Activate Configuration), the following steps are
performed:
TwinCAT 3.1 supports the exchange of C++ modules at runtime, i.e. without interrupting the real-time
program.
For this purpose, different versions of a TwinCAT Executable (TMX) are stored on the target system, as
already described here [} 49].
For all module instances from a TMX, a switchover between the versions can be initiated by the engineering.
The Online Change can be carried out through this dialog in engineering.
When dealing with the Online Change, there are therefore some aspects to consider:
• The project must provide a revision control.
• The DataAreas for these modules are kept outside the TcCOM module and made available to the
modules. This means that they do not need to consider the data or the mapping of the symbols in the
DataAreas.
• The DataAreas of the module must not change.
• References to internal data structures must not be passed on. Access must always take place via
interfaces that are retrieved via the TcQueryInterface, since these references are updated during an
Online Change.
After a restart, TwinCAT will start the driver in the initial version of the modules.
13.4 Limitations
TwinCAT 3 C++ modules [} 35] are executed in Windows kernel mode. Developers must therefore be aware
of some limitations:
• Win32 API [} 170] is not available in kernel mode
• Windows kernel mode API must not be used directly.
TwinCAT SDK provides functions, which are supported.
• User mode libraries (DLL) cannot be used. (see Third Party Libraries [} 250])
• The memory capacity for dynamic allocation in a real-time context is limited by the router memory (this
can be configured during engineering), see Memory Allocation [} 171].
• A subset of the C++ runtime library functions (CRT) is supported
• C++ exceptions are not supported.
• Runtime Type Information (RTTI [} 171]) is not supported.
• Subset of STL is supported (see STL / Containers [} 229])
• Support for functions from math.h through TwinCAT implementation (see Mathematical Functions
[} 226])
The original Win32 API is not available in Windows kernel mode. For this reason a list of the common
functions of the Win32 API and their equivalents for TwinCAT is provided here:
Instead, it may be possible to use the TCOM strategy. Define an ICustom interface, which is derived from
ITcUnknown and contains the methods, which are called from a derived class. The base class CMyBase is
derived from ITcUnknown and implements this interface. The class CMyDerived is derived from CMyBase
and from ICustom. It overwrites the TcQueryInterface method, which can then be used instead of dynamic
cast.
TcQueryInterface can also be used to display the IsType() function through evaluation of the return value.
This memory allocation can be used in the transitions [} 44] or in the OP state of the state machine.
If the memory allocation is made in a non-real-time context, the memory is allocated in the non-paged pool of
the operating system (blue in the diagram). In the TwinCAT real-time context, the memory is allocated in the
router memory (red in the diagram).
The memory can also be released in the transitions or the OP state; we recommend to always release the
memory in the "symmetric" transition, e.g. allocation in PS, release in SP.
Global instances must release memory allocated in the real-time context before the destructor.
13.6 Interfaces
Several interfaces are available for the interaction of the modules developed by the user with the TwinCAT 3
system. These are described (at API level) in detail on these pages.
Name Description
ITcUnknown [} 206] ITcUnknown defines the reference count as well as the querying of a reference
to a more specific interface.
ITComObject [} 191] The ITComObject interface is implemented by every TwinCAT module.
ITcCyclic [} 174] The interface is implemented by TwinCAT modules that are called once per task
cycle.
ITcCyclicCaller [} 175] Interface for logging the ItcCyclic interface of a module onto and off from a
TwinCAT task.
ITcFileAccess [} 177] Interface for accessing the file system
ITcFileAccessAsync [} 185] Asynchronous access to file operations.
ITcPostCyclic [} 197] The interface is implemented by TwinCAT modules that are called once per task
cycle following the output update.
ITcPostCyclicCaller [} 198] Interface for logging the ITcPostCyclic interface of a module onto and off from a
TwinCAT task.
ITcIoCyclic [} 186] This interface is implemented by TwinCAT modules that are called during the
input update and output update within a task cycle.
ITcIoCyclicCaller [} 188] Interface for logging the ITcIoCyclic interface of a module onto and off from a
TwinCAT task.
ITcRTimeTask [} 200] Query of extended TwinCAT task information.
ITcTask [} 201] Query of the timestamp and task-specific information of a TwinCAT task.
ITcTaskNotification Executes a callback if the cycle time was exceeded during the previous cycle.
[} 205]
TwinCAT SDK
The following return values can be returned in the case of ITc interfaces.
Name HRESULT
S_OK 0x0000 0000
S_FALSE 0x0000 0001
E_NOTIMPL 0x8000 4001
E_NOINTERFACE 0x8000 4002
E_POINTER 0x8000 4003
E_ABORT 0x8000 4004
E_FAIL 0x8000 4005
E_UNEXPECTED 0x8000 FFFF
E_ACCESSDENIED 0x8007 0005
E_HANDLE 0x8007 0006
E_OUTOFMEMORY 0x8007 000E
E_INVALIDARG 0x8007 0057
In addition, there is a possibility for ADS Return Codes to be returned as HRESULT. These are also available
as macros in the SDK, where they are known, for example, as ADS_E_BUSY for the ADS Error Code
ADSERR_DEVICE_BUSY.
Syntax
TCOM_DECL_INTERFACE("03000010-0000-0000-e000-000000000064", ITcCyclic)
struct__declspec(novtable) ITcCyclic : public ITcUnknown
Methods
Name Description
CycleUpdate [} 174] Is called once per task cycle if the interface is logged on to a cyclic caller.
Comments
The ITcCyclic interface is implemented by TwinCAT modules. This interface is passed to the
ITcCyclicCaller::AddModule() method when a module logs on to a task, usually as the last initialization step
in the transition from SafeOP to OP. After login, the CycleUpdate() method of the module instance is called.
Syntax
Parameters
Context: (type: ULONG_PTR) context contains the value which has been passed to method
ITcCyclicCaller::AddModule()
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Within a task cycle the method CycleUpdate() is called after InputUpdate() has been for all registered
module instances. Therefore, this method should be used to implement cyclic processing.
Syntax
TCOM_DECL_INTERFACE("0300001E-0000-0000-e000-000000000064", ITcCyclicCaller)
struct__declspec(novtable) ITcCyclicCaller : public ITcUnknown
Methods
Name Description
AddModule [} 175] Login module that implements the ITcCyclic interface.
RemoveModule [} 176] Log off the previously logged in ITcCyclic interface of a
module.
Comments
The ITcCyclicCaller interface is implemented by TwinCAT tasks. A module uses this interface to login its
ITcCyclic interface to a task, usually as the last initialization step in the SafeOP to OP transition. After login,
the CycleUpdate() method of the module instance is called. The interface is also used to log off the module
so that it is no longer called by the task.
Syntax
virtual HRESULT TCOMAPI
AddModule(STcCyclicEntry* pEntry, ITcCyclic* ipMod, ULONG_PTR
context=0, ULONG sortOrder=0)=0;
Parameter
pEntry: (type: STcCyclicEntry) [in] pointer to a list item that is inserted into the internal list of the cyclic caller;
see also description [} 176].
ipMod: (type: ITcCyclic) [in] interface pointer used by the cyclic caller.
context: (type: ULONG_PTR) [optional] a context value that is transferred to the ITcCyclic::CyclicUpdate()
method with each call.
sortOrder: (type: ULONG) [optional] the sorting order can be used for controlling the order of execution if
various module instances are executed by the same cyclic caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
The error ADSERR_DEVICE_INVALIDSTATE is returned if the cyclic caller, i.e. the TwinCAT task is not in
the OP state.
Description
A TwinCAT module class normally uses a Smart Pointer to refer to the cyclic caller type ITcCyclicCallerPtr.
The object ID of the task is stored in this Smart Pointer and a reference to the task can be obtained via the
TwinCAT object server. In addition, the Smart Pointer class already contains a list item. Therefore the Smart
Pointer can be used as the first parameter for the AddModule method.
The following sample code shows the login of the ITcCyclicCaller interface.
RESULT hr =
S_OK;
if ( m_spCyclicCaller.HasOID() ) {
if ( SUCCEEDED_DBG(hr =
m_spSrv->TcQuerySmartObjectInterface(m_spCyclicCaller)) )
{
if ( FAILED(hr =
m_spCyclicCaller->AddModule(m_spCyclicCaller,
THIS_CAST(ITcCyclic))) ) {
}
Syntax
virtual HRESULT TCOMAPI
RemoveModule(STcCyclicEntry* pEntry)=0;
Parameters
pEntry: (type: STcCyclicEntry) refers to the list entry which should be removed from the internal list of the
cyclic caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
The method returns E_FAIL if the entry is not in the internal list.
Description
Similar to the method AddModule() the smart pointer for the cyclic caller is used as list entry when the
module instance should be removed from cyclic caller.
ITcCyclicCallerInfoPtr m_spCyclicCaller;
if (
m_spCyclicCaller ) {
m_spCyclicCaller->RemoveModule(m_spCyclicCaller);
}
m_spCyclicCaller = NULL;
Syntax
Methods
Name Description
FileOpen [} 177] Opens a file.
FileClose [} 178] Closes a file.
FileRead [} 179] Reads from a file.
FileWrite [} 179] Writes to a file.
FileSeek [} 180] Sets position in a file.
FileTell [} 180] Queries position in a file.
FileRename [} 181] Renames a file.
FileDelete [} 181] Deletes a file.
FileGetStatus [} 182] Gets the status of a file.
FileFindFirst [} 183] Searches for a file, first iteration.
FileFindNext [} 183] Searches for a file, next iteration.
FileFindClose [} 184] Closes a file search.
MkDir [} 184] Creates a directory.
RmDir [} 185] Deletes a directory.
Remarks
Syntax
virtual HRESULT TCOMAPI FileOpen(PCCH szFileName, TcFileAccessMode AccessMode, PTcFileHandle
phFile);
Parameter
AccessMode: (type: TcFileAccessMode) [in] method of accessing the file; see TcFileAccessServices.h.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
The method returns a handle to access the file, which name is defined in szFileName.
Syntax
virtual HRESULT TCOMAPI FileClose(PTcFileHandle phFile);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI
FileRead(TcFileHandle hFile, PVOID pData, UINT cbData, PUINT pcbRead);
Parameter
cbData: (type: PVOID) [in] maximum size of the data to be read (size of the memory behind pData).
pcbRead: (type: PUINT) [out] size of the data that was read.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method retrieves data from a file defined by the file handle. Data will be stored in pData while pcbRead
provides length of given data.
Syntax
virtual HRESULT TCOMAPI
FileWrite(TcFileHandle hFile, PCVOID pData, UINT cbData, PUINT pcbWrite);
Parameter
cbData: (type: PVOID) [in] size of the data to be written (size of the memory behind pData).
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method writes data to a file defined by the file handle. Data will be read from pData while pcbRead
provides length of data.
Syntax
virtual HRESULT TCOMAPI FileSeek(TcFileHandle hFile, UINT uiPos);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method sets the position within the file for further actions
Syntax
virtual HRESULT TCOMAPI FileTell(TcFileHandle hFile, PUINT puiPos);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method retrieves the position within the file, which is currently set.
Syntax
virtual HRESULT TCOMAPI FileRename(PCCH szOldName, PCCH szNewName);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI FileDelete(PCCH szFileName);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI FileGetStatus(PCCH szFileName, PTcFileStatus pFileStatus));
Parameter
pFileStatus: (type: PTcFileStatus) [out] the state of the file, cf. TcFileAccessServices.h .
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI FileFindFirst (PCCH szFileName, PTcFileFindData pFileFindData ,
PTcFileFindHandle phFileFind);
Parameter
szFileName: (type: PCCH) [in] directory or path and name of the file sought. The file name can contain
placeholders such as asterisk (*) or question mark (?).
pFileFindData: (type: PTcFileFindData) [out] the description of the first file, cf. TcFileAccessServices.h
phFileFind: (type: PTcFileFindHandle) [out] handle for searching further with FileFindNext.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method starts with finding files in a defined directory. The Method provides access to PTcFileFindData
of the first found file, which contains the following information:
typedef struct TcFileFindData
{
TcFileHandle hFile;
DWORD dwFileAttributes;
ULONGLONG ui64CreationTime;
ULONGLONG ui64LastAccessTime;
ULONGLONG ui64LastWriteTime;
DWORD dwFileSizeHigh;
DWORD dwFileSizeLow;
DWORD dwReserved1;
DWORD dwReserved2;
CHAR cFileName[260];
CHAR cAlternateFileName[14];
WORD wReserved0;
} TcFileFindData, *PTcFileFindData;
Syntax
virtual HRESULT TCOMAPI FileFindNext (TcFileFindHandle hFileFind, PTcFileFindData pFileFindData);
Parameters
pFileFindData: (type: PTcFileFindData) [out] the description of the next file. Compare
TcFileAccessServices.h.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
This method finds next file in a directory. The Method provides access to PTcFileFindData of the found file,
which contains the following information:
typedef struct TcFileFindData
{
TcFileHandle hFile;
DWORD dwFileAttributes;
ULONGLONG ui64CreationTime;
ULONGLONG ui64LastAccessTime;
ULONGLONG ui64LastWriteTime;
DWORD dwFileSizeHigh;
DWORD dwFileSizeLow;
DWORD dwReserved1;
DWORD dwReserved2;
CHAR cFileName[260];
CHAR cAlternateFileName[14];
WORD wReserved0;
} TcFileFindData, *PTcFileFindData;
Syntax
virtual HRESULT TCOMAPI FileFindClose (TcFileFindHandle hFileFind);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI MkDir(PCCH szDir);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
virtual HRESULT TCOMAPI RmDir(PCCH szDir);
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
A particularly interesting error code is ADSERR_DEVICE_TIMEOUT if the timeout (5 seconds) has elapsed.
Description
Syntax
TCOM_DECL_INTERFACE("C04AC244-C126-466E-982E-93EC571F2277", ITcFileAccessAsync) struct
__declspec(novtable) ITcFileAccessAsync: public ITcFileAccess
Methods
Name Description
C [} 186]heck Query the state of the file operation.
Interface parameters
Name Description
PID_TcFileAccessAsyncSegmentSize Size of the segments transferred to system service.
PID_TcFileAccessAsyncTimeoutMs Sets the timeout in [ms].
PID_TcFileAccessAsyncNetId(Str) NetId of the system service to be contacted.
Comments
Syntax
virtual HRESULT TCOMAPI Check();
Parameters
none
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
This operation checks the state of the previously called file operation.
Syntax
TCOM_DECL_INTERFACE("03000011-0000-0000-e000-000000000064", ITcIoCyclic)
struct __declspec(novtable) ITcIoCyclic : public ITcUnknown
Methods
Name Description
InputUpdate [} 187] Is called at the beginning of a task cycle if the interface is
logged on to a cyclic I/O caller.
OutputUpdate [} 187] Is called at the end of a task cycle if the interface is logged on
to a cyclic I/O caller.
Comments
ITcIoCyclic can be used to implement a TwinCAT module that acts as a fieldbus driver or I/O filter module.
This interface is passed to the ITcIoCyclicCaller::AddIoDriver method when a module logs on to a task,
usually as the last initialization step at the transition from SafeOP to OP. After login, the methods
InputUpdate() and OutputUpdate() of the module instance are called once per task cycle.
Syntax
Parameter
dwStateIn: (type: DWORD) future extensions reserved; at present this value is always 0.
context: (type: ULONG_PTR) context contains the value that was transferred to the method
ITcCyclicCaller::AddIoDriver().
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
In a task cycle the method InputUpdate() is first called for all registered module instances. Therefore this
method must be used for updating the data areas of the type Input-Source of the module.
Syntax
Parameters
pdwStateOut: (type: DWORD) [out] reserved for future extensions, currently returned value is ignored.
context: (type: ULONG_PTR) context contains the value which has been passed to method
ITcCyclicCaller::AddIoDriver()
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
In a task cycle the method OutputUpdate() is called for all registered module instances. Therefore this
method must be used for updating the data areas of the type Output-Destination of the module.
Syntax
TCOM_DECL_INTERFACE("0300001F-0000-0000-e000-000000000064", ITcIoCyclicCaller)
struct__declspec(novtable) ITcIoCyclicCaller : public ITcUnknown
Methods
Name Description
AddIoDriver [} 188] Login module that implements the ITcIoCyclic interface.
RemoveIoDriver [} 189] Log off the previously logged in ITcIoCyclic interface of a
module.
Comments
The ITcIoCyclicCaller interface is implemented by TwinCAT tasks. A module uses this interface to login its
ITcIoCyclic interface to a task, usually as the last initialization step in the SafeOP to OP transition. After
login, the CycleUpdate() method of the module instance is called. The interface is also used to log off the
module so that it is no longer called by the task.
Syntax
Parameter
pEntry: (type: STcIoCyclicEntry) pointer to a list item that is inserted into the internal list of the cyclic I/O
caller; see also description [} 176].
ipDrv: (type: ITcloCyclic) [in] interface pointer used by the cyclic I/O caller.
context: (type: ULONG_PTR) [optional] a context value that is transferred to the ITcIoCyclic::InputUpdate()
and ITcIoCyclic::OutputUpdate methods with each call.
sortOrder: (type: ULONG) [optional] the sorting order can be used for controlling the order of execution if
various module instances are executed by the same cyclic caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
A TwinCAT module class normally uses a Smart Pointer to refer to the cyclic I/O caller of type
ITcIoCyclicCallerPtr. The object ID of the cyclic I/O caller is stored in this Smart Pointer and a reference can
be obtained via the TwinCAT object server. In addition, the Smart Pointer class already contains a list item.
Therefore the Smart Pointer can be used as the first parameter for the AddIoDriver method.
The following code sample illustrates the login of the ITcIoCyclicCaller interface.
HRESULT hr = S_OK;
if ( m_spIoCyclicCaller.HasOID() )
{
if ( SUCCEEDED_DBG(hr = m_spSrv->TcQuerySmartObjectInterface(m_spIoCyclicCaller))
)
{
if ( FAILED(hr = m_spIoCyclicCaller->AddIoDriver(m_spIoCyclicCaller,
THIS_CAST(ITcIoCyclic))) )
{
m_spIoCyclicCaller = NULL;
}
}
}
Syntax
Parameters
pEntry: (type: STcIoCyclicEntry) refers to the list entry which should be removed from the internal list of the
cyclic I/O caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
The method returns E_FAIL if the entry is not in the internal list.
Description
Comparable with the AddIoDriver() method, the smart pointer is used for the cyclic I/O caller as a list item if
the module instance is to be removed from the cyclic I/O caller.
Syntax
TCOM_DECL_INTERFACE ("D28A8CD2-5477-4B75-AF0F-998841AF9E44", ITComOnlineChange)
Methods
Name Description
PrepareOnlineChange [} 190] This method is called to prepare the Online Change.
PerformOnlineChange [} 191] This method is called to perform the Online Change.
Comments
The implementation of this interface is necessary for a module to be capable of Online Change. Furthermore
such a module must be created in a versioned C++ project.
• Here [} 168] is a general description of the procedure.
• This procedure can be followed for existing modules: Online Change [} 168].
The method is called by TwinCAT to execute the OnlineChange. It runs asynchronously in the background,
which must be taken into account when accessing the existing object.
The preparation should include all operations that can already be performed.
Syntax
virtual HRESULT TCOMAPI PrepareOnlineChange(ITComObject* ipOldObj, TmcInstData* pOldInfo) = 0;
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Via ipOldObj, the data of the existing object is made available for transfer so that it can be applied.
For example:
ULONG nData = sizeof(m_Parameter);
PVOID pData = &m_Parameter;
ipOldObj->TcGetObjPara(PID_Module1Parameter, nData, pData);
The method is called by TwinCAT to execute the OnlineChange. It is called blocking. It should therefore only
take a short time.
Syntax
virtual HRESULT TCOMAPI PerformOnlineChange(ITComObject* ipOldObj, TmcInstData* pOldInfo) = 0;
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Via ipOldObj, the data of the existing object is made available for transfer so that it can be applied.
For example:
ULONG nData = sizeof(m_Parameter);
PVOID pData = &m_Parameter;
ipOldObj->TcGetObjPara(PID_Module1Parameter, nData, pData);
Syntax
TCOM_DECL_INTERFACE("00000012-0000-0000-e000-000000000064", ITComObject)
struct__declspec(novtable) ITComObject: public ITcUnknown
Methods
Name Description
TcGetObjectId(OTCID& objId) Saves the object ID using the given OTCID reference.
[} 192]
TcSetObjectId [} 192] Sets the object ID of the object to the given OTCID.
TcGetObjectName [} 193] Saves the object names in the buffer with the given length.
TcSetObjectName [} 193] Sets the object name of the object to given CHAR*.
TcSetObjState [} 194] Initializes a transition to a predefined state.
TcGetObjState [} 194] Queries the current state of the object.
TcGetObjPara [} 194] Queries an object parameter identified with its PTCID.
TcSetObjPara [} 195] Sets an object parameter identified with its PTCID.
TcGetParentObjId [} 195] Saves the parent object ID with the help of the given OTCID reference.
TcSetParentObject [} 196] Sets the parent object ID to the given OTCID.
Comments
The ITComObject interface is implemented by every TwinCAT module. It makes functionalities available
regarding the state machine and Information from/to the TwinCAT system.
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameters
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameters
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The method TcGetObjectName stores the Object name into buffer with given length.
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The method TcSetObjectName sets objects’s Object Name to the given CHAR*.
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The method TcGetParentObjId stores Parent Object ID using given OTCID reference.
Syntax
Parameter
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The method TcSetParentObjId sets Parent Object ID using given OTCID reference.
TwinCAT C++ provides additional functions, which are not directly defined through the interface.
Syntax
Methods
Name Description
OTCID TcGetObjectId [} 197] Queries the object ID.
TcTryToReleaseOpState [} 197] Releases resources; must be implemented.
Comments
Syntax
OTCID TcGetObjectId(void)
Parameters
Return Value
Description
Syntax
BOOL TcTryToReleaseOpState(void)
Parameters
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The method TcTryToReleaseOpState releases resources, e.g. data pointers, in order to prepare for exiting
the OP state. Must be implemented in order to cancel possible mutual dependencies of module instances.
See Sample 10 [} 279].
Syntax
TCOM_DECL_INTERFACE("03000025-0000-0000-e000-000000000064", ITcPostCyclic)
struct__declspec(novtable) ITcPostCyclic : public ITcUnknown
Methods
Name Description
PostCycleUpdate [} 198] Is called once per task cycle after the output update if the interface has been
logged on to a cyclic caller.
Comments
The ITcPostCyclic interface is implemented by TwinCAT modules. This interface is passed to the
ITcCyclicCaller::AddPostModule() method when a module logs itself on to a task, usually as the last
initialization step at the transition from SafeOP to OP. After login, the PostCycleUpdate() method of the
module instance is called.
Syntax
Parameters
Context: (type: ULONG_PTR) context contains the value which has been passed to method
ITcPostCyclicCaller::AddPostModule()
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Within a task cycle the method PostCycleUpdate() is called after OutputUpdate() has been for all registered
module instances. Therefore, this method should be used to implement such cyclic processing.
Syntax
TCOM_DECL_INTERFACE("03000026-0000-0000-e000-000000000064", ITcCyclicCaller)
struct__declspec(novtable) ITcPostCyclicCaller : public ITcUnknown Ca
Methods
Name Description
AddPostModule [} 199] Login module that implements the ITcPostCyclic interface.
RemovePostModule [} 200] Log off the previously logged in ITcPostCyclic interface of a
module.
Comments
The ITcPostCyclicCaller interface is implemented by TwinCAT tasks. A module uses this interface to login its
ITcPostCyclic interface to a task, usually as the last initialization step in the SafeOP to OP transition. After
login, the PostCycleUpdate() method of the module instance is called. The interface is also used to log off
the module so that it is no longer called by the task.
Syntax
virtual HRESULT TCOMAPI
AddPostModule(STcPostCyclicEntry* pEntry, ITcPostCyclic* ipMod, ULONG_PTR
context=0, ULONG sortOrder=0)=0;
Parameter
pEntry: (type: STcPostCyclicEntry) [in] pointer to a list item that is inserted into the internal list of the cyclic
caller; see also description [} 199].
ipMod: (type: ITcPostCyclic) [in] interface pointer used by the cyclic caller.
sortOrder: (type: ULONG) [optional] the sorting order can be used for controlling the order of execution if
various module instances are executed by the same cyclic caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
The error ADSERR_DEVICE_INVALIDSTATE is returned if the cyclic caller, i.e. the TwinCAT task is not in
the OP state.
Description
A TwinCAT module class uses a Smart Pointer to refer to the cyclic caller of type ITcPostCyclicCallerPtr. The
object ID of the task is stored in this Smart Pointer and a reference to the task can be obtained via the
TwinCAT object server. In addition, the Smart Pointer class already contains a list item. Therefore the Smart
Pointer can be used as the first parameter for the AddPostModule method.
The following code sample illustrates the login of the ITcPostCyclicCaller interface.
RESULT hr =
S_OK;
if ( m_spPostCyclicCaller.HasOID() ) {
if ( SUCCEEDED_DBG(hr =
m_spSrv->TcQuerySmartObjectInterface(m_spPostCyclicCaller)) )
{
if ( FAILED(hr =
m_spPostCyclicCaller->AddPostModule(m_spPostCyclicCaller,
THIS_CAST(ITcPostCyclic))) ) {
}
Syntax
virtual HRESULT TCOMAPI
RemovePostModule(STcPostCyclicEntry* pEntry)=0;
Parameters
pEntry: (type: STcPostCyclicEntry) refers to the list entry which should be removed from the internal list of
the cyclic caller.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
The method returns E_FAIL if the entry is not in the internal list.
Description
Similar to the method AddPostModule() the smart pointer for the cyclic caller is used as list entry when the
module instance should be removed from cyclic caller.
ITcPostCyclicCallerInfoPtr m_spPostCyclicCaller;
if (
m_spPostCyclicCaller ) {
m_spPostCyclicCaller->RemovePostModule(m_spPostCyclicCaller);
m_spPostCyclicCaller = NULL;
Syntax
TCOM_DECL_INTERFACE("02000003-0000-0000-e000-000000000064", ITcRTimeTask)
struct __declspec(novtable) ITcRTimeTask : public ITcTask
Methods
Name Description
GetCpuAccount [} 201] Query of the CPU account of a TwinCAT Task.
Remarks
Retrieving and using TwinCAT task Information could be done by this interface.
Syntax
virtual HRESULT TCOMAPI GetCpuAccount(PULONG pAccount)=0;
Parameters
pAccount: (type: PULONG) [out] TwinCAT task CPU account is stored in this parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
The GetCpuAccount() method can be used to query the current computing time used for the task.
Code snippet showing the use of GetCpuAccount(), e.g. within an ITcCyclic::CycleUpdate() method:
ComputeSomething();
ULONG nStop = 0;
hr = FAILED(hr) ? hr : spRTimeTask->GetCpuAccount(&nStop);
Syntax
TCOM_DECL_INTERFACE("02000002-0000-0000-e000-000000000064", ITcTask)
struct __declspec(novtable) ITcTask : public ITcUnknown
Methods
Name Description
GetCycleCounter [} 204] Query number of task cycles since task start.
GetCycleTime [} 204] Query of task cycle time in nanoseconds, i.e. time between
"begin of task" and next "begin of task".
GetPriority [} 202] Querying the task priority.
GetCurrentSysTime [} 203] Querying the time when the task cycle starts at intervals of 100
nanoseconds since January 1, 1601 (UTC).
GetCurrentDcTime [} 203] Querying the distributed clock time when the task cycle starts
in nanoseconds since January 1, 2000.
GetCurPentiumTime [} 204] Querying the time when the method is called at intervals of 100
nanoseconds since January 1, 1601 (UTC).
Comments
With the ITcTask interface the time can be measured in real-time context.
Syntax
Parameter
pPriority: (Type: PULONG) [out] Priority value of the task is stored in this parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameters
pSysTime: (type: PLONGLONG) [out] current system time at task cycle start is stored in this parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameters
pDcTime: (type: PLONGLONG) [out] distributed clock time at task cycle start is stored in this parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
pCurTime: (Type: PLONGLONG) [out] This parameter stores the current time (UTC) in 100 nanosecond
intervals since January 1, 1601.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameter
pCnt: (type: PULONGLONG) [out] the number of task cycles since the task was started is stored in this
parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
Parameters
pCycleTimeNS: (type: PULONG) [out] the configured task cycle time in nanoseconds is stored in this
parameter.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Syntax
TCOM_DECL_INTERFACE("9CDE7C78-32A0-4375-827E-924B31021FCD", ITcTaskNotification) struct
__declspec(novtable) ITcTaskNotification: public ITcUnknown
Methods
Name Description
NotifyCycleTimeExceeded Called if the cycle time was exceeded.
Comments
Note that the callback does not take place during the calculations, but at the end of the cycle. Therefore, this
method does not offer any mechanism for immediately stopping the calculations.
Syntax
virtual HRESULT TCOMAPI NotifyCycleTimeExceeded ();
Parameters
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Gets called if cycle time was exceeded beforehand. So not immediately on exceeded time, but afterwards.
Syntax
TCOM_DECL_INTERFACE("00000001-0000-0000-e000-000000000064", ITcUnknown)
Required include: -
Methods
Name Description
TcAddRef [} 206] Increments the reference counter.
TcQueryInterface [} 206] Query of the reference to an implemented interface via the IID.
TcRelease [} 207] Decrements the reference counter.
Remarks
Every TcCOM interface is directly or indirectly derived from ITcUnknown. As a consequence every TcCOM
module class implements ITcUnknown, because it is derived from ITComObject.
The default implementation for ITcUnknown will delete the object if its last reference is released. Therefore
an interface pointer must not be dereferenced after TcRelease() has been called.
Syntax
ULONG TcAddRef( )
Return Value
Description
Syntax
HRESULT TcQueryInterface(RITCID iid, PPVOID pipItf )
pipItf: (PPVOID Type) pointer to interface pointer. Is set when the requested interface type is available from
the corresponding instance.
Return value
If successful, S_OK ("0") or another positive value will be returned, cf. Return values [} 173]. Extended
messages refer in particular to the column HRESULT in ADS Return Codes.
Description
Query reference to an implemented interface by the IID. It is recommended to use smart pointers to initialize
and hold interface pointers.
Variant 1:
HRESULT GetTraceLevel(ITcUnkown* ip, TcTraceLevel& tl)
{
HRESULT hr = S_OK;
if (ip != NULL)
{
ITComObjectPtr spObj;
hr = ip->TcQueryInterface(spObj.GetIID(), &spObj);
if (SUCCEEDED(hr))
{
hr = spObj->TcGetObjPara(PID_TcTraceLevel, &tl, sizeof(tl));
}
return hr;
}
}
The interface id associated with the smart pointer can be used as parameter in TcQueryInterface. The
operator “&” will return pointer to internal interface pointer member of the smart pointer. Variant 1 assumes
that interface pointer is initialized if TcQueryInterface indicates success. If scope is left the destructor of the
smart pointer spObj releases the reference.
Variant 2:
When assigning interface pointer ip to smart pointer spObj method TcQueryInterface is implicitly called with
IID_ITComObject on the instance ip refers to. This results in shorter code, however it loses the original return
code of TcQueryInterface.
Syntax
ULONG TcRelease( )
Return Value
Description
Methods provided
Name Description
abs Calculates the absolute value.
atof Converts a string (char *buf) into a double.
BitScanForward Searches for a set bit (1) from LSB to MSB.
BitScanReverse Searches for a set bit (1) from MSB to LSB.
labs Calculates the absolute value.
memcmp Compares two buffers.
memcpy Copies one buffer into another.
memcpy_byte Copies one buffer into another (bytewise).
memset Sets the bytes of a buffer to a value.
qsort QuickSort for sorting a list.
snprintf Writes formatted data into a character string.
sprintf Writes formatted data into a character string.
sscanf Reads data from a character string after specification of a format.
strcat Appends one character string to another.
strchr Searches for a character in a character string.
strcmp Compares two character strings.
strcpy Copies a character string.
strlen Determines the length of a character string.
strncat Appends one character string to another.
strncmp Compares two character strings.
strncpy Copies a character string.
strstr Searches for a character string within a character string.
strtol Converts a character string into an integer.
strtoul Converts a character string into an unsigned integer.
swscanf Reads data from a character string after specification of a format.
tolower Converts a letter into a lower-case letter.
toupper Converts a letter into an upper-case letter.
vsnprintf Writes formatted data into a character string ('\0' scheduling).
vsprintf Writes formatted data into a character string.
Comments
In this section both the outgoing and incoming ADS communication is described for TwinCAT 3 C++
modules.
The ADS Return Codes [} 344] apply to the entire ADS communication.
13.8.1 AdsReadDeviceInfo
13.8.1.1 AdsReadDeviceInfoReq
The method AdsDeviceInfoReq enables the transfer of an ADS DeviceInfo command for reading the
identification and version number of an ADS server.
AdsReadDeviceInfoCon is called on receipt of the response.
Syntax
Parameters
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
Return value
Type: int
13.8.1.2 AdsReadDeviceInfoInd
The method AdsDeviceInfoInd indicates an ADS DeviceInfo command for reading the identification and
version number of an ADS server. The AdsReadDeviceInfoRes [} 210] must be called afterwards.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
Return Value
void
13.8.1.3 AdsReadDeviceInfoRes
The method AdsReadDeviceInfoRes sends an ADS Read Device Info. AdsReadDeviceInfoCon [} 211] forms
the counterpart and is subsequently called.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
version: (type: AdsVersion) [in] structure of build (int), revision (byte) and version (byte) of the device.
Return value
Type: int
13.8.1.4 AdsReadDeviceInfoCon
The method AdsReadDeviceInfoCon permits to receive an ADS read device info confirmation. The receiving
module has to provide this method. The AdsReadDeviceInfoReq [} 209] is the counterpart and need to be
called beforehand.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
version: (type: AdsVersion) [in] structure of build (int), revision (byte) and version (byte) of the device.
Return Value
void
13.8.2 AdsRead
13.8.2.1 AdsReadReq
The method AdsReadReq enables the sending of an ADS read command for the data transmission from an
ADS device.
AdsReadCon [} 213] is called on receipt of the response.
Syntax
int AdsReadReq( AmsAddr& rAddr, ULONG invokeId, ULONG indexGroup, ULONG indexOffset, ULONG
cbLength );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data to be read (pData).
Return value
Type: int
13.8.2.2 AdsReadInd
The method AdsReadInd permits to receive an ADS read request. The AdsReadRes [} 212] needs to be
called for sending the result.
Syntax
void AdsReadInd( AmsAddr& rAddr, ULONG invokeId, ULONG indexGroup, ULONG indexOffset, ULONG
cbLength );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data to be read (pData).
Return value
Type: int
13.8.2.3 AdsReadRes
The method AdsReadRes enables the sending of an ADS read response. AdsReadCon [} 213] forms the
counterpart and is subsequently called.
Syntax
int AdsReadRes( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG cbLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS read command; see AdsStatuscodes [} 344].
cbLength: (type: ULONG) [in] contains the length in bytes of the data that was read (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the data are located.
Return value
Type: int
13.8.2.4 AdsReadCon
The method AdsReadCon enables the reception of an ADS read confirmation. The receiving module must
provide this method.
The counterpart AdsReadReq [} 211] must have been called beforehand.
Syntax
void AdsReadCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG cbLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS read command; see AdsStatuscodes [} 344].
cbLength: (type: ULONG) [in] contains the length in bytes of the data that was read (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the data are located.
Return Value
void
13.8.3 AdsWrite
13.8.3.1 AdsWriteReq
The method AdsWriteReq enables the sending of an ADS write command for transferring data to an ADS
device.
AdsWriteCon [} 215] is called on receipt of the response.
Syntax
int AdsWriteReq( AmsAddr& rAddr, ULONG invokeId, ULONG indexGroup, ULONG indexOffset, ULONG
cbLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data to be written (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return value
Type: int
13.8.3.2 AdsWriteInd
The method AdsWriteInd indicates an ADS write command, for the transfer of data to an ADS device.
The AdsWriteRes [} 214] has to be called for confirming the operation.
Syntax
void AdsWriteInd( AmsAddr& rAddr, ULONG invokeId, ULONG indexGroup, ULONG indexOffset, ULONG
cbLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data to be written (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return value
void
13.8.3.3 AdsWriteRes
The method AdsWriteRes sends an ADS write response. AdsWriteCon [} 215] forms the counterpart and is
subsequently called.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return Value
Type: int
13.8.3.4 AdsWriteCon
The method AdsWriteCon enables the reception of an ADS write confirmation. The receiving module must
provide this method.
AdsWriteReq [} 213] forms the counterpart and must have been called beforehand.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return Value
void
13.8.4 AdsReadWrite
13.8.4.1 AdsReadWriteReq
The method AdsReadWriteReq permits to send an ADS readwrite command, for the transfer of data to and
from an ADS device. The AdsReadWriteCon [} 217] will be called on arrival of the answer.
Syntax
int AdsReadWriteReq( AmsAddr& rAddr, ULONG invokeId, ULONG indexGroup, ULONG indexOffset, ULONG
cbReadLength, ULONG cbWriteLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbReadLength: (type: ULONG) [in] contains the length in bytes of the data to be read (pData).
cbWriteLength: (type: ULONG) [in] contains the length in bytes of the data to be written (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return value
Type: int
13.8.4.2 AdsReadWriteInd
The method AdsReadWriteInd indicates an ADS readwrite command, for the transfer of data to and from an
ADS device. The AdsReadWriteRes [} 218] needs to be called for sending the result.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbReadLength: (type: ULONG) [in] contains the length in bytes of the data to be read (pData).
cbWriteLength: (type: ULONG) [in] contains the length in bytes of the data to be written (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return Value
void
13.8.4.3 AdsReadWriteRes
The method AdsReadWriteRes permits to receive an ADS read write confirmation. The AdsReadWriteCon
[} 217] is the counterpart and will be called afterwards.
Syntax
int AdsReadWriteRes( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG cbLength, PVOID
pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
cbLength: (type: ULONG) [in] contains the length in bytes of the data that was read (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the data are located.
Return value
Type: int
13.8.4.4 AdsReadWriteCon
The method AdsReadWriteCon enables the reception of an ADS read/write confirmation. The receiving
module must provide this method.
AdsReadWriteReq [} 215] forms the counterpart and must be called beforehand.
Syntax
void AdsReadWriteCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG cbLength, PVOID pData );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
cbLength: (type: ULONG) [in] contains the length in bytes of the data that was read (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the data are located.
Return Value
void
13.8.5 AdsReadState
13.8.5.1 AdsReadStateReq
The method AdsReadStateReq permits to send an ADS read state command for reading the ADS status and
the device status from an ADS server. The AdsReadStateCon [} 219] will be called on arrival of the answer.
Syntax
Parameters
rAddr: (type: AmsAddr) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
Return value
Type: int
13.8.5.2 AdsReadStateInd
The method AdsReadStateInd indicates an ADS read state command for reading the ADS status and the
device status from an ADS device. The AdsReadStateRes [} 218] needs to be called for sending the result.
Syntax
Parameters
rAddr: (type: AmsAddr) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
Return Value
void
13.8.5.3 AdsReadStateRes
The method AdsWriteRes enables the sending of an ADS status read response. AdsReadStateCon [} 219]
forms the counterpart and is subsequently called.
Syntax
int AdsReadStateRes( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, USHORT adsState, USHORT
deviceState );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
adsState: (type: USHORT) [in] contains the ADS state of the device.
deviceState: (type: USHORT) [in] contains the device status of the device.
Return value
Type: int
13.8.5.4 AdsReadStateCon
The method AdsWriteCon enables the reception of an ADS state read confirmation. The receiving module
must provide this method.
AdsReadStateReq [} 217] forms the counterpart and must be called beforehand.
Syntax
void AdsReadStateCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, USHORT adsState, USHORT
deviceState );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
adsState: (type: USHORT) [in] contains the ADS state of the device.
deviceState: (type: USHORT) [in] contains the device status of the device.
Return Value
void
13.8.6 AdsWriteControl
13.8.6.1 AdsWriteControlReq
The method AdsWriteControlReq permits to send an ADS write control command for changing the ADS
status and the device status of an ADS server. The AdsWriteControlCon [} 221] will be called on arrival of
the answer.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
adsState: (Type: USHORT) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
deviceState: (Type: USHORT) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return value
Type: int
13.8.6.2 AdsWriteControlInd
The method AdsWriteControlInd permits to send an ADS write control command for changing the ADS status
and the device status of an ADS device. The AdsWriteControlRes [} 220] has to be called for confirming the
operation.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
adsState: (Type: USHORT) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
deviceState: (Type: USHORT) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
cbLength: (type: ULONG) [in] contains the length in bytes of the data (pData).
pData: (type: PVOID) [in] pointer to the data buffer in which the written data are located.
Return Value
void
13.8.6.3 AdsWriteControlRes
The method AdsWriteControlRes permits to send an ADS write control response. The AdsWriteControlCon
[} 221] is the counterpart and will be called afterwards.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return value
Type: int
13.8.6.4 AdsWriteControlCon
The method AdsWriteCon enables the reception of an ADS write control confirmation. The receiving module
must provide this method.
AdsWriteControlReq [} 219] forms the counterpart and must be called beforehand.
Syntax
void AdsWriteControlCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return Value
void
13.8.7 AdsAddDeviceNotification
13.8.7.1 AdsAddDeviceNotificationReq
The method AdsAddDeviceNotificationReq permits to send an ADS add device notification command, for
adding a device notification to an ADS device. The AdsAddDeviceNotificationCon [} 223] will be called on
arrival of the answer.
Syntax
Parameters
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
indexGroup: (type: ULONG) [in] contains the index group number (32 bit, unsigned) of the requested ADS
service.
indexOffset: (type: ULONG) [in] contains the index offset number (32 bit, unsigned) of the requested ADS
service.
noteAttrib: (type: AdsNotificationAttrib) [in] contains specification of the notification parameters (cbLength,
TransMode, MaxDelay)
Return value
Type: int
13.8.7.2 AdsAddDeviceNotificationInd
The method AdsAddDeviceNotificationInd should enable sending AdsDeviceNotification [} 225]. The
AdsAddDeviceNotificationRes [} 222] has to be called for confirming the operation.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
indexGroup: (Type: ULONG) [in] contains the index group number (32-bit, unsigned) of the requested ADS
service.
indexOffset: (Type: ULONG) [in] contains the index offset number (32-bit, unsigned) of the requested ADS
service.
noteAttrib: (type: AdsNotificationAttrib) [in] contains the specification of the notification parameters
(cbLength, TransMode, MaxDelay).
Return Value
void
13.8.7.3 AdsAddDeviceNotificationRes
The method AdsAddDeviceNotificationRes permits to send an ADS add device notification response. The
AdsAddDeviceNotificationCon [} 223] is the counterpart and will be called afterwards.
Syntax
void AdsAddDeviceNotificationCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG handle );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes
Return Value
void
13.8.7.4 AdsAddDeviceNotificationCon
The method AdsAddDeviceNotificationCon confirms an ADS device addition notification request.
AdsAddDeviceNotificationReq [} 221] forms the counterpart and must be called beforehand.
Syntax
void AdsAddDeviceNotificationCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG handle );
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes.
Return Value
void
13.8.8 AdsDelDeviceNotification
13.8.8.1 AdsDelDeviceNotificationReq
The method AdsDelDeviceNotificationReq permits to send an ADS delete device notification command, for
removing a device notification from an ADS device. The AdsDelDeviceNotificationCon [} 224] will be called
on arrival of the answer.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
hNotification: (type: ULONG) [in] contains the handle of the notification to be removed.
Return value
Type: int
13.8.8.2 AdsDelDeviceNotificationInd
The method AdsAddDeviceNotificationCon permits to receive an ADS delete device notification confirmation.
The receiving module has to provide this method. The AdsDelDeviceNotificationRes [} 224] has to be called
for confirming the operation.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return Value
void
13.8.8.3 AdsDelDeviceNotificationRes
The method AdsAddDeviceNotificationRes permits to receive an ADS delete device notification. The
AdsDelDeviceNotificationCon [} 224] is the counterpart and will be called afterwards.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
nResult: (type: ULONG) [in] contains the result of the ADS command; see AdsStatuscodes [} 344].
Return value
Int
13.8.8.4 AdsDelDeviceNotificationCon
The method AdsAddDeviceNotificationCon enables the reception of an ADS device deletion notification
confirmation. The receiving module must provide this method. AdsDelDeviceNotificationReq [} 223] forms
the counterpart and must be called beforehand.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the transmitted command; the InvokeId is specified by the source
device and serves to identify the commands.
nResult: (type: ULONG) [in] contains the result of the ADS write command; see AdsStatuscodes [} 344].
Return Value
void
13.8.9 AdsDeviceNotification
13.8.9.1 AdsDeviceNotificationReq
The method AdsAddDeviceNotificationReq permits to send an ADS device notification, to inform an ADS
device. The AdsDeviceNotificationInd [} 225] will be called on the counterpart.
Syntax
int AdsDeviceNotificationReq( AmsAddr& rAddr, ULONG invokeId, ULONG cbLength,
AdsNotificationStream notifications[] );
Parameters
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
nResult: (type: ULONG) [in] contains result of the device notification indication.
Return value
Type: int
13.8.9.2 AdsDeviceNotificationInd
The method AdsDeviceNotificationInd enables receiving of information from an ADS device notification
display. The receiving module must provide this method. There is no acknowledgment of receipt.
AdsDeviceNotificationCon [} 226] must be called by AdsDeviceNotificationReq [} 225] to check the transfer.
Syntax
Parameter
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the responding ADS server.
invokeId: (type: ULONG) [in] handle of the command that is sent. The InvokeId is specified by the source
device and is used for the identification of the commands.
pNotifications: (type: AdsNotificationStream*) [in] pointer to the notifications. This array consists of
AdsStampHeader with notification handle and data via AdsNotificationSample.
Return Value
void
13.8.9.3 AdsDeviceNotificationCon
The sender can use the method AdsAddDeviceNotificationCon to check the transfer of an ADS device
notification.
AdsDeviceNotificationReq [} 225] must be called first.
Syntax
void AdsDeviceNotificationCon( AmsAddr& rAddr, ULONG invokeId, ULONG nResult );
Parameters
rAddr: (type: AmsAddr&) [in] structure with NetId and port number of the ADS server.
invokeId: (type: ULONG) [in] handle of the command, which is sent. The InvokeId is specified from the
source device and serves to identify the commands.
nResult: (type: ULONG) [in] contains result of the device notification indication
Return Value
void
Methods provided
Name Description
sqr_ Calculates the square.
sqrt_ Calculates the square root.
sin_ Calculates the sine.
cos_ Calculates the cosine.
tan_ Calculates the tangent.
atan_ Calculates the angle whose tangent is the specified value.
atan2_ Calculates the angle whose tangent is the quotient of two
specified values.
asin_ Calculates the angle whose sine is the specified value.
acos_ Calculates the angle whose cosine is the specified value.
exp_ Calculates e to the specified power.
log_ Calculates the logarithm of a specified value.
log10_ Calculates the base 10 logarithm of a specified value.
fabs_ Calculates the absolute value.
fmod_ Calculates the remainder.
ceil_ Calculates the smallest integer that is greater than or equal to
the specified number.
floor_ Calculates the largest integer that is smaller than or equal to
the specified number.
pow_ Calculates a specified number to the specified power.
sincos_ Calculates the sine and cosine of x.
fmodabs_ Calculates the absolute value that meets the Euclidean
definition of the mod operation.
round_ Calculates a value and rounds to the nearest integer.
round_digits_ Calculates a rounded value with a specified number of
decimal places.
coubic_ Calculates the cubic value.
ldexp_ Calculates a real number (double) from mantissa and
exponent.
ldexpf_ Calculates a real number (float) from mantissa and exponent.
sinh_ Calculates the hyperbolic sine of the specified angle.
cosh_ Calculates the hyperbolic cosine of the specified angle.
tanh_ Calculates the hyperbolic tangent of the specified angle.
finite_ Determines whether the specified value is finite.
isnan_ Determines whether the specified value is not a number
(NAN).
rands_ Calculates a pseudo random number between 0 and 32767.
The parameter holdrand is set randomly and changed with
every call.
Comments
The functions have the extension "_" (underscore), which identifies them as TwinCAT implementation.
Most are analog math.h, designed by Microsoft, only for the data type double.
See also
Methods provided
Name Description
TcDayOfWeek(WORD day, WORD month, WORD year) Determines the day of the week.
Input: day (0..30) and month (1..12)
Return: 0 is Sunday, 6 is Saturday
TcIsLeapYear Determines whether the given year is a leap year.
TcDaysInYear Determines the number of days in a given year.
TcDaysInMonth Determines the number of days in a given month.
TcSystemTimeToFileTime(const SYSTEMTIME* Converts the given system time into a file time.
lpSystemTime, FILETIME *lpFileTime);
TcFileTimeToSystemTime(const FILETIME *lpFileTime, Converts the given file time into a system time.
SYSTEMTIME* lpSystemTime);
TcSystemTimeToFileTime(const SYSTEMTIME* Converts the given system time into a file time
lpSystemTime, ULONGLONG& ul64FileTime); (ULONGLONG format).
TcFileTimeToSystemTime(const ULONGLONG& Converts the given file time (ULONGLONG
ul64FileTime, SYSTEMTIME* lpSystemTime); format) into a system time.
TcIsISO8601TimeFormat(PCCH sDT) Checks whether a PCCH follows the time format
ISO8601.
TcDecodeDateTime(PCCH sDT) Converts a ULONG as DateTime from the PCCH
into ISO8601 format.
TcDecodeDcTime(PCCH sDT) Converts a LONGLONG as DcTime from the
PCCH into ISO8601 format.
TcDecodeFileTime(PCCH sFT) Converts a LONGLONG as FileTime from the
PCCH into ISO8601 format.
TcEncodeDateTime(ULONG value, PCHAR p, UINT len) Converts a string (p, len) into ISO8601 format on
the basis of the ULONG value in DateTime
format.
Minimum length for p is 24 bytes.
TcEncodeDcTime(LONGLONG value, PCHAR p, UINT Converts a string (p, len) into ISO8601 format on
len) the basis of the LONGLONG in DcTime format.
Minimum length for p is 32 bytes.
TcEncodeFileTime(LONGLONG value, PCHAR p, UINT Converts a string (p, len) into ISO8601 format on
len) the basis of the LONGLONG in FileTime format.
Minimum length for p is 32 bytes.
TcDcTimeToFileTime(LONGLONG dcTime) Converts a LONGLONG as FileTime from the
LONGLONG into DcTime.
TcFileTimeToDcTime(LONGLONG fileTime); Converts a LONGLONG as DcTime from the
LONGLONG into FileTime.
TcDcTimeToDateTime(LONGLONG dcTime) Converts a ULONG as DateTime from the
LONGLONG into DcTime.
TcDateTimeToDcTime(ULONG dateTime) Converts a ULONG as DcTime from the
LONGLONG into DateTime.
TcFileTimeToDateTime(LONGLONG fileTime) Converts a ULONG as DateTime from the
LONGLONG into FileTime.
TcDateTimeToFileTime(ULONG dateTime) Converts a LONGLONG as FileTime from the
ULONG into DateTime.
Restrictions
• Class templates do not exist for all data types.
• Some header files should not be used directly.
More detailed documentation on memory management, which uses STL, can be found here [} 171].
Therefore, you should examine the method "SetObjStateSP()", which is responsible for this transition, in
more detail. In the case of the generated standard code, you can see that the addition of the module takes
place there.
The reason for this error is that no task has been assigned to this module, so the module cannot have a task
in which it is executed.
TwinCAT 3 C++ offers the option of sending messages from a C++ module to the TwinCAT 3 Engineering as
tracing or logging.
Syntax
Level 0 tlAlways
Level 1 tlError
Level 2 tlWarning
Level 3 tlInfo
Level 4 tlVerbose
• FNMACRO can be used to place the function name before the message to be printed
◦ FENTERA: Used when entering a function; prints the function name followed by ">>>".
◦ FNAMEA: Used within a function; prints the function name.
◦ FLEAVEA: Used when exiting a function; prints the function name followed by "<<<".
• The %q format specifier is used to output pointers and other variables of platform-specific size.
Sample
HRESULT CModule1::CycleUpdate(ITcTask* ipTask, ITcUnknown* ipCaller, ULONG_PTR context)
{
HRESULT hr = S_OK;
if (cnt%510 == 0)
m_Trace.Log(tlError, FENTERA "Level tlError: cycle=%llu", cnt);
if (cnt%520 == 0)
m_Trace.Log(tlWarning, FENTERA "Level tlWarning: cycle=%lld", cnt);
if (cnt%530 == 0)
m_Trace.Log(tlInfo, FENTERA "Level tlInfo: cycle=%llu", cnt);
if (cnt%540 == 0)
m_Trace.Log(tlVerbose, FENTERA "Level tlVerbose: cycle=%llu", cnt);
}
return hr;
}
The tracking level can be preconfigured at the level of the module instance.
1. Navigate to the instance of the module in the solution tree.
2. Select the Parameters (Init) tab on the right.
3. Make sure that you activate Show Hidden Parameters.
4. Select the tracking level.
Alternatively, you can change the tracking level at runtime by going to the instance, selecting a level at Value
for TraceLevelMax parameters, right-clicking in front of the first column, and selecting Online Write.
Visual Studio Error List allows you to filter entries by category. The three categories Errors, Warnings and
Messages can be enabled or disabled independently by simply switching the keys.
In this screenshot only warnings are enabled - errors and messages are disabled:
In this screenshot, only messages are enabled - errors and warnings, on the other hand, are disabled for
the display:
14 How to...?
This is a collection of frequently ask questions about common paradigms of coding as well as handling of
TwinCAT C++ modules.
This includes creating projects [} 103] and using the wizard for creating module classes [} 104].
In addition, the project properties can be set and the TMC Code Generator and the publishing of modules
called. The corresponding documentation [} 351] is part of the Automation Interface.
Irrespective of the programming language, access to and creation and handling of TcCOM modules [} 355]
may be relevant.
From there, common System Manager tasks such as linking of variables can be executed.
Up to TwinCAT 3.1 Build 4022.2, the Rename Destination option must be enabled for this purpose in the
TMC Editor deployment [} 148]. In later versions this is done implicitly when the target system uses Windows
10 as operating system.
The engineering system (XAE) does not necessarily have to be on the same platform type as the executing
system. To this end, TwinCAT creates all versions of the module in the course of the publication.
Migration
If a build is not contained in the published module, the corresponding platform cannot be used as an
executing system.
Add the corresponding target platforms in the provision [} 148] of the TMC Editor or remove them.
The following provision configuration, for example, only makes the TwinCAT RT (x86) build available:
The CppProject.vcxproj parameter must be adapted according to the existing project file.
14.5 Clone
The runtime data can be transferred from one machine to another by means of a file copy if both originate
from the same platform and are connected with equivalent hardware equipment.
The following steps describe a simple procedure to transfer a binary configuration from one machine,
"source", to another, "destination".
Handling licenses
Note that licenses cannot be transferred in this manner. Please use pre-installed licenses, volume
licenses or other mechanisms for providing licenses.
The name of the variable for access by ADS is derived from the name of the instance.
It is configured under Sort Order in the context [} 152] of the TwinCAT Module Instance Configurator [} 150].
These are accessible, for example, via the Details tab of each properties file.
TwinCAT offers this behavior via the familiar Windows mechanisms of .rc files, which are generated in the
course of creating the TwinCAT C++ project.
Edit the .rc file in the Source Files folder with the resource editor in order to define these properties:
In summary, one can say that the C++ project will be renamed together with the corresponding files.
ü A project, "OldProject", exists and is to be renamed "NewProject".
1. If TcCOM instances exist in the project and are to be retained along with their links, first move them by
drag & drop out of the project into System->TcCOM Objects.
2. Remove the old project from the TwinCAT Solution using Remove.
3. Compilations of the "OldProject" can be deleted. To do this, delete the corresponding .sys/.pdb files in
"_Deployment".
Any existing .aps file can also be deleted.
4. Rename the C++ project directory and the project files (.vcxproj, .vcxproj.filters).
If version management is in use, this renaming must be carried out via the version management system.
5. If a .vcvproj.user file exists, check the contents; this is where user settings are stored. Also rename this
file if necessary.
6. Open the TwinCAT Solution. Re-link the renamed project to the C++ node using Add existing Item:
navigate to the renamed subdirectory and select the .vcxproj file there.
7. Rename the ClassFactory, services and interfaces as well as header/source code files to the new project
name. In addition, rename the TMC file and the corresponding files in the project folders "TwinCAT RT
Files" and "TwinCAT UM Files".
This renaming should also be mapped in the version management system; if the version management
system is not integrated in Visual Studio, this step must also be carried out in the version management
system. Replace all occurrences in the source code (case-sensitive):
"OLDPROJECT" becomes "NEWPROJECT" and "OldProject" becomes "NewProject".
Use the Find and Replace dialog in Visual Studio for this; note that the "NewProject Project" in the
Solution Explorer has to be selected.
NOTE
Incorrect source code
The simple renaming of all occurrences of the character string may result in incorrect source code, for ex-
ample if the project name is used within a method name.
• If such occurrences are possible, carry out the renaming individually (Replace instead of Replace All).
B) Alternatively, carry this out via System->TcCOM Objects and the Project Objects tab by right-
clicking on the OTCID.
2. Move System->TcCOM into the project.
3. Clean up the target system(s).
Delete the files "OldProject.sys/.pdb" in C:\TwinCAT\3.x\Driver\AutoInstall.
4. Test the project.
4. Note that the .cpp and .h files are retained – delete them manually if necessary.
Delete other components concerned (e.g. header files, structures). See Compiler error messages for
more information.
These steps are described on the subpages. However, it may be useful to create a new project yourself and
transfer the corresponding differences. Thus, the respective context is visible.
6. This file only needs to be built for TwinCAT UM platforms, so it should otherwise be excluded for the
build process. This is done via right-click and properties:
#ifdef _DEBUG
12. Add Modul1.cpp to the source code:
END_INTERFACE_MAP()
IMPLEMENT_IPERSIST_LIB(CModule1, VID_Untitled1,
CID_Untitled1CModule1)
IMPLEMENT_ITCOMOBJECT(CModule1)
IMPLEMENT_ITCOMOBJECT_SETSTATE_LOCKOP2(CModule1)
13. Call the code generator.
15. Change the signing in the project properties in the tab Tc Sign [} 165]. To do this, switch SHA1 signing
off and TwinCAT signing on; provide TwinCAT user certificate and password at the same time.
If a module is to be made Online Change capable, this can be achieved by the following instructions [} 244].
3. Under Implemented Interfaces, delete the interfaces ITcADI and ITcWatchsource and add
ITComOnlineChange.
You create the following parameters with the given names, in each case without code generation:
"PID_LibraryID" with the name "LibraryID"
"PID_ModuleClsId" with the name "ModuleClsId"
"PID_Ctx_TaskSortOrders with the name "SortOrders"
"PID_Ctx_TaskOids" with the name "Contexts"
"IOFFS_TcIoDataAreaSize" with the name "DataAreas"
7. Some changes must be made in the header of the module "Module1.h". First, delete the declarations of
the interfaces that are no longer required and the corresponding maps in two places.
class CModule1
: public ITComObject
, publicITcADI
, publicITcWatchSource
///<AutoGeneratedContent id="InheritanceList">
, public ITcCyclic
///</AutoGeneratedContent>
{
public:
DECLARE_IUNKNOWN()
DECLARE_IPERSIST(CID_Untitled1CModule1)
DECLARE_ITCOMOBJECT_LOCKOP()
DECLARE_ITCADI()
DECLARE_ITCWATCHSOURCE()
DECLARE_OBJPARAWATCH_MAP()
DECLARE_OBJDATAAREA_MAP()
8. Create a new member variable in the header:
///</AutoGeneratedContent>
ITcADIPtr m_spADI;
// TODO: Custom variable
9. Some changes need to be made to the source code of the module "Module1.cpp". First, delete the
implementations of the interfaces that are no longer required in two places.
BEGIN_INTERFACE_MAP(CModule1)
INTERFACE_ENTRY_ITCOMOBJECT()
INTERFACE_ENTRY(IID_ITcADI, ITcADI)
INTERFACE_ENTRY(IID_ITcWatchSource, ITcWatchSource)
///<AutoGeneratedContent id="InterfaceMap">
INTERFACE_ENTRY(IID_ITcCyclic, ITcCyclic)
///</AutoGeneratedContent>
END_INTERFACE_MAP()
IMPLEMENT_ITCOMOBJECT(CModule1)
IMPLEMENT_ITCOMOBJECT_SETSTATE_LOCKOP2(CModule1)
IMPLEMENT_ITCADI(CModule1)
IMPLEMENT_ITCWATCHSOURCE(CModule1)
10. Delete the implementation of the maps belonging to the deleted interfaces:
BEGIN_SETOBJPARA_MAP(CModule1)
SETOBJPARA_DATAAREA_MAP()
///<AutoGeneratedContent id="SetObjectParameterMap">
SETOBJPARA_VALUE(PID_TcTraceLevel, m_TraceLevelMax)
SETOBJPARA_VALUE(PID_Module1Parameter, m_Parameter)
SETOBJPARA_ITFPTR(PID_Ctx_TaskOid, m_spCyclicCaller)
///</AutoGeneratedContent>
END_SETOBJPARA_MAP()
///////////////////////////////////////////////////////////////////////////////
// Get parameters of CModule1
BEGIN_GETOBJPARA_MAP(CModule1)
GETOBJPARA_DATAAREA_MAP()
///<AutoGeneratedContent id="GetObjectParameterMap">
GETOBJPARA_VALUE(PID_TcTraceLevel, m_TraceLevelMax)
GETOBJPARA_VALUE(PID_Module1Parameter, m_Parameter)
GETOBJPARA_ITFPTR(PID_Ctx_TaskOid, m_spCyclicCaller)
///</AutoGeneratedContent>
END_GETOBJPARA_MAP()
///////////////////////////////////////////////////////////////////////////////
// Get watch entries of CModule1
BEGIN_OBJPARAWATCH_MAP(CModule1)
OBJPARAWATCH_DATAAREA_MAP()
///<AutoGeneratedContent id="ObjectParameterWatchMap">
///</AutoGeneratedContent>
END_OBJPARAWATCH_MAP()
///////////////////////////////////////////////////////////////////////////////
11. The m_spAPI pointer must be obtained in the transition P->S in the state machine:
HRESULT CModule1::SetObjStatePS(PTComInitDataHdr pInitData)
{
m_Trace.Log(tlVerbose, FENTERA);
HRESULT hr = S_OK;
IMPLEMENT_ITCOMOBJECT_EVALUATE_INITDATA(pInitData);
// query TcCOM object server for ITcADI interface with own object id,
// which retrieves a reference to the TMC module instance handler
m_spADI.SetOID(m_objId);
hr = FAILED(hr) ? hr : m_spSrv->TcQuerySmartObjectInterface(m_spADI);
// TODO: Add initialization code
12. Add the following in the state machine in the transition S->O, the calls to AddModuleToCaller or
RemoveModuleFromCaller are omitted.
HRESULT hr = S_OK;
// Retrieve pointer to data areas via ITcADI interface from TMC module handler
///<AutoGeneratedContent id="DataAreaPointerInitialization">
///</AutoGeneratedContent>
// TODO: Add any additional initialization
// Cleanup if transition failed at some stage
if ( FAILED(hr) )
{
SetObjStateOS();
}
13. Add the following in the state machine in the transition O->S, the call RemoveModuleFromCaller is
omitted:
HRESULT hr = S_OK;
// Release pointer to data areas via ITcADI interface from TMC module handler
///<AutoGeneratedContent id="DataAreaPointerRelease">
///</AutoGeneratedContent>
// TODO: Add any additional deinitialization
14. The AddModuleToCaller and RemoveModuleFromCaller methods are not required and can be deleted.
15. Change the accesses to the DataAreas:
HRESULT CModule1::CycleUpdate(ITcTask* ipTask, ITcUnknown* ipCaller, ULONG_PTR context)
{
HRESULT hr = S_OK;
// TODO: Replace the sample with your cyclic code
m_Counter+=m_pInputs->Value;
m_pOutputs->Value=m_Counter;
return hr;
}
16. Implement the ITcOnlineChange. The functions are created by the previous code generation, but must
not return NOTIMPL.
///<AutoGeneratedContent id="ImplementationOf_ITComOnlineChange">
///////////////////////////////////////////////////////////////////////////////
// PrepareOnlineChange is called after this instance has been set to PREOP in non RT context.
// Parameter ipOldObj refers to the currently active instance which is still in OP.
// Retrieve parameter values that are not changed during OP via ipOldObj here.
//
// Parameter pOldInfo refers to instance data which includes the libraryId and
// the module class id. This information can be used to implement switch from one
// specific version to another.
HRESULT CModule1::PrepareOnlineChange(ITComObject* ipOldObj, TmcInstData* pOldInfo)
{
HRESULT hr = S_OK;
The projects generated with the TwinCAT C++ Wizard prior to TwinCAT 3.1 Build 4018 do not use this
property, but can easily be adapted by inserting this line in the corresponding code (e.g. Constructor):
///<AutoGeneratedContent id="MemberInitialization">
Such a method can be called by means of implementing a method within the wrapper function block.
The reason is the different handling of method parameters in the two worlds:
• PLC: Uses the call by value for STRING(nn) data types.
• TwinCAT C++ (TMC): Uses the call by reference.
The connection of the TwinCAT 3 real-time environment can be realized via ADS communication instead.
You can implement a User-mode application that makes use of the third-party library that provides TwinCAT
functions via ADS.
This action of an ADS component in User mode can take place both as a client (i.e. the DLL transmits data
to the TwinCAT real-time if necessary) and as a server (i.e. the TwinCAT real-time fetches data from the
User mode if necessary).
Such an ADS component in User mode can also be used in the same way from the PLC. In addition, ADS
can communicate beyond device limits.
15 Troubleshooting
This is a list of pitfalls and glitches within the handling of TwinCAT C++ modules.
If this error message appears, carry out a check according to the WinDDK installation manual [} 22]:
• Make sure that WinDDK is installed.
• The environment variable WinDDK7 and its configured value must exist; see the description in the
above-mentioned document. The value must correspond to the path where WinDDK is installed,
including the first subfolder. Restart the computer after changing this value.
15.2 Build - "The target ... does not exist in the project"
In particular when transferring a TwinCAT solution from one machine to another, Visual Studio may display
error messages to the effect that not all targets (such as Build, Rebuild, Clean) exist in the project.
Check the configuration of the "platform toolset" of the C++ project. It may need to be reconfigured if
solutions migrate from one Visual Studio version to another:
In this case, navigate to System -> Real-Time, select the C++ Debugger tab and activate the option Enable
C++ Debugger.
LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or
corrupt
indicates that a Visual Studio 2010 is being used, but without Service Pack 1, which is required [} 20] for
TwinCAT C++ modules.
Download the installation program for the service pack from Microsoft.
Insert the following lines at the start of your generated class file:
#include "TcPch.h"
#pragma hdrstop
16 C++-samples
16.1 Overview
Numerous samples are available – further samples follow.
This picture provides an overview in graphical form and places the emphasis on the interaction possibilities
of a C++ module.
13 Sample13: Module communication: C- • Describes how a TwinCAT C++ module calls a PLC
module calls PLC methods [} 309] function block using TcCOM interface methods.
19 Sample19: Synchronous File Access Describes how the File IO function can be used in a
[} 312] synchronized manner with C++ modules.
The sample writes process values in a file. The writing of
the file is triggered by a deterministic cycle - the
execution of File IO is decoupled (asynchronous), i.e.:
the deterministic cycle continues to run and is not
hindered by writing to the file. The status of the routine
for decoupled writing to the file can be checked.
20 Sample20: FileIO-Write [} 313] Describes how the File IO function can be used with C++
modules.
The sample writes process values in a file. The writing of
the file is triggered by a deterministic cycle - the
execution of File IO is decoupled (asynchronous), i.e.:
the deterministic cycle continues to run and is not
hindered by writing to the file. The status of the routine
for decoupled writing to the file can be checked.
20a Sample20a: FileIO-Cyclic Read / Write A more extensive sample than S20 and S19. It describes
[} 313] the cyclic read and/or write access to files from a TC3 C+
+ module.
22 Sample22: Automation Device Driver Describes how the TwinCAT Automation Device Driver
(ADD): Access DPRAM [} 314] (ADD) is to be written for access to the DPRAM.
25 Sample25: Static Library [} 318] Describes how to use the TC3 C++ static library
contained in another TC3 C++ module.
26 Sample26: Order of execution in a Describes the determination of the task execution order,
task [} 319] if a task is assigned to more than one module.
27 Sample27: Using the JobTask Describes the use of a JobTask by means of four
variants.
30 Sample30: Timing Measurement Describes the measurement of the TC3 C++ cycle or
[} 321] execution time.
31 Sample31: Functionblock TON in Describes the implementation of a behavior in C++,
TwinCAT3 C++ [} 322] which is comparable to a TON function block of PLC /
61131.
37 Sample37: Archive data [} 324] Describes the loading and saving of the state of an object
during the initialization and de-initialization.
TcCOM TcCOM samples [} 325] Several samples are provided to illustrate the module
communication between PLC and C++.
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
This sample describes the quick start for the purpose of creating a C++ module that increments a counter on
each cycle and assigns the counter to the logical output Value in the data area.
The data area can be assigned to the physical IO or another logical input or another module instance.
The sample is described step by step here [} 60] in the short instructions.
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Source code, which is not automatically generated by the wizard, is identified with a start flag "//sample
code" and end flag "//sample code end".
In this way you can search for these strings in the files, in order to get an idea of the details.
Description
This sample describes the flexibility of C++ code when working with IOs configured at the task. This
approach enables a compiled C++ module to respond more flexibly, if a different number of IOs are linked to
the IO task. One application option would be cyclic testing of analog input channels with a different number
of channels, depending on the project.
The C++ code accesses the values via a data image, which is initialized during the transition from SAFEOP
to OP (SO).
In the cyclically executed method CycleUpdate the value of each input variable is checked by calling the
helper method CheckValue. If it is less than 0, the corresponding output variable is set to 1, if it is greater
than 0, it is set to 2, if it is 0, the output is set to 3.
After activation of the configuration you can access the variables via the Solution Explorer and set them.
Double-click on the Task1 image of system for an overview.
The input variables can be opened and then set with the Online tab.
• The creation of a C# ADS client to interact with the C++ ADS server.
The client provides a UI for connection locally or via a network to an ADS server with the ADS interface
to be counted. The UI enables the starting / stopping / reading / overwriting and resetting of the
counter.
Sample code: ADS Client UI written in C# [} 265].
Options for the automatic determination of an ADS port are used in the sample. The disadvantage of this is
that the client has to be configured at each start in order to access the correct ADS port.
Alternatively, the ADS port can be hard-coded in the module as shown below.
Disadvantage here: The C++ module cannot be instanced more than once as it is not possible to share an
ADS port.
Download
Here you can access the source code for this sample:
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
This sample contains a C++ module that acts as an ADS server. The server grants access to a counter that
can be started, stopped and read.
The header file of the module defines the counter variable m_bCount, and the corresponding .cpp file
initializes the value in the constructor and implements the logic in the CycleUpdate method.
The AdsReadWriteInd method in the .cpp file analyzes the incoming messages and returns the return
values. A define in the header file is added for a further added message type.
Details such as the definition of the ADS message types are described in the following cookbook, where you
can compile the sample manually.
Cookbook
This is a step by step description about the creation of the C++ module.
Follow the steps for the creation of a new TwinCAT 3 C++ project [} 62].
Select TwinCAT Module Class with ADS port in the Class templates dialog.
Usually, the ADS server receives an ADS message, which contains two parameters (indexGroup and
indexOffset) and perhaps further data pData.
These parameters are defined in modules1Ads.h – change the source code to add a new command for
IG_RESET.
#include "TcDef.h"
enum Module1IndexGroups : ULONG
{
Module1IndexGroup1 = 0x00000001,
Module1IndexGroup2 = 0x00000002, // add command
IG_OVERWRITE = 0x00000003 // and new command
};
Change the source code in your <MyClass>::AdsReadWriteInd() method (in this case in Module1.cpp).
switch(indexGroup)
{
case Module1IndexGroup1:
switch(indexOffset)
{
case Module1IndexOffset1:
...
// TODO: add custom code here
m_bCount = TRUE; // receivedIG=1 IO=1, start counter
AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, 0,NULL);
break;
case Module1IndexOffset2:
...
// TODO: add custom code here
// map counter to data pointer
pData = &m_Counter; // received IG=1 IO=2, provide counter value via ADS
AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, 4 ,pData);
//comment this: AdsReadWriteRes(rAddr, invokeId,ADSERR_NOERR, 0, NULL);
break;
}
break;
case Module1IndexGroup2:
switch(indexOffset)
{
case Module1IndexOffset1:
...
// TODO: add custom code here
// Stop incrementing counter
m_bCount = FALSE;
// map counter to data pointer
pData = &m_Counter;
AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, 4,pData);
break;
case Module1IndexOffset2:
...
// TODO: add custom code here
// Reset counter
m_Counter = 0;
// map counter to data pointer
pData = &m_Counter;
AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, 4, pData);
break;
}
break;
case IG_OVERWRITE:
switch(indexOffset)
{
case Module1IndexOffset1:
...
// TODO: add custom code here // override counter with value provided by ADS-client
unsigned long *pCounter = (unsigned long*) pData;
m_Counter = *pCounter;
AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, 4, pData);
break;
}
break;
}
break;
default:
__super::AdsReadWriteInd(rAddr, invokeId, indexGroup,indexOffset, cbReadLength, cbWriteLength,
pData;
break;
}
The method <MyClass>::CycleUpdate() is cyclically called - this is the place to modify the logic.
// TODO: Replace the sample with your cyclic code
m_Counter+=m_Inputs.Value; // replace this line
m_Outputs.Value=m_Counter;
In this case the counter mCounter is incremented if the boolean variable m_bCount is true.
In this sample the default setting (keep flexible) is selected. First of all you have to determine the ADS port
that was assigned to the module that has just been activated.
1. Navigate to the module instance.
2. Select the Parameter Online tab.
ð 0x8235 or decimal 33333 is assigned to the ADS port (this may be different in your sample). If more
and more instances are created, each instance is allocated its own unique AdsPort.
ð The counter is still at "0" because the ADS message to start the incrementation has not been sent.
ð The server part is completed - continue with ADS client sends the ADS messages [} 265].
The implementation of the ADS server depends neither on the language (C++ / C# / PLC / ...) nor on the
TwinCAT version (TwinCAT 2 or TwinCAT 3).
Download
Here you can access the source code for this sample.
ü This code requires .NET Framework 3.5 or higher!
1. Unpack the downloaded ZIP file.
2. Open the sln file contained in it with Visual Studio.
3. Create the sample on your local machine (right-click on the project and click on Build).
4. Start the program with a right-click on Project, Debug->Start new instance.
Description
Enter both ADS parameters in order to specify your ADS communication partner:
• NetID:
127.0.0.1.1.1 (for ADS partner also linked with local ADS Message Router)
Enter another NetID, if you want to communicate with an ADS partner connected to another ADS
router via the network.
First you have to create an ADS route between your device and the remote device.
• AdsPort
Enter the AdsServerPort of your communication partner.
Do not confuse the ADS server port (which has explicitly implemented your own message handler) with
the regular ADS port for the purpose of access to symbols (this is provided automatically, without the
need for user intervention).
Find the assigned AdsPort [} 261], in this sample the AdsPort was 0x8235 (dec 33333).
Click on Connect to call the method TcAdsClient.Connect for the purpose of creating a link with the
configured port.
ADS messages are sent to the ADS server with the help of the Start / Read / Stop / Overwrite / Reset
buttons.
The specific indexGroup / indexOffset commands were already designed in the ADS interface of the ADS
server [} 261].
The result of clicking on the command buttons can also be seen in the module instance in the Parameters
(online) tab.
C# program
Here is the "Core" code of the ADS client – download for the GUI or ZIP file above.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using TwinCAT.Ads;
namespace adsClientVisu
{
public partial class form : Form
{
public form()
{
InitializeComponent();
}
}
/*
* Connect the client to the local AMS router
*/
try
{
_tcClient.Connect(serverAddress.NetId, serverAddress.Port);
lbOutput.Items.Add("Client port " + _tcClient.ClientPort + " opened");
}
catch
{
MessageBox.Show("Could not connect client");
}
}
try
{
_tcClient.ReadWrite(0x2, 0x2, adsReadStream, adsWriteStream);
byte[] dataBuffer = adsReadStream.ToArray();
lbOutput.Items.Add("Counter reset Value = " + BitConverter.ToInt32(dataBuffer, 0));
}
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
5. Note the actions listed on this page under Configuration.
Description
This sample describes access to an EtherCAT Terminal, which reads the manufacturer ID and specifies the
baud rate for serial communication.
This sample describes the quick start for the purpose of creating a C++ module that increments a counter on
each cycle and assigns the counter to the logical output Value in the data area.
Configuration
1. Activate the EtherCAT address of the terminal concerned and assign it.
2. Activate inclusion of the ADS address in the advanced settings for the EtherCAT Terminal:
3. Assign the ADS address (including netId and port) to the module input AdsAdress:
4. The module parameters are read out and displayed by the sample code during the course of the
initialization:
Download
The client sample should be used with example 03 "C++ as ADS server".
Open Sample 03 [} 261] before you begin with this client-side sample!
Description
The possibilities of the ADS are described on the basis of this sample.
The details of the implementation are described in Form1.cs, which is included in the download. The
connection via ADS with the target system is established in the btnLoad_Click method, which is called on
clicking on the Load Symbols button. From there you can explore the different GUI functions.
Background information:
For this ADS client it is irrelevant whether the ADS server is based on TwinCAT 2 or TwinCAT 3. It also
doesn't matter if the server is a C++ module, a PLC module or an IO task without any logic.
After starting the client, enter the two ADS parameters, in order to determine your ADS communication
partner.
• NetID:
127.0.0.1.1.1 (for ADS partner also linked with local ADS message router).
Enter another NetID, if you want to communicate with an ADS partner connected to another ADS
router via the network.
First you have to create an ADS route between your device and the remote device.
• AdsPort
Enter the AdsPort of your communication partner: 350 (in this sample).
Do not confuse the ADS server port with the regular ADS port.
Do not confuse the ADS server port (which was explicitly implemented in sample 03 for providing
your own message handler) with the regular ADS port for the purpose of access to symbols (this is
provided automatically, without the need for user intervention):
The regular ADS port is required to access symbols. You can find the AdsPort for the IO task of
your instance or the module instance yourself (since the module is executed in the context of the IO
task).
Navigate to IO task Task1 and note the value of the port: 350.
Since the C++ module instance is executed in the context of Task1, the ADS port is also 350.
Individual symbols or whole data areas can be provided for access via ADS, or they can be deliberately not
provided.
Navigate to the Data Area tab of your instance and activate/deactivate the C/S column.
In this sample all symbols are marked and therefore available for ADS access.
Load symbols
Once the NetID and the ADS port have been set up, click on the Load Symbols button to make a
connection with the target system and load the symbols.
After writing a new value with Write using WriteSymbol, the C# application is assigned a callback
with the new value.
Download
Here you can access the source code for this sample:
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
This sample describes the reception of ADS notifications in a TwinCAT C++ module.
The address is prepared during the module transition PREOP->SAFEOP (SetObjStatePS). The CycleUpdate
method contains a simple state machine, which sends the required ADS command. Corresponding methods
show the receipts.
The inherited and overloaded method AdsDeviceNotificationInd is called when a notification is received.
During shutdown, ADS messages are sent during transition for the purpose of logoff (SetObjStateOS), and
the module waits for receipts of confirmation until a timeout occurs.
See also
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
Four methods with different signatures are provided and called. These are organized in two interfaces, so
that the composition of the ADS symbol names of the methods becomes clear.
The sample consists of the TwinCAT C++ module, which offers the RPC methods and a C++ sample
program that calls them.
The TwinCAT C++ project contains a module and an instance of the module with the name "foobar".
RPC methods are normal methods that are described by interfaces in the TMC editor and are additionally
enabled by an RPC enable checkbox. The options are described in greater detail in the Description of the
TMC Editor [} 107].
In this module two interfaces are described and implemented, as can be seen in the TMC Editor:
The methods, four in all, have different signatures of call and return values.
As can be seen in the C++ code itself, the methods are generated by the code generator and implemented
like normal methods of a TcCOM module.
If the type information of the methods is to be available on the target system, the TMI file of the module can
be transferred to the target system.
The TwinCAT OPC-UA server offers the option to call these methods also by OPC-UA – the TMI files are
required on the target system for this.
Directly after starting, the C++ client will fetch the handles and then call the methods any number of times;
however a [RETURN] is expected between the procedures. Every other key leads to the enabling of the
handle and the termination of the program.
The outputs illustrate the calls:
Download
Here you can access the source code for this sample:
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
This communication is based on a "split" data area: Provided by a module and accessible from another
module via pointers.
It is not possible that two different data pointers are linked with the same entry in an output or input data
area; without this limitation there could be synchronization problems. For this reason a ModuleDataProvider
module consolidates input and output in a standard data area, which is not subject to this restriction.
• ModuleDataAccessA accesses the data area of ModuleDataProvider and cyclically processes Bit1 /
BitOut1 and the integer.
• ModuleDataAccessB accesses the data area of ModuleDataProvider and cyclically processes Bit2 /
BitOut2 and the integer.
The user of the sample triggers ModuleDataInOut by setting the variables ValueIn / Bit1 / Bit2:
• When setting the input Bit1, the output Switch1 will be set accordingly.
• When setting the input Bit2, the output Switch2 will be set accordingly.
• When the input ValueIn is set, the output ValueOut is incremented twice in each cycle.
All modules are configured such that they have the same task context, which is necessary since access via
pointers offers no synchronization mechanism. The order of execution corresponds to the order specified on
the context configuration tab. This value is passed on as parameter SortOrder and stored in the smart
pointer of the cyclic caller (m_spCyclicCaller), which also contains the object ID of the cyclic caller.
The module ModuleDataInOut has input and output variables. They are linked with the corresponding
variables of the data provider.
The module ModuleDataProvider provides an input and output data array and implements the ITcIoCylic
interface. The method InputUpdate copies data from the input variables to the DataIn symbol of the standard
data area Data, and the method OutputUpdate copies data from the DataOut symbol to the output variables.
The modules ModuleDataAccessA and ModuleDataAccessB contain pointers to data areas of the data
provider via links. These pointers are initialized during the transition from SAFEOP to OP.
ModuleDataAccessA cyclically sets BitOut1 according to Bit1. ModuleDataAccessB accordingly, with
BitOut2 / Bit2. Both increment ValueOut through multiplication of the internal counter with the value ValueIn.
It is important that all modules are executed in the same context, since there is no synchronization
mechanism via data pointers. The order of execution is defined by the Sort Order on the Context tab of the
respective module. This is provided as parameter SortOrder in the SmartPointer (m_SpCyclicCaller), which
also includes the ObjectID.
• of a PLC module [} 296] for calling the function of the C++ module.
The fact that no hard-coded link exists between the PLC and the C++ module is a great advantage.
Instead, the called C++ instance can be configured in the system manager.
Follow this step-by-step introduction with regard to the implementation of a PLC project that calls
methods from a C++ module.
Download
The idea is to create a simple state machine in C++ that can be started and stopped from the outside by
other modules, but which also allows the setting or reading of the particular state of the C++ state machine.
Two further articles use the result from this C++ state machine.
• Calling the function from the PLC logic [} 280] - i.e. affecting the C++ code from the PLC.
• Calling the function from the C++ logic [} 308] - i.e. interaction between two C++ modules.
2. Select the template TwinCAT Driver Project and enter a driver name, "StateMachineDrv" in this sample.
Click on Add to continue.
3. Select a template to be used for this new driver. In this sample "TwinCAT Module Class with Cyclic IO" is
selected, since the internal counter of the state machine is available for assigning to the IO.
4. Click on Add to continue.
5. Specify a name for the new class in the C++ driver "StateMachineDrv".
The names of the module class and the header and source files are derived from the specified "Short
Name".
6. Click on OK to continue.
ð The wizard then creates a C++ project, which can be compiled error-free.
NOTE
Name conflict
A name collision can occur if the driver is used in combination with a PLC module.
Do not use any of the keywords that are reserved for the PLC as names.
2. Replace the default name Method1 by a more meaningful name, in this sample "Start".
5. Subsequently, you can add parameters by clicking on Add a new parameter or edit parameters of the
SetState method.
ð You then obtain a list of all methods. You can change the order of the methods with the
buttons.
3. All available interfaces are listed - select the new interface IStateMachine and end with OK.
The C++ module instance is cyclically called, even if the internal state machine is in Stop mode.
• If the state machine is not to be executed, the m_bRun Flag signals that the code execution of the
internal state machine is to be quit.
• If the state is "1" the counter must be incremented.
• If the state is "2" the counter must be decremented.
• The resulting counter value is assigned to Value, which is a member variable of the logical output of
the data area. This can be assigned to the physical IO level or to other data areas of other modules at
a later time.
2. Repeat the compilation and optimize your code until the result looks like this:
2. Select the module that is to be added as a new instance – in this case CStateMachineModule.
Option 1:
1. Navigate to the C++ module instance.
2. Select the Interfaces tab.
ð The IStateMachine interface is in the list with its specific IID (Interface ID).
Option 2:
1. Navigate to System.
2. Select the Interfaces tab.
ð The IStateMachine interface is in the list with its specific IID (Interface ID).
The lower section shows the stored code in different programming languages.
Step 3: add a function block (FB) (which serves as the proxy for calling the C++ module methods)
1. Right-click on POUs.
2. Select Add->POU....
3. Define a new FB to be created, which will later act as a proxy for calling C++ classes: Enter the name of
the new FB: "FB_StateMachine".
4. Select Function Block, then Implements and then click on the ... button.
5. Select the interface either via the Text Search tab or the Categories tab by deselecting Structured
View.
As a result of creating an FB that implements the IStateMachine interface, the wizard will create an FB with
corresponding methods.
2. Add the methods FB_exit and FB_init - both with Structured Text (ST) as the implementation language.
They are available as predefined name.
NOTE
Missing attributes lead to unexpected behavior
Attribute statements in brackets represent code to be added.
2. Implement the variable declarations and the code area of the method FB_exit.
3. Implement the variable declarations and the code area of the method FB_init.
4. Implement the variable declaration and the code area of the method GetState (the generated pragmas
can be deleted as they are not required for a proxy FB).
5. Implement the variable declaration and the code area of the method SetState (the generated pragmas
can be deleted as they are not required for a proxy FB).
6. Implement the variable declaration and the code area of the method Start
(the generated pragmas can be deleted as they are not required for a proxy FB).
7. Implement the variable declaration and the code area of the method Stop
(the generated pragmas can be deleted as they are not required for a proxy FB).
ð The implementation of the FB_StateMachine, which acts as the proxy for calling the C++ module
instance, is completed.
The PLC FB FB_StateMachine can be configured with regard to linking with every instance of the C++
module StateMachine. This is a very flexible and powerful method of connecting PLC and C++ modules on
the machine with each other.
1. Navigate to the instance of the PLC module in the left-hand tree and select the Symbol Initialization tab
on the right-hand side.
ð All instances of FB_StateMachine are listed; in this sample we have only defined one FB instance in
POU MAIN.
2. Select the drop-down field Value and then the C++ module instance that is to be linked to the FB
instance.
Step 10: observe the execution of the two modules, PLC and C++
Following the activation of the TwinCAT configuration and the downloading and starting of the PLC code, the
execution of the two codes, PLC and C++, is simple to observe:
1. After the Login and Start of the PLC project, the editor is already in online mode (left-hand side – see
following illustration).
2. In order to be able to access online variables of the C++ module, activate the C++ debugging [} 88] and
follow the steps in the quick start [} 60] in order to start the debugging (right-hand side of the following
illustration).
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The read/write instances are configured for access to the DataProvider instance, which can be seen in the
Interface Pointer menu on the instance configuration.
The context (task), in which the instances are to be executed, can also be configured there. In this sample
two tasks are used, TaskRead and TaskWrite.
The DataWriteCounterModul parameters of CModuleDataWrite and DataReadCounterModulo
(CModuleDataRead) enable the moment to be determined, at which the module instances initiate the
access.
CriticalSections are described in the SDK in TcRtInterfaces.h and are therefore intended for the real-time
context.
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
Description
Both instances are realized by means of a module class ModuleInToOut: The class cyclically copies its input
data area Value to its output data area Value.
The Front instance acts as front end for the user. An input Value is transferred to the output Value via the
method cycleupdate(). This output value of Front is assigned (linked) to the input "value" of the Back
instance.
The Back instance copies the input Value to its output Value, which can be monitored by the user (see the
following quick start steps to start debugging: Debugging a TwinCAT 3 C++ project [} 74])
Ultimately, the user can define the input value of the Front instance and observe the output value of Back.
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
This sample provides for communication from a C++ module to a function block of a PLC by means of
method call. To this end a TcCOM interface is defined that is offered by the PLC and used by the C++
module.
The PLC page as a provider in the process corresponds to the corresponding project of the TcCOM Sample
01 [} 325], where an PLC is considered after PLC communication. Here a Caller is now provided in C++,
which uses the same interface.
The PLC page adopted by TcCOM Sample 01 [} 325]. The function block registered there as TcCOM module
offers the object ID allocated to it as an output variable.
It is the C++ module’s task to make the offered interface of this function block accessible.
ü A C++ project with a Cycle IO module is assumed.
1. In the TMC editor, create an interface pointer of the type I_Calculation with the name Calculationn). Later
access occurs via this.
2. The Data Area Inputs have already been created by the module wizard with the type Input-Destination.
Here in the TMC editor you create an input of the type OTCID with the name oidProvider, via which the
Object ID will be linked from the PLC later.
3. All other symbols are irrelevant for the sample and can be deleted.
In the actual code of the module in CycleUpdate() the interface pointer is set using the object ID
transmitted from the PLC. It is important that this happens in the CycleUpdate() and thus in real-time
context, since the PLC must first provide the function block.
When this has taken place once, the methods can be called.
In addition, as can be seen above, the interface pointer is cleared when the program shuts down.
This happens in the SetObjStateOS method.
4. Now build the C++ project.
5. Create an instance of the module.
6. Connect the input of the C++ module to the output of the PLC.
ð The project can be started. When the PLC is running, the OID is made known through the mapping to the
C++ instance. Once this has occurred, the method can be called.
Download
The whole source code, which is not automatically generated by the wizard, is identified with the comment
start flag "//sample code" and the comment end flag "//sample code end".
In this way you can search for these strings in the files, in order to get an idea of the details.
Description
This sample describes file access via the TwinCAT interface ITCFileAccess. The access is synchronous and
can be used for reading a configuration during startup of a module, for example.
The sample contains a C++ module, TcFileTestDrv, with an instance of this module, TcFileTestDrv_Obj1.
In this sample the file access takes place during the transition PREOP to SAFEOP, i.e. in the
SetObjStatePS() method.
For access to the log entries, see the Error List tab in the TwinCAT 3 output window.
The amount of information can be set by changing the variable TraceLevelMax in the instance
TcFileTestDrv_obj1 in Parameter (Init) tab.
The writing of the file is triggered by a deterministic cycle - the execution of File IO is decoupled
(asynchronous), i.e.: the deterministic cycle continues to run and is not hindered by writing to the file.
Download
Here you can access the source code for this sample
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The sample includes an instance of TcAsyncWritingModule, which writes data to the file AsyncTest.txt in
directory BOOTPRJPATH (usually C:\TwinCAT\3.x\Boot).
TcAsyncBufferWritingModule has two buffers (m_Buffer1, m_Buffer2), which are alternately filled with current
data. The member variable m_pBufferFill points to the buffer that is currently to be filled. Once a buffer is
filled, the member variable m_pBufferWrite is set such that it points to the full buffer.
Note that the file has no human-readable content, such as ASCII characters; in this sample, but binary data
are written to the file.
Download
Here you can access the source code for this sample
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The sample describes how to access files for reading and/or writing using the CycleUpdate method, i.e. in a
cyclic manner.
On starting the sample, the writing module begins to write data to the file located in the boot project path
(normally C:\TwinCAT\3.x\Boot\AsyncTest.txt). The input variable bDisableWriting can be used to prevent
writing.
The objects are connected to one another: once the writing is complete, the WritingModule triggers the
DetectModule of TcAsyncBufferReadingDrv. As a result of this, the ReadingModule initiates a reading
procedure.
Observe the nBytesWritten / nBytesRead output variables of the WritingModule / ReadingModule. Over and
above that, protocol messages are generated at verbose level. As before, these can be configured with the
help of the TraceLevelMax parameter of the module.
• A driver (TcAsyncFileFindDrv) provides one instance
◦ FileFindModule: list the files of a directory with the help of the static library.
Initiate the action with the help of the input variable bExecute. The FilePath parameter contains the directory
whose files are to be listed (default value: c: \TwinCAT\3. 1\Boot\*).
Observe the sequence tracking (verbose protocol level) with regard to the list of files found.
The project TcAsyncFileIO contains various classes in a static library. This library is used by driver projects
for reading and writing.
Each class is intended for a file access operation such as Open / Read / Write / List / Close / .... Since
execution takes place in a cyclic real-time context, each operation has a status, and the class encapsulates
this state machine.
As an entry point for understanding the file access, begin with the classes TcFsmFileReader and
TcFsmFileWriter.
If too many history tracking messages occur, which hamper understanding of the sample, you can disable
modules!
See also
Download
Here you can access the source code for this sample.
NOTE
Configurations details
Read the configurations details below prior to the activation.
Description
This sample is intended to switch the Link Detect bit of the network adapter (i.e. of an CX5010) cyclically on
and off.
The C++ module is connected to the NOV/DP-RAM device via the PciDeviceAdi interface pointer of the C++
module.
Configuration
To make the sample work, the hardware addresses must be configured to match your own hardware.
Check the PCI configuration:
To check whether the communication with NOV/DPRAM is set up correctly, use the DPRAM (Online) view:
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The sample contains five variants that demonstrate the use of SEH in TwinCAT C++:
All of these variants can be selected via a drop-down box at the instance of the C++:
After selecting a variant you can also write the value at runtime by right-clicking on the first column:
All variants write trace messages to illustrate the behavior, so that messages appear in TwinCAT
Engineering:
The selection in the drop-down box is an enumeration that is used in the CycleUpdate() of the module for
selecting a case (switch case). As a result the variants can be considered independently of one another
here:
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The sample contains two projects – the DriverUsingStaticLib project uses the static content of the StaticLib
project.
StaticLib:
On the one hand, StaticLib offers the function ComputeSomething in the StaticFunction.h/.cpp.
On the other hand an interface ISampleInterface is defined (see TMCEditor) and implemented in the
MultiplicationClass.
DriverUsingStaticLib:
In the CycleUpdate method of the ModuleUsingStaticLib, both the class and the function of StaticLib is used.
Manual recompilation
Note that Visual Studio does not automatically recompile the static library during driver develop-
ment. Do that manually.
ü During development of a C++ project use the TwinCAT Static Library Project template for creating a
static library.
ü For the following steps use the Edit dialog of VisualStudio, so that afterwards %(AddtitionalIncludeDirec-
tories) or %(AdditionalDependencies) is used.
1. In the driver add the directory of the static library to the compiler under Additional Include Directories.
2. Add this as an additional dependency for the linker in the driver, which uses the static library. Open the
project properties of the driver and add the static library:
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The sample contains the SortOrder module, which is instanced twice. The sort order determines the
execution order, which can be configured via the TwinCAT Module Instance Configurator [} 150].
For example, the CycleUpdate method tracks the object name and ID along with the sort order of this
module. On the console window you can see the order of execution:
In the sample, one instance is configured with Sort Order 150 and one with 170, while both instances are
assigned to a task.
2. Start the TMC Code Generator in order to obtain the standard implementation.
3. Since the code is modified in the next step, disable the code generation for this parameter now.
4. Make sure you accept the changes before restarting the TMC Code Generator:
Take a look at the CPP module (SortOrderModule.cpp in the sample). The instance of the smart pointer
of the cyclic caller includes information data, including a field for the sorting order. The parameter value
is stored in this field.
///////////////////////////////////////////////////////////////////////////////
// Set parameters of CSortOrderModule
BEGIN_SETOBJPARA_MAP(CSortOrderModule)
SETOBJPARA_DATAAREA_MAP()
///<AutoGeneratedContent id="SetObjectParameterMap">
SETOBJPARA_VALUE(PID_TcTraceLevel, m_TraceLevelMax)
SETOBJPARA_ITFPTR(PID_Ctx_TaskOid, m_spCyclicCaller)
///</AutoGeneratedContent>
///////////////////////////////////////////////////////////////////////////////
// Get parameters of CSortOrderModule
BEGIN_GETOBJPARA_MAP(CSortOrderModule)
GETOBJPARA_DATAAREA_MAP()
///<AutoGeneratedContent id="GetObjectParameterMap">
GETOBJPARA_VALUE(PID_TcTraceLevel, m_TraceLevelMax)
GETOBJPARA_ITFPTR(PID_Ctx_TaskOid, m_spCyclicCaller)
///</AutoGeneratedContent>
GETOBJPARA_TYPE_CODE(PID_Ctx_TaskSortOrder, ULONG, *p=m_spCyclicCaller.GetInfo()-
>sortOrder) //ADDED
//generated code: GETOBJPARA_VALUE(PID_Ctx_TaskSortOrder, m_TaskSortOrderContext1Parameter)
END_GETOBJPARA_MAP()
5. In this sample the object name, ID and sort order are tracked cyclically:
// TODO: Add your cyclic code here
m_counter+=m_Inputs.Value;
m_Outputs.Value=m_counter;
m_Trace.Log(tlAlways, FNAMEA "I am '%s' (0x%08x) w/ SortOrder %d ", this->TcGetObjectName(),
this->TcGetObjectId() , m_spCyclicCaller.GetInfo()->sortOrder); //ADDED
6. The sorting order can also be transferred as the fourth parameter of the method
ITcCyclicCaller::AddModule(), which is used in CModuleA::AddModuleToCaller().
7. Allocate a task with a long cycle interval (e.g. 1000 ms) to the instances of this module, in order to limit
the tracking messages sent to the TwinCAT Engineering system.
8. Assign a different sorting order to each instance via the TwinCAT Module Instance Configurator [} 150]:
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
See also
Source
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
Description
The behavior of this module is comparable with a module that was created with the Cyclic IO wizard.
m_input.Value is added to m_Output.Value. As opposed to the Cyclic IO module, this module only adds
m_input.Value to m_Output.Value if the defined time interval (1000 ms) has elapsed.
This is achieved with the help of a CTON class, which is comparable with the TON function block of PLC /
61131.
The C++ class CTON (TON.h/.cpp) provides the behavior of a TON function block of PLC / 61131. The
Update() method is comparable with the rump of the function block, which has to be called regularly.
See also
The sample illustrates the direct access to the Ethernet card. The TF6311 TCP/UDP RT function provides
access to Ethernet cards on the basis of TCP and UDP, so that an implementation of a network stack is not
necessary on the basis of this sample.
Download
Here you can access the source code for this sample.
1. Unpack the downloaded ZIP file.
2. Open the zip file that it contains in TwinCAT 3 by clicking on Open Project ….
3. Select your target system.
4. Build the sample on your local machine (e.g. Build->Build Solution).
5. Note the actions listed on this page under Configuration.
Description
The sample contains an instance of the TcEthernetSample module, which sends and received ARP packets
for the purpose of determining the remote hardware address (MAC).
The CycleUpdate method implements a rudimentary state machine for sending ARP packets and waiting for
a response with a timeout.
Configuration
The downloaded TwinCAT project must be configured for execution in a network environment. Please carry
out the following steps:
ü This sample demands the use of the TwinCAT driver by the Ethernet card.
1. Start TcRteInstall.exe either from the XAE via the menu TwinCAT->Show Realtime Ethernet
compatible devices… or from the hard disk on the XAR systems.
2. You may have to install and activate the driver with the help of the buttons.
3. TwinCAT must know which Ethernet card is to be used. Open the project in XAE and click on Select I/
O / Devices / Device 1 (RT-Ethernet Adapter).
4. Click on the Adapter tab and select the adapter with Search.
5. TcEthernetSample_Obj1 must be configured. Open the instance window and set the following values:
Parameter (Init): SenderIpAddress (IP of the network adapter configured in step 2)
Parameter (Init): TargetIpAddress (IP of target host)
Interface pointer: EthernetAdapter must point to I/O / Devices / Device 1 (RT-Ethernet Adapter).
Download
Description
The sample TcCOM object archive describes restoration and saving of an object state during initialization
and deinitialization. The state of the sample class CmoduleArchive corresponds to the value of the counter
CModuleArchive::m_counter.
During the transition from PREOP to SAFEOP, i.e. when calling the method
CModuleArchive::SetObjStatePS(), the object archive server (ITComObjArchiveServer) is used to create an
object archive for reading, which is accessed via the interface ITComArchiveOp. This interface provides
overloads from operator>>() in order to read them in the archive.
During the transition from SAFEOP to PREOP, i.e. when calling the method
CModuleArchive::SetObjStateSP(), the TCOM object archive server is used to create an object archive for
writing, which is accessed via the interface ITComArchiveOp. This interface provides overloads from
operator<<() in order to write them in the archive.
The TcCOM_Sample01 sample [} 325] shows how TcCOM communication can take place between two
PLCs. In the process functionalities from one PLC are directly called up from the other PLC.
The TcCOM_Sample02 sample [} 335] shows how a PLC application can use functionalities of an existing
instance of a TwinCAT C++ class. In this way separate algorithms written C++ (or Matlab) can be used easily
in the PLC.
Although in the event of the use of an existing TwinCAT C++ driver the TwinCAT C++ license is required on
the target system, a C++ development environment is not necessary on the target system or on the
development computer.
The TcCOM_Sample03 sample [} 339] shows how a PLC application uses functionalities of a TwinCAT C++
class by generating an instance of C++ class at the same time. In comparison to the previous sample this
can offer increased flexibility.
16.25.1 TcCOM_Sample01_PlcToPlc
This sample describes a TcCOM communication between two PLCs.
Functionalities provided by a function block in the first PLC (also called "provider" in the sample), are called
from the second PLC (also called "caller" in the sample). To this end it is not necessary for the function block
or its program code to be copied. Instead the program works directly with the object instance in the first PLC.
Both PLCs must be in a TwinCAT runtime. In this connection a function block offers its methods system-wide
via a globally defined interface and represents itself a TcCOM object. As is the case with every TcCOM
object, such a function block is also listed at runtime in the TcCOM Objects node.
System requirements
16.25.1.1 Creating an FB which provides its functionality globally in the first PLC
1. Create a PLC and prepare a new function block (FB) (here: FB_Calculation). Derive the function block
from the TcBaseModuleRegistered class, so that an instance of this function block is not only available in
the same PLC, but can also be reached from a second.
Note: as an alternative you can also modify an FB in an existing PLC.
2. The function block must offer its functionality by means of methods. These are defined in a global
interface, whose type is system-wide and known regardless of programming language. To create a
global interface, open the Context menu in the “Interface” tab of System Properties and choose the
option “New”.
ð The TMC Editor opens, which provides you with support in creating a global interface.
3. Specify the name (here: I_Calculation) and append the desired methods. The interface is automatically
derived from ITcUnknown, in order to fulfill the TwinCAT TcCOM module concept.
4. Specify the name of the methods analogously (here: Addition() and Subtraction()) and select HRESULT
as return data type. This return type is mandatory if this type of TcCOM communication should be
implemented.
5. Specify the method parameters last and then close the TMC Editor.
6. Now implement the I_Calculation interface in the FB_Calculation function block and append the c+
+_compatible attribute.
7. Choose the “Implement interfaces...” option in the Context menu of the function block in order to obtain
the methods belonging to this interface.
8. Delete the two methods TcAddRef() and TcRelease() because the existing implementation of the base
class should be used.
9. Create the FB_reinit() method for the FB_Calculation function block and call the basic implementation.
This ensures that the FB_reinit() method of the base class will run during the online change. This is
imperative.
10. Implement the TcQueryInterface() method of the Interface ITcUnknown [} 206]. Via this method it is
possible for other TwinCAT components to obtain an interface pointer to an instance of this function
block and thus actuate method calls. The call for TcQueryInterface is successful if the function block or
its base class provides the interface queried by means of iid (Interface ID). For this case the handed over
interface pointer is allocated the address to the function block type-changed and the reference counter is
incremented by means of TcAddRef().
11. Fill the two methods Addition() and Subtraction() with the corresponding code to produce the
functionality: nRes := nIn1 + nIn2 and nRes := nIn1 - nIn2
12. Add one or more instances of this function block in the MAIN program module or in a global variable list.
ð The implementation in the first PLC is complete.
ð After compiling the PLC, the object ID of the TcCOM object which represents the instance of
FB_Calculation is available as an outlet in the in the process image.
2. In the declaration part of the function block declare as an output an interface pointer to the global
interface which later provides the functionality outward.
3. In addition create the object ID and the interface ID as local member variables.
While the interface ID is already available via a global list, the object ID is assigned via a link in the
process image.
4. Implement the PLC proxy function block. First add the GetInterfacePointer() method to the function block.
The interface pointer is fetched to the specified interface of the specified TcCOM object with the help of
the FW_ObjMgr_GetObjectInstance() function. This will only be executed if the object ID is valid and the
interface pointer has not already been allocated. The object itself increments a reference counter.
5. It is imperative to release the used reference again. To this end call the FW_SafeRelease() function in
the FB_exit destructor of the function block.
Order irrelevant
The sequence in which the two PLCs start later is irrelevant in this implementation.
ð In the online view of the PLC application “Caller” the Proxy function block has been allocated the
same object ID via the process image. The interface pointer has a valid value and the methods are
executed.
16.25.2 TcCOM_Sample02_PlcToCpp
This example describes a TcCOM communication between PLC and C++. In this connection a PLC
application uses functionalities of an existing instance of a TwinCAT C++ class. In this way own algorithms
written in C++ can be used easily in the PLC.
Although in the event of the use of an existing TwinCAT C++ driver the TwinCAT C++ license is required on
the destination system, a C++ development environment is not necessary on the destination system or on
the development computer.
An already built C++ driver provides one or more classes whose interfaces are deposited in the TMC
description file and thus are known in the PLC.
2. Creating an FB in the PLC, which as a simple wrapper offers the functionality of the C++ object [} 336]
System requirements
The existing TwinCAT C++ driver as well as its TMC description file(s) are available as a driver archive. This
archive (IncrementerCpp.zip) is unpacked in the following folder:
C:\TwinCAT\3.1\CustomConfig\Modules\IncrementerCpp\
The TwinCAT Deployment copies the file(s) later in the following folder upon the activation of a configuration
in the target system:
C:\TwinCAT\3.1\Driver\AutoInstall\
1. Open a TwinCAT project or create a new project.
2. Add an instance of Class CIncrementModule in the solution under the node TcCOM Objects.
16.25.2.2 Creating an FB in the PLC that, as a simple proxy, offers the functionality
of the C++ object
1. Create a PLC and append a new function block there.
This Proxy function block should provide the functionality that was programmed in C++. It is able to do
this via an interface pointer that was defined from the C++ class and is known in the PLC due to the TMC
description file.
2. In the declaration part of the function block declare as an output an interface pointer to the interface
which later provides the functionality outward.
3. Create the object ID and the interface ID as local member variables.
While the interface ID is already available via a global list, the object ID is allocated via the TwinCAT
symbol initialization. The TcInitSymbol attribute ensures that the variable appears in a list for external
symbol initialization. The object ID of the created C++ object should be allocated.
ð The object ID is displayed upon selection of the object under the TcCOM Objects node.
Provided the TcInitSymbol attribute was used, the list of symbol initializations is located in the node
of the PLC instance in the Symbol Initialization tab.
4. Here, assign an existing object ID to the symbol name of the variable by drop-down. This value is
assigned when the PLC is downloaded so it can be defined prior to the PLC run-time. New symbol
initializations or changes are accordingly entered with a new download of the PLC.
As an alternative, the passing of the object ID could also be implemented by means of process image
linking as implemented in the first sample (TcCOM_Sample01_PlcToPlc [} 325]).
5. Implement the PLC Proxy function block.
First the FB_init constructor method is added to the function block. For the case that it is no longer an
OnlineChange but rather the initialization of the function block, the interface pointer to the specified
interface of the specified TcCOM object is obtained with the help of the function
FW_ObjMgr_GetObjectInstance(). In this connection the object itself increments a reference counter.
6. It is imperative to release the used reference again. To this end call the FW_SafeRelease() function in
the FB_exit destructor of the function block.
ð In the online view of the PLC application the assigned object ID of the C++ object in the PLC Proxy
function block can be seen. The interface pointer has a valid value and the method will be executed.
16.25.3 TcCOM_Sample03_PlcCreatesCpp
Just like Sample02, this sample describes a TcCOM communication between PLC and C++. To this end a
PLC application uses functionalities of a TwinCAT C++ class. The required instances of this C++ class will
be created by the PLC itself in this sample. In this way own algorithms written in C++ can be used easily in
the PLC.
Although in the event of the use of an existing TwinCAT C++ driver the TwinCAT C++ license is required on
the destination system, a C++ development environment is not necessary on the destination system or on
the development computer.
An already built C++ driver provides one or more classes whose interfaces are deposited in the TMC
description file and thus are known in the PLC.
2. Creating an FB in the PLC that creates the C++ object and offers its functionality [} 341]
System requirements
The existing TwinCAT C++ driver as well as its TMC description file(s) are available as a driver archive. This
archive (IncrementerCpp.zip) is unpacked in the following folder:
C:\TwinCAT\3.1\CustomConfig\Modules\IncrementerCpp\
The TwinCAT Deployment copies the file(s) later in the following folder upon the activation of a configuration
in the target system:
C:\TwinCAT\3.1\Driver\AutoInstall\
1. Open a TwinCAT project or create a new project.
2. Select the required C++ driver in the solution under the TcCOM Objects node in the Class Factories
tab.
ð This ensures that the driver is loaded on the target system when TwinCAT starts up. In addition this
selection provides for the described deployment.
16.25.3.2 Creating an FB in the PLC that creates the C++ object and offers its
functionality
1. Create a PLC and append a new function block there.
This Proxy function block should provide the functionality that was programmed in C++. It manages this
via an interface pointer that was defined by C++ and is known in the PLC due to the TMC description file.
2. In the declaration part of the function block declare as an output an interface pointer to the interface
(IIncrement) which later provides the functionality outward.
4. Add the FB_init constructor method to the PLC Proxy function block.
For the case, that it is not an online change but rather the initialization of the function block, a new
TcCOM object (Class instance of the specified class) is created and the interface pointer to the specified
interface is obtained. In the process the used FW_ObjMgr_CreateAndInitInstance() function is also given
the name and the destination state of the TcCOM object. These two parameters are declared here as
input parameters of the FB_init method, whereby they are to be specified in the instantiation of the Proxy
function block. The TwinCAT C++ class to be instantiated manages without TcCOM initialization data
5. It is imperative to release the used reference again and to delete the object, provided it is no longer being
used. To this end call the FW_ObjMgr_DeleteInstance() function in the FB_exit destructor of the function
block.
17 Appendix
• The ADS Return Codes [} 344] are important across TwinCAT 3, particularly if ADS communication
[} 209] itself is implemented.
• The Retain data [} 349] (in NOVRAM memory) can be used in a similar way from the PLC and also C+
+.
• In addition to the TcCOM Module [} 35] concept, the TwinCAT 3 type system is an important basis for
understanding.
• The following pages originate from the documentation for the Automation Interface.
When using the Automation Interface please refer to the dedicated documentation.
◦ Creating and handling C++ projects and modules [} 351]
◦ Creating and handling TcCOM modules [} 355]
0x501 1281 0x9811 0501 ROUTERERR_RESIZEMEMORY The router memory size could not be changed.
0x502 1282 0x9811 0502 ROUTERERR_MAILBOXFULL The mailbox has reached the maximum number of
possible messages.
0x503 1283 0x9811 0503 ROUTERERR_DEBUGBOXFULL The Debug mailbox has reached the maximum
number of possible messages.
0x100D 4109 0x9811 100D RTERR_EXTIRQALREADYDEF An external synchronization interrupt is already ap-
plied.
0x100E 4110 0x9811 100E RTERR_EXTIRQNOTDEF No external sync interrupt applied.
0x100F 4111 0x9811 100F RTERR_EXTIRQINSTALLFAILED Application of the external synchronization interrupt
has failed.
0x1010 4112 0x9811 1010 RTERR_IRQLNOTLESSOREQUAL Call of a service function in the wrong context
0x1017 4119 0x9811 1017 RTERR_VMXNOTSUPPORTED Intel VT-x extension is not supported.
0x1018 4120 0x9811 1018 RTERR_VMXDISABLED Intel VT-x extension is not enabled in the BIOS.
0x1019 4121 0x9811 1019 RTERR_VMXCONTROLSMISSING Missing function in Intel VT-x extension.
0x101A 4122 0x9811 101A RTERR_VMXENABLEFAILS Activation of Intel VT-x fails.
Solution.
2. Create one or more Retain Handler below this device.
4. An additional retain directory for the symbols is created in the TwinCAT boot directory.
In a PLC project the variables are either created in a VAR RETAIN section or identified with the attribute
TcRetain.
PROGRAM MAIN
VAR RETAIN
l: UINT;
k: UINT;
END_VAR
VAR
{attribute ‘TcRetain’:=’1’}
m: UINT;
x: UINT;
END_VAR
If self-defined data types (DUTs) are used as retain, the data types must be available in the TwinCAT type
system. You can either use the option Convert to Global Type or you can create structures directly as
STRUCT RETAIN. However, the Retain Handler then handles all occurrences of the structure.
Retain data cannot be used for POUs (function blocks) as a whole. However, individual elements of a POU
can be used.
In a C++ module a data area of type Retain Source is created, which contains the corresponding symbols.
At the instances of the C++ module, a retain handler of the NOV-DP-RAM device to be used for this data
area is defined in column Retain Hdl.
Conclusions
When a retain handler is selected as target in the respective project, the symbols under retain handler and a
mapping are created automatically after a "Build".
• Building project
C++ projects are specified by their so-called project template, which are used by the “TwinCAT C++ Project
Wizard”. Inside a project multiple modules could be defined by module templates, which are used by the
“TwinCAT Class Wizard”.
The customer could define own templates, which is documented at the corresponding sub-section if C++
Section / Wizards [} 154].
To create a new C++ project via Automation Interface, you need to navigate to the C++ node and then
execute the CreateChild() method with the corresponding template file as a parameter.
Within a C++ project usually a TwinCAT Module Wizard is used to let the wizard create a module by a
template.
As example for instantiating a Cyclic IO module project please use "TcModuleCyclicCallerWizard " as
pathToTemplateFile.
To open an existing C++-Project via Automation Interface, you need to navigate to the C++ node and then
execute the CreateChild() method with the path to the corresponding C++ project file as a parameter.
Basically, these values represent the functionalities (Yes, No, Cancel) from the following MessageBox in
TwinCAT XAE:
In place of the template file you need to use the path to the C++ project (to its vcxproj file) that needs to be
added. As an alternative, you can also use a C++ project archive (tczip file).
Please note that C++ projects can’t be renamed, thus the original project name needs to be specified. (cmp.
Renaming TwinCAT C++ projects [} 238])
TcCOM Modules could be created at the System -> TcCOM Modules node. Please see documentation there
[} 355].
The same procedure could also be applied to the C++ project node to add TcCOM instances at that place
($newProject at the code on top of this page.).
TMC Code generator could be called to generate C++ code after changes at the TMC file of the C++ project.
</CppProjectDef>
</TreeItem>"
$cppProject.ConsumeXml($startTmcCodeGenerator)
Publishing includes building the project for all platforms. The compiled module will be provided for Export like
described in the Module-Handling section of C++ [} 50].
C++ projects provide different options for the build and deployment process.
These are settable by the Automation Interface.
For the BootProjectEncryption the values “None” and “Target” are valid.
Both other settings are “false” and “true” values.
Building project
To build the project or solution you can use the corresponding classes and methods of the Visual Studio API,
which are documented here.
In a TwinCAT configuration, the “TcCOM Objects” node is located under “SYSTEM^TcCOM Objects”.
Therefore you can acquire a reference to this node by using the method ITcSysManager::LookupTreeItem()
in the following way:
The code above assumes that there is already a systemManager objects present in your AI code.
To add existing TcCOM modules to your TwinCAT configuration, these modules need to be detectable by
TwinCAT. This can be achieved by either of the following ways:
• Copying TcCOM modules to folder %TWINCAT3.XDIR”\CustomConfig\Modules\
• Editing %TWINCAT3.XDIR”\Config\Io\TcModuleFolders.xml to add a path to a folder of your choice
and place the modules within that folder
Both ways will be sufficient to make the TcCOM modules detectable by TwinCAT.
Alternatively, you can also determine the GUID via the TMC file of the TcCOM module.
<TcModuleClass>
<Modules>
<Module GUID="{8f5fdcff-ee4b-4ee5-80b1-25eb23bd1b45}">
...
</Module>
</Modules>
</TcModuleClass>
Let’s assume that we already own a TcCOM module that is registered in and detectable by TwinCAT. We
now would like to add this TcCOM module, which has the GUID {8F5FDCFF-
EE4B-4EE5-80B1-25EB23BD1B45} to our TwinCAT configuration. This can be done by the following way:
Please note that the vInfo parameter of the method ItcSmTreeItem::CreateChild() contains the GUID of the
TcCOM module which is used to identify the module in the list of all registered TcCOM modules in that
system.
• This name can be used to add a TcCOM module to a TwinCAT configuration via the
ITcSmTreeItem::CreateChild() method. The name can be determined in TwinCAT XAE via the TMC
Editor.
•
• This can be done by the following way:
To iterate through all added TcCOM module instances, you may use the ITcModuleManager2 interface. The
following code snippet demonstrates how to use this interface.
Please note that every module object can also be interpreted as an ITcSmTreeItem, therefore the following
type cast would be valid:
The CreateSymbol (CS) flag for parameters of a TcCOM module can be set via its XML description. The
following code snippet demonstrates how to activate the CS flag for the Parameter “CallBy”.
// Third step: Look for specific parameter (in this case “CallBy”) and read its CreateSymbol
attribute
XmlNode destModule = targetDoc.SelectSingleNode("TreeItem/TcModuleInstance/Module ");
XmlNode callByParameter = destParameters.SelectSingleNode("Parameters/Parameter[Name='CallBy']");
XmlAttribute createSymbol = callByParameter.Attributes["CreateSymbol"];
createSymbol.Value = "true";
$destModule = $targetDoc.TreeItem.TcModuleInstance.Module
$callByParameter = $destmodule.SelectSingleNode("Parameters/Parameter[Name='CallBy']")
$callByParameter.CreateSymbol = "true"
$targetXml = $targetDoc.OuterXml
$tempController.ConsumeXml($targetXml)
The CreateSymbol (CS) flag for Data Areas of a TcCOM module can be set via its XML description. The
following code snippet demonstrates how to activate the CS flag for the Data Area “Input”. Please note that
the procedure is pretty much the same as for parameters.
// Third step: Look for specific Data Area (in this case "Input") and read its CreateSymbol
attribute
XmlElement dataArea = (XmlElement)targetDoc.SelectSingleNode("TreeItem/TcModuleInstance/Module/
DataAreas/DataArea[ContextId=’0’ and Name=’Input’]");
XmlNode dataAreaNo = dataArea.SelectSingleNode("AreaNo");
XmlAttribute createSymbol = dataAreaNoNode.Attributes["CreateSymbols"];
// Fourth step: Set CreateSymbol attribute to true if it exists. If not, create attribute and set
its value
if (createSymbol != null)
string oldValue = createSymbol.Value;
else
{
createSymbol = targetDoc.CreateAttribute("CreateSymbols");
dataAreaNo.Attributes.Append(createSymbol);
}
createSymbol.Value = XmlConvert.ToString(activateCS);
$destModule = $targetDoc.TreeItem.TcModuleInstance.Module
[System.XML.XmlElement] $dataArea = $destModule.SelectSingleNode("DataAreas/DataArea[ContextId='0'
and Name='Input']")
$dataAreaNo = $dataArea.SelectSingleNode("AreaNo")
$dataAreaNo.CreateSymbols = "true"
Every TcCOM module instance needs to be run in a specific context (task). This can be done via the
ITcModuleInstance2::SetModuleContext() method. This method awaits two parameters: ContextId and
TaskObjectId. Both are equivalent to the corresponding parameters in TwinCAT XAE:
You can determine the TaskObjectId via the XML description of the corresponding task, for example:
Linking variables
Linking variables of a TcCOM module instance to PLC/IO or other TcCOM modules can be done by using
regular Automation Interface mechanisms, e.g. ITcSysManager::LinkVariables().