Sample10: module communication: Using data pointer
This article describes the implementation of two TC3 C++ modules, which communicate via a data pointer.
Download
Here you can access the source code for this sample.
- 1. Unpack the downloaded ZIP file.
- 2. Using a Visual Studio with TwinCAT installed, open the project via Open Project ....
- 3. Configure signing for this project by switching on TwinCAT signing with a right-click on Project->Properties->Tc Sign and configure your certificate and password if necessary.
For more information on signing C++ projects, click here. - 4. Select your target system.
- 5. Build the sample (e.g. Build->Build Solution).
- 6. Activate the configuration by clicking on .
- The sample is ready for operation.
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.
All in all, this sample includes the following modules:
- ModuleDataProvider provides a data area, which can be accessed by the other modules.
The data area contains 4 bits (2 for input, 2 for output) and 2 integers (1 for input, 1 for output). - ModuleDataInOut provides "normal" input variables, which are written to the data area of the ModuleDataProvider, and output variables, which are read from
the data area.
This instance of the CModuleDataInOut class serve as a simulation for real IO. - 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.
Understanding the sample
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.