You are on page 1of 518

FactoryLink

Version 8.0




























Programmer’s Access Kit




Disclaimer of Liability
The information contained in this document (and other media provided
herewith) constitutes confidential information of Siemens AG and is
protected by copyright laws and international copyright treaties, as well
as other intellectual property laws and treaties. Such information is not to
be disclosed, used or copied by, or transferred to, any individual,
corporation, company or other entity, in any form, by any means or for
any purpose, without the express written permission of Siemens AG.
The information contained in this document and related media
constitutes documentation relating to a software product and is being
provided solely for use with such software product. The software product
was provided pursuant to a separate license or other agreement and
such information is subject to the restrictions and other terms and
conditions of such license or other agreement.
The information contained in this document and related media is subject
to change without notice and does not represent a commitment and does
not constitute any warranty on the part of Siemens AG. Except for
warranties, if any, set forth in the separate license or other agreement
relating to the applicable software product, Siemens AG makes no
warranty, express or implied, with respect to such information or such
software product.

Trademarks
Siemens AG and FactoryLink are trademarks or registered trademarks of
Siemens AG in the United States and/or other countries. All other brand
or product names are trademarks or registered trademarks of their
respective holders.

Siemens AG Copyright © Siemens AG 2007.


Automation and Drives 0829/2007 Technical data subject to change
Postfach 48 48
90327 NÜRNBERG
GERMANY
Programmer’s Access Kit in the Programmer’s Programmer’s Access Kit in this book
Access Kit
Contents





Programmer’s Access Kit

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Using this Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Part I Basic PAK


Chapter 1 Programmer’s Access Kit Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
FactoryLink Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Installation Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Compiling Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
For All Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Chapter 2 Skeleton Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Integrating Skeleton into the FactoryLink System . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Verify the FactoryLink Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Compiling and Executing the Skeleton Task . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Testing the Skeleton Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

Chapter 3 Run-Time Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25


Run-Time Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
FactoryLink Kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Kernel Multi-User Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
USER and SHARED Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Application Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
FactoryLink Real-Time Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
FactoryLink Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
How FactoryLink Tasks Transfer Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
How FactoryLink Architecture Affects New Task Development . . . . . . . . . . . . 37

FactoryLink Programmer’s Access Kit / 3






Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Configuration Explorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
FactoryLink Directory Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Chapter 4 FactoryLink Configuration Architecture . . . . . . . . . . . . . . . . . . . . . . . . 45


Configuring FactoryLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Arrayed Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Tag Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Tag Name Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Predefined Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
OBJECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
XREF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Task-Specific . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
{FLAPP} Application Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

Chapter 5 Constructing a FactoryLink Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Setting up the Configuration Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Convert Database Tables to CTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Writing the Run-Time Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Creating a Configuration Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Design the Database Table(s) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Create the Attribute Catalog(s) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
XLATES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
TASK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
CT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
EDIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
VALIDATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
PANEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
FIELD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
HEADING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
RELATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
DESC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
DOMAIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

4 / FactoryLink Programmer’s Access Kit


SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
SEQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Naming Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Associating Help with the Task Attributes Catalog . . . . . . . . . . . . . . . . . . . . . . 84
Executing an Editor Program from the Configuration Explorer . . . . . . . . . . . . 85
Create the KEY Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Informing FactoryLink about the Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Testing the Configuration Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Viewing Contents of a Configuration Database without Configuration Explorer 89
Creating a Single Point Configuration Environment . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Extending the Single Point Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
AC file Language Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Using PAGEDIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Adding Help to Your Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Preparing Configuration for Run Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Create the CTG Conversion Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
HEADER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
RECORD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
DOMAIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
FIELD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
SKIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
SORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Creating FactoryLink Configuration Tables (CTs) . . . . . . . . . . . . . . . . . . . . . 111
Debugging the Conversion Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Writing the Run-Time Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Kernel Check (Conditional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
New Configuration Notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
RTM File and Task Bumping Determination . . . . . . . . . . . . . . . . . . . . . . . . . 116
Termination Notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Orderly Shutdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Message Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Task Program Skeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

FactoryLink Programmer’s Access Kit / 5






Chapter 6 PAK Library Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Kernel Interface Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Task/Kernel Session Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Database Access Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Calling and Return Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
CT Access Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Object CT Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Overview of Object CT Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Overview of the Object CT API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Direct Tag Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Direct Tag Library Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
FLDTP API Exit Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Normalized Tag Reference Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
FLNTAG Services Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
FLNTAG API Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
FLNTAG Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
FLNTAG Function Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Path Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Path Name Building and Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Path Name Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Use of Environment Variables in Path Names . . . . . . . . . . . . . . . . . . . . . . . . . 154
Allocating/Destroying a Normalized Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Converting To/From a Normalized Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Modifying an Existing Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Creating/Deleting Directories and Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Searching for Matching Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Getting File Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Message Translation Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Message Translation Functions Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Loading Translation Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Translating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Managing Multiple Translation Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Extended Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

6 / FactoryLink Programmer’s Access Kit


Chapter 7 PAK API Reference Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

Chapter 8 Application Objects API Reference Library . . . . . . . . . . . . . . . . . . . . 259

Part II Configuration PAK


Chapter 9 Configuration PAK Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Required Hardware and Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Configuration Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Configuration Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Configuration Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Data Structure Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331

Chapter 10 Configuration PAK Library Services . . . . . . . . . . . . . . . . . . . . . . . . . . 333


Configuration Session API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Attribute Catalog API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
What is an Attributes Catalog (AC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Accessing CDBs Defined Within an AC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Configuration Database API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Interrogating a CDB Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Key Field API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Reading Configuration from a CDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Writing Configuration to a CDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Multi-User Access to a CDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
Configuration Text File API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Object Database API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Locating the Object CDB Handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Reading Tag Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Exception Handling API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Return Codes and Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Validation Error Reporting for Inserts and Updates . . . . . . . . . . . . . . . . . . . 373

Chapter 11 Configuration Database ActiveX Component . . . . . . . . . . . . . . . . . . . 375


Using CFGPAK OCX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375

FactoryLink Programmer’s Access Kit / 7






OBJPACK Sample Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378

Chapter 12 Configuration PAK API Reference Library . . . . . . . . . . . . . . . . . . . . . 379

Part III RAPD PAK


Chapter 13 RAPD Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
RAPD Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Compiling with MCI Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439

Chapter 14 MCI Messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441


Mailbox Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
mm_msg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
mm_type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
mm_user1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
mm_user2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Datasets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Dataset Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Datasets Defined in an Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Passing and Processing a Dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
I/O Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
The Block Read Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Block Write Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
Exception Write Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Normal Exception Write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Unsolicited Receive Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Data Directions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Combinations of CDE Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Converting MCI Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
MCI and LANS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466

Chapter 15 Writing a RAPD Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
IOX - Driver Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

8 / FactoryLink Programmer’s Access Kit


Error Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472

Chapter 16 MCI Reference Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475


Function Categories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
General MCI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
MCI Header (MCIHDR) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
MCI System (MCISYS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
MCI Message (MCIMSG) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
MCI Dataset (MCIDS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
MCI Data Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
MCI APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479

Appendix PAK Conversion Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509


Converting FactoryLink pre-7.0 PAK Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Adding Multilingual Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Automated Conversion of pre-6.0.4 Driver or PAK Task . . . . . . . . . . . . . . . . . . . . . . 511
Converting IMX RAPD PAK Drivers to MCI3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513

FactoryLink Programmer’s Access Kit / 9





10 / FactoryLink Programmer’s Access Kit






Preface

P URPOSE
The FactoryLink Programmer’s Access Kit is a collection of software tools for use in the
design and construction of FactoryLink-compatible tasks. This guide provides the technical
information programmers of these systems need to complete their applications.

The major audience of this guide is programmers who design and construct programs to
• Create new tasks that perform functions not performed by standard FactoryLink tasks.
• Develop communications interfaces to computers or devices for which standard interface
tasks are not already developed.

In addition, FactoryLink Customer Support Services personnel use the procedures and
examples to help you develop and troubleshoot your applications.

U SING THIS G UIDE


The material in this guide is presented in learning, then performance order. It is recommend
you become familiar with the complete procedure before you develop your application.

Located within each part of this guide is a section named “ … at a Glance”. This section
provides a quick key to locations to find information to perform the procedures detailed in that
part with hypertext links to those locations.

FactoryLink Programmer’s Access Kit / 11


• PREFACE
• Conventions


C ONVENTIONS
The FactoryLink Programmer’s Access Kit uses the following conventions.

Convention Description

… Horizontal ellipsis points indicate the omission of material


from an example. The information is omitted because it is
not important to the topic being discussed.

. Vertical ellipsis points indicate the omission of information


. from an example or command format. The information is
. omitted because it is not important to the topic being
discussed.

italic type Italic type is used to denote user-supplied variables in


command examples.
Italic type also sets off references to specific documents.

monospace type Monospace type is used to denote command names and


code examples or example output.

bold monospace type Bold monospace type is used in command examples to


indicate words that must be typed literally.
sans serif type Sans Serif type is used to set off field names, button names,
and keys on the keyboard.

press nnnnn Press is used to denote a key on the keyboard. The key
name will appear in a sans serif type.

click nnnnn Click is used to denote a button on the screen. The button
name will appear in a sans serif type.
Shift+F1 The + indicates the keys must be pressed simultaneously.
Shift+F1 indicates you hold down the Shift key while you
press another key or mouse button (indicated here by F1).
Other key combinations are presented in the same manner.

12 / FactoryLink Programmer’s Access Kit


PREFACE
Conventions

Convention Description

F1 F2 F3 The space between the key callouts indicates press and


release.
The key sequence F1 F2 F3 indicates you press and release
F1, then F2, and then F3.
Other key combinations are presented in the same manner.
File>Open The > indicates a progression through a menu sequence.
File>Open indicates you choose Open from the File menu
to perform the required action.
Other menu sequences are presented in the same manner.
FLAPP\user\drw\mydrw.g The \ indicates the directory structure for the listed file.
FLAPP\user\drw\mydrw.g indicates the drawing file
mydrw.g is located in the drw sub-directory of the user
sub-directory to the FLAPP directory.
Other directory structures are presented in the same
manner.

[] Brackets indicate an optional argument. You can choose


none, one, or all of the options.

{ } and | Braces indicate a choice. You must choose one of the


elements. The vertical bar separates choices within braces.

Example Syntax

Example syntax using these conventions is provided below:

command input_file [input_file…] {a|b} output_file

where
command is typed as it is displayed in the syntax.
input_file indicates a variable the user supplies.
[input_file…] indicates the user can optionally supply multiple input file names, each
name separated by a space.
{a|b} indicates either the a or b must be specified as an argument.
output_file indicates the user must specify an output file.

FactoryLink Programmer’s Access Kit / 13


• PREFACE
• Conventions

14 / FactoryLink Programmer’s Access Kit








Part I











Basic PAK













15



16 / FactoryLink Programmer’s Access Kit


Chapter 1





Programmer’s Access Kit
Overview 1

Programmer’s Access
Kit Overview
The FactoryLink Programmer's Access Kit (PAK) is a collection of optional FactoryLink
software tools and related documentation for use in the design and construction of
FactoryLink-compatible tasks.

PAK allows you to take full advantage of FactoryLink's open architecture. This guide describes
the C-language calling conventions; however, you can develop programs using any language
that supports these calling conventions. Customer-written programs have full access to
FactoryLink's real-time database and operate in conjunction with other FactoryLink programs.

Caution: The structure of FactoryLink provides an architecture that


supports an arbitrary number of languages, not just English,
French, and German. Test for the availability of a particular
language by checking the subdirectories under
the%FLINK%\DLL directory. The FactoryLink utility,
FLSETLNG, assumes any subdirectories added to the DLL
directory are additional language implementations. If
additional languages are not implemented correctly,
FactoryLink produces unpredictable results.

Use the FactoryLink Programmer's Access Kit to:


• Create new tasks that perform functions not performed by standard FactoryLink tasks
• Develop communications interfaces to computers or devices for which standard interface
tasks are not already developed

Unlike any other open architecture system, FactoryLink fully integrates a customer-written
task into the FactoryLink environment. The FactoryLink Configuration Explorer fully supports
new tasks with full-screen editing, context-sensitive help, and documentation utilities.

FactoryLink Programmer’s Access Kit / 17


• PROGRAMMER’S ACCESS KIT OVERVIEW
• FactoryLink Environment Variables


F ACTORY L INK E NVIRONMENT V ARIABLES
FactoryLink tasks depend on the values of various environment variables to determine many
aspects of their interactions with files and the Real-Time Database. FactoryLink must know
where the FactoryLink application, FactoryLink system files, and FactoryLink software
license information are located. Because multiple FactoryLink applications can run
concurrently and because FactoryLink software is designed to run in both single-user and
multi-user environments, the following environment variables must always be set to
appropriate values:
{FLINK} Base directory of FactoryLink system installation
{FLAPP} Base directory of application files
{FLOPT} Directory where software licence files reside
{FLNAME} Name of application that is running
{FLDOMAIN} Domain name
{FLUSER} User instance name

These variables are set to default values during installation.

I NSTALLATION R EQUIREMENTS
PAK is an option used in conjunction with a FactoryLink Development System. Refer to the
FactoryLink Release Notes. PAK requires specific versions of software tools not included with
PAK. See the FactoryLink Installation Guide for a list of FactoryLink software and
requirements and for information on which compiler to use.

Install the Programmer’s Access Kit as an option during the installation procedure for
FactoryLink following the procedure explained in FactoryLink Installation Guide.

C OMPILING P ROGRAMS
PAK provides a command script for all supported compilers named setup<platform>.bat that
sets the environment variables required to successfully build the example programs. This
command script must be executed prior to building any of the shipped examples. The set up
script resides in directory {FLINK}/src/examples/skel.

Each example program is accompanied with a makefile. Execute the compiler make facility at
the command prompt to build the example programs. While PAK does not provide any
pre-built projects for use within the compiler integrated developer’s environment, you should
be able to create one with limited effort.

18 / FactoryLink Programmer’s Access Kit


PROGRAMMER’S ACCESS KIT OVERVIEW
For All Users

F OR A LL U SERS
1
Whenever you receive a new version of FactoryLink, you must relink all tasks to the new

Programmer’s Access
libraries. Also, you cannot run old FactoryLink tasks with the new ones. You must run all new
FactoryLink tasks.

Kit Overview
Caution: Failure to heed these concerns will almost certainly result in
an immediate crash of your entire application.

FactoryLink Programmer’s Access Kit / 19


• PROGRAMMER’S ACCESS KIT OVERVIEW
• For All Users

20 / FactoryLink Programmer’s Access Kit


Chapter 2





Skeleton Task
2

Skeleton Task
O VERVIEW
The Skeleton Task serves as a framework to build a custom task designed to meet your unique
needs. Ensure the Skeleton Task is both functional and integrated into your FactoryLink
system before beginning the PAK task construction.

The source code and support files for the Skeleton Task reside in the directory
{FLINK}\src\skeleton and include the following files.

Skeleton Files Description

skel.ac Skeleton Task attribute catalog

skel.ctg Skeleton Task configuration table conversion script

skel.c Skeleton Task source code

skel.txt Skeleton Task error message translation file

skeleton.dsp Skeleton Task project file

skel.rc, skel.ico Skeleton Task icon for when it is minimized


(Windows only)

FactoryLink Programmer’s Access Kit / 21


• SKELETON TASK
• Integrating Skeleton into the FactoryLink System


I NTEGRATING S KELETON INTO THE F ACTORY L INK S YSTEM
Perform the following steps to integrate the skeleton development components:

1 Copy the Attribute Catalog skel.ac into the AC directory: {FLINK}\ac.

2 Make the Skeleton Task AC known to the FactoryLink system:

a) With a text editor, append a new line skel.ac to {FLINK}\ac\titles.


b) From the system prompt, execute {FLINK}\bin\acctmgr -c -d.

3 Copy the conversion script skel.ctg into the CT directory: {FLINK}\ctgen.

4 Copy the on-line configuration handling script skel.rtm to the CT directory: {FLINK}\ctgen.

5 Make the Skeleton Task conversion script known to the FactoryLink system. With a text editor,
add the line skel: skeltrig skeltags to {FLINK}\ctgen\ctlist.

6 Copy the translation file skel.txt into the message directory: {FLINK}\msg\{FLLANG}.

7 To verify the Skeleton Task is successfully integrated into the development environment,
perform these steps:

a) Create a new application (FLNEW).


b) Set the FLAPP environment variable to this application.
c) Open the Configuration Explorer.

22 / FactoryLink Programmer’s Access Kit


SKELETON TASK
Integrating Skeleton into the FactoryLink System

Verify the FactoryLink Integration


2
Perform the following steps to verify the integration:

1 In your application, open Other Tasks > Skeleton FL Task > Trigger Tags.

Skeleton Task
2 Create a row in the Triggers Tag table with the Table Name as A and the Trigger Tag as
skeltrig_a. Accept the defaults when creating the trigger tag.

3 Close the table and open System > System Configuration > System Configuration
Explorer in grid view. Again, configure a row for the Skeleton Task. Make the row the same
as the one pre-configured for the RTMON task, except set the tag dimension indices to the next
available slot. A common technique is to copy and paste the RTMON line and then change the
array indices and task specific fields to reflect the new skel task. Also, set the following fields
to the values shown.

Flags Task Name Description Executable File

FR SKEL Skeleton PAK Task bin/skel

4 Exit Configuration Explorer, run FLRUN, and then shut down the application. Verify this
sequence generates the file {FLAPP}\shared\ct\skel.ct.

You have now confirmed the successful integration of the Skeleton Task into the FactoryLink
system.

FactoryLink Programmer’s Access Kit / 23


• SKELETON TASK
• Integrating Skeleton into the FactoryLink System


Compiling and Executing the Skeleton Task
Use this procedure to confirm the run-time environment is functional and verified.

1 From the Windows Start menu, open either Microsoft Visual Studio (2000 or 2003) or
Microsoft Visual C++ 6.0.

2 Using the Microsoft development tool, open the Microsoft Visual C++ project: Skeleton.dsp.

If you are using Visual Studio, you will receive a message that prompts you to convert the
Microsoft Visual C++ 6.0 project. If this message appears, perform the conversion.

3 To start the compilation, select Build > Rebuild All.

The task is now compiled and ready to test.

Testing the Skeleton Task


1 To test the task, copy the executable from {FLINK}\src\skeleton\Debug\skel.exe to
{FLINK}\bin.

2 Run the application created earlier a second time to verify the task is functional.

3 When the graphics for the application are displayed, switch to the SHARED Run-time
Manager screen (either 1 or 2) that has the SKEL task listed. The screen indicates the
task is running.

4 To verify the SKEL task is working as expected, use RTMON to write a 1 to the skeltrig_a tag.
A message displays in the Skeleton Task Message field that effectively verifies the Skeleton
Task has read its configuration and is correctly processing it.

24 / FactoryLink Programmer’s Access Kit


Chapter 3





Run-Time Architecture
3

Run-Time Architecture
FactoryLink is a modular system of individual tasks that perform separate functions. These
tasks communicate and share data with one another through the Real-Time Database managed
by the FactoryLink Run-Time Manager and Kernel. This system provides the following
advantages over systems relying on real-time inter-process communications (IPC) through
passing buffers or sharing files:
• Tasks maintain their independence and inherent compatibility with one another.
• Data formats for interfaces will not change unpredictably as the maintenance programmer
changes.
• Tasks can hand off the inter-process communication to the database function, which acts as
an intermediary, meaning less time is spent waiting for another task to acknowledge
error-free receipt of data.
• Functions, conditions, or events can be related through the use of a common tag since each
task has access to the same global tags.

FactoryLink allows you to create custom applications by selecting, configuring, and linking
different programs to exchange information freely in real time.

FactoryLink operation involves the following:


• Run-Time Manager
• Kernel
• Real-Time Database
• FactoryLink Tasks
• Triggers
• Configuration Explorer
• FactoryLink Directory Organization ({FLINK})

FactoryLink Programmer’s Access Kit / 25


• RUN-TIME ARCHITECTURE
• Run-Time Manager


R UN -T IME M ANAGER
The Run-Time Manager supplied with FactoryLink orchestrates the run-time environment. It is
a FactoryLink task that runs concurrently with other tasks to start, monitor, control, and shut
down the concurrent execution of all FactoryLink tasks.

The Run-Time Manager reads the System Configuration table [sys.ct]to determine the startup
criteria for each task. The Run-Time Manager communicates with each task by sending
commands to and reading status information from the Real-Time Database. Each task must
monitor the command objects so the task shuts down when instructed to by the Run-Time
Manager.

The Run-Time Manager interacts with the other tasks within a specific domain through the
FactoryLink API and the Real-Time Database as shown in the following figure.

Run-Time Manager Data Flow Diagram

Run-Time
SYS.CT
Manager

Read Write

FactoryLink
Real-time
Database

Read Write

FactoryLink
*.CT Application
Tasks

Figure 3-1 Run-Time Manager Data Flow Diagram

26 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Kernel

F ACTORY L INK K ERNEL


3
The FactoryLink Kernel is a software module that creates the Real-Time Database in memory

Run-Time Architecture
and serializes access to the memory so tasks can communicate with each other. When you start
the FactoryLink Run-Time system, the Run-Time Manager creates the shared memory using
the Kernel Services. Other tasks also use the Kernel Services to access the shared memory as
they start.

Kernel Multi-User Capabilities


The following aspects of the FactoryLink Kernel allow multiple independent users of a
FactoryLink application:
• Provide global memory areas for real-time data
• Provide private, per-user memory areas for real-time data (an instance of the USER domain)
• Allow up to 31 tasks for each user’s instances’ collection of tasks
• Allow multiple applications to run simultaneously

USER and SHARED Domains

Domain

FactoryLink supports the concept of shared and private data areas by the separation of data
access into domains. The SHARED domain is the shared portion of the Real-Time Database
and the collection of shared processes that have access to that data. The USER domain is an
instance of the user Real-Time Database and the set of all the user processes having access to
that Real-Time Database. Multiple USER domains each have their own set of user processes.
Each can access both the SHARED Real-Time Database and the USER instance of the
Real-Time Database.

When FactoryLink runs, the entire Real-Time Database is created, including the SHARED
portion and all Real-Time Database USER instances. Next, the SHARED Run-Time Manager
initializes the SHARED Run-Time Database and starts the SHARED processes. As USER
instances start, each USER Run-Time Manager initializes its instance of the USER Real-Time
Database and starts an instance of all USER processes.

Within the starter and example application, default domain associations are made in the
System Configuration Table. These defaults determine which domain a task is associated with
at run time. Some tasks are associated with both SHARED and USER domains. Review the
default domain associations during application planning to verify they are compatible with
current needs. These default associations may be changed if an application has special
requirements.

FactoryLink Programmer’s Access Kit / 27


• RUN-TIME ARCHITECTURE
• FactoryLink Kernel


FactoryLink tasks use Real-Time Database tags to control tasks. User database tags are
duplicated for each FactoryLink user. The subset of the Real-Time Database duplicated on a
per-user basis is known as the USER domain.

The multi-user architecture allows duplicate USER domains by allocating an array of pointers
to database segments for each user. This allows the tag numbers (indices into the pointer array)
themselves to remain the same for each user while referencing a private data area for each user.

Some FactoryLink tasks monitor and control processes, such as a PLC driver task, that require
the process data values be the same for all users. The subset of the Real-Time Database shared
by all users is known as the SHARED domain.

Application Instances/Identification

Since multiple copies of a FactoryLink task may be running concurrently, a task must identify
itself to the Kernel. The task must specify the application, domain, and user instance as well as
the task name.

Each application instance is specified by its invocation name. The invocation name is a
character string of up to 16 characters. The invocation identifies an instance of the Real-Time
Database and is used to locate the memory segment the kernel is stored in. The Run-Time
Manager refers to the invocation name stored in the environment variable {FLNAME} and
stores it in the tags FLNAME_U or FLNAME_S, depending upon the domain.

The domain within an application is specified by the domain name. The domain name is a
character string of up to 16 characters and is used to determine which portion of the Real-Time
Database the task has access to: either the tags in the SHARED domain or tags in one of the
duplicate USER domains. In addition, the task uses the domain name to determine which CT
files should be processed. The Run-Time Manager refers to the domain in the environment
variable {FLDOMAIN} and stores it in the tag FLDOMAIN_U or FLDOMAIN_S, depending
upon the domain.

The user instance is specified by the user name. The user name is a character string of up to 16
characters and is used to determine which instance of the duplicate USER portions of the
Real-Time Database the task has access to. The Run-Time Manager refers to the environment
variable FLUSER and stores it in the tag FLUSER_U or FLUSER_S, depending upon the
domain. The FLUSER environment variable must be unique for each user of the application.

When a FactoryLink application is started, the Run-Time Manager must be supplied with the
invocation name, domain name, and user name on the command line or through environment
variables. All sub-processes the Run-Time Manager creates inherit these environment
variables.

28 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Kernel

Domain Tables
3
The domain table in the Configuration Explorer contains the definition of domains in the

Run-Time Architecture
application. Currently, two domains are supported: SHARED and USER. The definition of
these domains includes the number of allowed instances as well as domain-wide persistence
attributes.

The Configuration Explorer has a domain selection feature that must be set before tasks are
configured. The default is SHARED. If the run-time domain associations do not match the
configuration domain associations, the application will not run as intended.

Domain Associations

Domain designations are critically important. Before each task begins to run, the associated
domain is defined as an environment variable. Typically, the task inherits the environment
from the Run-Time Manager when the Run-Time Manager starts the task. This variable must
match one of the previously defined domain values. Two types of domain relationships are
possible:
• A task may be designed to run as SHARED. All tables and database tag are associated with
the SHARED domain. At run time the task runs as a shared entity with one set of tags for all
users.
• A task may be designed to run as USER. You have a private copy (domain instance) of the
task for every user. The tasks may use both the SHARED and USER Run-Time Database
tags. At run time all user domain instances are identical when generated; however,
individual user actions are independent, and the resulting data is stored in a Real-Time
Database unique to each operator.

FactoryLink Programmer’s Access Kit / 29


• RUN-TIME ARCHITECTURE
• FactoryLink Kernel


Application Example
The following example of one of numerous application configurations possible illustrates one
way a FactoryLink application may be configured.

Single Application/Multiple Users

In the following example, you have created an application that allows multiple operators to run
separate user instances of the same application in which each operator has his own USER
domain tasks and Real-Time Database.

USER

SHARED

USER

Figure 3-2 Domains: Single Application/Multiple Users

30 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Real-Time Database

F ACTORY L INK R EAL -T IME D ATABASE


3
The Real-Time Database is the area of the Kernel’s shared memory used to store the current

Run-Time Architecture
value of the application tags. It exists only in memory and does not persist between subsequent
invocations of the FactoryLink system.

The Real-Time Database is made up of arrays and pointers. Each array consists of up to 65535
tags of a single data type. Whenever you define an tag, the system prompts you to identify the
data type of the tag by choosing one of FactoryLink predefined data types. The following table
shows the storage capacities, ranges, and accuracies of each data type.

Storage in Storage in Value Range


Data Type Value
User Area Kernel Area and Accuracy

Digital (Boolean) 1 bit * 2 bytes 12 bytes 1 (ON) or 0 (OFF)


Analog (Short integer) 2 bytes * 2 bytes 14 bytes -32,768 to 32,767
(signed)
Long Analog (Long integer) 4 bytes 4 bytes 16 bytes -231 to 231 -1
Floating point (IEEE 8 bytes 8 bytes 20 bytes +/-10-308 to +/-10308
standard/double precision)
Message (String) 0 to 65535 0 to 65535 20 bytes per ASCII or arbitrary
bytes bytes message + storage binary data
of data
Mailbox (Variable- length 0 to 65535 0 to 65535 20 bytes per Arbitrary binary data
data, organized as a queue) bytes bytes message + storage
of data

Use the following formulas to determine memory requirements:

Formula = storage requirement for a tag defined for the SHARED domain:
(N - 4) + (4 x I)

where
N Is the storage in Kernel area from the table above.
I Is the number of instances (shared + user).

FactoryLink Programmer’s Access Kit / 31


• RUN-TIME ARCHITECTURE
• FactoryLink Real-Time Database


Example:
A SHARED domain long analog tag in a system with a maximum of two USER
instances:
[20 bytes (from table) - 8] + {8 x [1(shared) + 2 (user)]} = 40 bytes

Formula = storage requirement for a tag in the USER domain:


(N x I)

where
N Is the storage in kernel area from the table above.
I Is the number of instances (shared + user).

Example:
A USER domain floating-point tag in a system with a maximum of two USER instances:
24 bytes (from table) x [1 (shared) + 2(user)] = 72 bytes

The FactoryLink Kernel uses data types and tag numbers to read from or write to tags in the
Real-Time Database.

Structure of a Tag

A tag consists of the following items:


• One or more bits containing the tag value
• Set of change-status bits (change-status word)
• Set of wait bits (wait-status word)
• Set of reserved bits

FactoryLink pre-allocates a single bit to each potential client task in each of these status words.
Each domain instance has potentially 31 possible processes. The 32nd bit is a digital tag value
or unused.

Change-Status Bits

For each tag, one change-status bit exists for each potential client process. The read-call and
write-call functions use the change-status bits within the FactoryLink Kernel to indicate

32 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Real-Time Database

changes in a tag value. The value of the change-status bit can be either ON (equal to 1) or OFF
(equal to 0). 3

Run-Time Architecture
FactoryLink tasks write information to tags through either
• Write call
• Forced-write calls

Tasks use the Kernel Service’s write-call function to update a value of a tag. This function first
determines whether the tag value changed. If the new value differs from the old, the write-call
function sets each of the tag change-status bits to 1 and stores the new value in the tag;
however, if the comparison determines the new value for the tag is identical to the old, nothing
changes. This method saves processing time because tasks watching the tag will not waken to
process unchanged values.

Alternatively, the writing task can also use the Kernel Service’s forced-write function. This
function does not compare old and new values. Instead, the forced-write call function assumes
the tag has changed and sets all of the tag change-status bits to ON as it stores the new value,
even if the updated value being assigned to the tag is the same as the old. Forced writes are
useful when you need to trigger processes setting the tag change bit but do not wish to change
the actual contents of the tag or when an tag needs to be processed a second time, even if its
value has not changed.

Use write calls except when the forced-write is specifically needed.

FactoryLink tasks read information from tags through


• Read calls
• Change-read calls
• Change-wait calls

The read-call function always returns the current value of the tag to the calling process
regardless of the value of the tag change-status bit assigned to that process.

When a task makes a change-read-call, the reading task requests change-status information
about specific tags. If the function finds that the change-status bit of a tag has been set since it

FactoryLink Programmer’s Access Kit / 33


• RUN-TIME ARCHITECTURE
• FactoryLink Real-Time Database


was last read, the function informs the calling task it has found a changed tag and returns the
value of the first changed tag found. If the change-status bits have not been set since the last
read for any of the specified tags, the change-read-call function returns a code indicating this to
the calling task. This method blocks the calling routine’s processing for less time than reading
and comparing the values of all the tags.

When a task makes a change-wait call, the reading task uses the change-wait-call function
within the Kernel to request change-status information about specific tags. Once a task makes
its call, the task then hibernates while waiting for a tag to change. When a task is asleep, it uses
no CPU cycles. The task wakes when any one of the specified tags have changed and/or have
had their change-status bits set to 1 by another task since the last reading. In other words, this
call blocks the calling process until at least one of the specified tags change-status bits are
toggled.

Regardless the method of reading a tag, the act of reading a tag resets the tag change-status bit
associated with the reading task to OFF by writing a 0 to the task change-status bit in the tag.
As successive tasks read a tag, they toggle the change-status bits in the tag, one by one, to OFF.

The Kernel maintains the change-status bits in a manner transparent to the tasks; however, you
can use these bits in the Math & Logic task.

For example, you can write a Math & Logic procedure that uses the ? operator to determine
whether the value of a tag has changed and then take an action.

Change-status bits optimize system performance in the multi-tasking environment.


FactoryLink tasks use change-status bits as exception flags and the Kernel acts as an exception
processor.

Caution: Exception processor terminology is uniform across all


FactoryLink documentation and should not be confused with
the traditional use within the industry of the term exception
processing to mean error handling or CPU exception
recovery.

This allows FactoryLink tasks to perform functions on an exception-only basis or only on


those tags whose values have changed rather than continuously reprocessing unchanged
information. This method results in increased software performance.

Wait bits: For each tag, one wait bit exists for each possible client process. When the client is
currently waiting to read the specified tag, the value of the bit is 1; otherwise, the value is 0.

34 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Tasks

F ACTORY L INK TASKS


3
FactoryLink tasks are programs that read from and write to the Real-Time Database allowing

Run-Time Architecture
for an exchange of information among the tasks. You use the configuration tables to specify the
tags each task reads or writes. A task is only aware of the tags it is reading and writing, not of
other tasks; therefore, it does not know which task wrote the data it is reading from the
database nor can it know which task is reading the data it is writing to the database.

An application task calls functions to perform the following FactoryLink operations involving
the Real-Time Database:
• Lock the database
• Unlock the database
• Read one or more database tags
• Write one or more database tags
• Determine whether a database tag has been modified by another task since it last read the
tag
• Sleep until any one member of a list of specific database tags is modified
• Access miscellaneous utilities

How FactoryLink Tasks Transfer Data


Data transfer is based on reads, writes, and change reads of information in the Real-Time
Database. All information, either transmitted to or collected from outside sources, goes
through the Real-Time Database on its way to its final destination.

Any task can use any tag in the Real-Time Database as long as the data type and domain of that
tag matches the type required for the indicated operation. It is possible— even beneficial— for
two tasks to use the same tag. When this occurs, both tasks share the information stored in the
tag.

Although some tasks may only read or write to tags, most tasks have both read and write
access to the tags. Remember all tags are global, so any task can use any tag as long as that tag
data type matches the type required for the indicated operation. It is possible for two tasks to
use the same tag, sharing responsibility for updating the information stored in the tag.

It is important to plan and configure the system so read and write operations to the Real-Time
Database are predictable. For example, if two tasks are configured to write simultaneously to
the same tag, it is impossible to know which task is responsible for the data in the tag. Even
though it is sometimes desirable to have such a capability, most applications should be
designed so only one writer task and one or more reader tasks function for any particular tag.

FactoryLink Programmer’s Access Kit / 35


• RUN-TIME ARCHITECTURE
• FactoryLink Tasks


Transfer Methods

FactoryLink transfers data in three ways:


• Reading data from the Real-Time Database
A task reads the value of a tag in the Real-Time Database to display it on a screen, transmit
it to an external device, or send it along to another task.
• Writing data to the Real-Time Database
A task writes information to a tag in the Real-Time Database as the result of an operator
input, a read of an external device, or an input from another task.
• Change-read operations
A change-read operation is a block read of the Real-Time Database that returns only those
tags whose values have changed since the last read operation. This is known as exception
processing. The flags contained in the structure of FactoryLink tags make this possible.
Change-reads optimize system performance because large blocks of data can be checked for
change and because only the changed values are processed.

Data Transfer Examples

Reads, writes, and change-reads are generally performed in combinations.

Example 1. When you enter a new value from the keyboard, the Graphics Task gets the value
and writes it to the tag associated with the input object.

Example 2. The Graphics Task uses a change-read function that executes in a loop to
determine whether tag values linked to a screen display have changed. The function informs
the task if no values have changed. The function returns the new value for the changed tag
from the Real-Time Database if a value has changed. At the completion of the execution of the
loop, the task relinquishes the CPU to another process or task.

Example 3. The Batch Recipe task is configured to read values from a file and write them to
associated tags in the Real-Time Database or read tags from the database and write their values
to a file on the disk.

Example 4. A programmable controller task reads values from the programmable controller
and writes them to the Real-Time Database. It can also read values from the Read-Time
Database and write them to the programmable controller.

36 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Tasks

How FactoryLink Architecture Affects New Task Development


3
The following illustrates FactoryLink architecture.

Run-Time Architecture
Overview of FactoryLink Architecture

ASCII Application
/{FLAPP}/, MPS (ASCII)

FLSAVE/FLREST *Attribute
Catalogs
/{FLINK}/BIN/ /{FLINK}/AC/*.AC

FactoryLink
Configuration
Manager
Configuration *Key Word Files
Database Tables /{FLINK}/Key/{FLLANG}/*.KEY
/{FLAPP}/

*ConfigurationTable
FLRUN
/{FLINK}/BIN/ Generator Scripts
CTGEN.EXE /{FLINK}/CTG/*.CTG

Starts Run-Time Manager


Configuration Tables
(Binary)
/{FLAPP}/{FLDOMAIN}/
CT/*.CT SYS.CT

TASK.CT

*Source Run-Time
Manager
Starts other
task
Compile & Link
/{FLINK}/BIN/TASK.EXE
FactoryLink
FLIB Task
Real-Time
/{FLINK}/INC/ Database
/{FLINK}/LIB/

* Denotes user-written with any text editor

FactoryLink Programmer’s Access Kit / 37


• RUN-TIME ARCHITECTURE
• FactoryLink Tasks


The following table describes each part of the illustration, beginning with the upper left
portion.

Item in Illustration Description

ASCII Application Any application can be saved to enable the


importing/exporting of configuration data from one
application directory to another (typically, from one platform
to another).

FLSAVE/FLREST Utilities used to save/restore an application. For more


information, see the FactoryLink Utilities Guide.

Configuration Database Tables that store information about the Real-Time Database
(.CDB) tags. You must design these tables as part of task development.
In this guide, configuration database tables are referred to as
database tables.

FactoryLink Configuration Development system tool used to set up or configure an


Explorer application.

Attribute Catalogs (.AC) Programmer-created ASCII text files that describe the
database tables and the editing criteria for operator-entered
data.

Key Word Files (.KEY) ASCII text files that 1) delimit valid entries for a database
table field; and 2) provide binary value for conversion by
CTGEN.

FLRUN Command that executes the FactoryLink Software System


including the custom application. This command starts the
Run-Time Manager task.

Configuration Table Programmer-created script files that tell the CTGEN utility
Generator Scripts (generate binary CT files) how to extract data from the
database tables and combine it to produce a binary
Configuration Table (CT) file at run time.

Configuration Tables Binary files produced by the CTGEN utility at run time
(Binary) (.CT) containing data extracted from the database tables.

Source Programmer-developed source code for a task.

Compile and Link Step to compile source code into object code and link object
modules.

38 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Tasks

Item in Illustration Description 3

Run-Time Architecture
FLIB FactoryLink library. Collection of utility functions serving
primarily to interface application and system programs to the
FactoryLink Kernel.

Task Task that performs a required operation. Up to 31 tasks,


including the Run-Time Manager, may be active concurrently
per domain instance.

Run-Time Manager Task that monitors and controls other FactoryLink tasks using
the services of the Real-Time Database.

FactoryLink Real-Time Memory-resident array of information that exists only at run


Database time.

Only portions of the FactoryLink architecture affect you directly. You must design the database
tables for the task. These tables contain all information required to completely describe the
application with the possible exception of operator-entered menu selections and/or commands.

Once the design is final, you must create an Attribute Catalog file for one or more database
tables. The Attribute Catalog file represents an option in the Configuration Explorer. If the
Attribute Catalog file references a KEY file, you must create a KEY file that provides the
Configuration Explorer with information on developer-entered keywords placed in the
database tables. Then, you must open the Configuration Explorer and use it to test whether the
Attribute Catalog file(s) and, if used, the KEY files, accurately reflect the desired database
table design and editing requirements.

At run time the Run-Time Manager starts and the database tables are converted into one or
more sorted binary files known as a CT file(s). When a task begins running, it reads its CT file
to determine the tags to open and the actions to perform on those tags. You must write a
configuration table generator script that describes how to extract data from the database tables
and produce the CT file at run time.

The custom-developed program describes how the custom-developed task functions in relation
to other tasks, including the Run-Time Manager.

FactoryLink Programmer’s Access Kit / 39


• RUN-TIME ARCHITECTURE
• Triggers


TRIGGERS
Many FactoryLink tasks use digital tags to trigger certain actions. Events, such as read or write
operations, can be configured to occur as the result of a combination of bit value and
change-status flag value in a trigger tag. A trigger tag can be used as a trigger by more than one
task.

Two conditions must exist for a tag to trigger an event in existing FactoryLink tasks:
• Value of the tag must be 1.
• Value of the change-status flag being read must be non-zero.

Note: Remember: trigger conditions are task dependent.

When a task reads a trigger tag, the reading task sets its change-status flag to 0 and begins the
operation designated by the trigger if the tag value is 1 and has changed since the last time it
was read.

Forced-writing a 1 to a digital tag, even though it may not change the actual value of the tag (if
the tag was already equal to 1), causes the events tied to that trigger to be triggered during the
next read operation. If multiple tasks are to use the same tag as a trigger, using the forced-write
technique simplifies inter-task handshaking requirements.

You use trigger tags in many ways:


• Define Interval and Event Timer digital tags in the Real-Time Database for use as triggers
• Configure function keys as triggers
• Initiate a Math & Logic procedure by having Math & Logic create triggers of any data type
• Report or log data
• Read and write recipes
• Execute another program
• Cause a screen to be printed
• Initiate a network transfer
• Cause a new setpoint to be downloaded to a programmable controller
• Trigger separately each polled read function used by a programmable controller task

40 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
Configuration Explorer

C ONFIGURATION E XPLORER
3
The Configuration Explorer is a development system program used to set up or configure a

Run-Time Architecture
FactoryLink application. It is used only for system configuration and application development.

You create an application by specifying the tags created for each task and the actions each task
performs on these tags. In the Configuration Explorer, you enter data in one or more database
tables for each task. The Configuration Explorer normally opens a default table editor that
provides a data entry table for each of the database tables; however, the Configuration Explorer
may open specialized editors to handle non-textual configuration.

Advantages of using the Configuration Explorer include reduction of development time for an
application and having the same developmental look and feel as standard FactoryLink tasks.

FactoryLink Programmer’s Access Kit / 41


• RUN-TIME ARCHITECTURE
• FactoryLink Directory Organization


F ACTORY L INK D IRECTORY O RGANIZATION
The following files are located in the {FLINK} directory. The subdirectories containing
program files are organized as follows.

Subdirectory File(s) Description of File(s)

\AC *.AC Text files that function as


Attribute Catalogs to inform the
Configuration Explorer of the
format of the database tables and
to determine editing entry criteria.

\BIN Command files, executable


program files, and related support
files for each task.

\BLANK Blank {FLAPP} directory used by


the FLBLANK utility to create a
new application.

\CML * Compiled Math & Logic files.

\CTGEN *.CTG CT script files.

\DLL\en *.DLL Contains language specific DLL


\DLL\fr files.
\DLL\de

\EDI … /* Subdirectory for External Device


Interfaces (PLC drivers).

\INC *.H Header files for C programs.

\INSTALL Files used during installation.

\KEY\en *.KEY Text files that tell the


\KEY\fr Configuration Explorer how to
translate text table entries into
\KEY\de
binary values to be placed in a
configuration table (CT) for the
specified language.

42 / FactoryLink Programmer’s Access Kit


RUN-TIME ARCHITECTURE
FactoryLink Directory Organization

Subdirectory File(s) Description of File(s) 3

Run-Time Architecture
\LIB *.LIB (WIN& ) Library files.
*. a

*.DLL WIN Dynamic link library files.

\MPS\en *.MPS Multiplatform save files for the


\MPS\fr specified language.
\MPS\de

\MSG\en *.TXT Message files for tasks.


\MSG\fr
\MSG\de

\RPT *.FMT Report formats.

\SRC … /* Programmer's Access Kit files.

FactoryLink Programmer’s Access Kit / 43


• RUN-TIME ARCHITECTURE
• FactoryLink Directory Organization

44 / FactoryLink Programmer’s Access Kit


Chapter 4





FactoryLink Configuration
Architecture 4

Configuration
Architecture
This chapter highlights the following aspects of constructing tasks and integrating them with
the rest of the FactoryLink system:
• Configuring FactoryLink
• FactoryLink Application Directory ({FLAPP})

C ONFIGURING F ACTORY L INK


Configure FactoryLink by filling in configuration panels (tables) associated with different
FactoryLink tasks. Define one or more tags, assigning each a symbolic tag name and enter
other static information required to define the function of the tag(s). For instance, in the
Interval Timer Information table, you define a tag with the symbolic tag name sec1 and a
value specifying the length of time between intervals. The tag name serves to link the interval
timer tag to other FactoryLink tasks by making the state of the timer tag accessible by other
tasks.

This information allows tasks to read data from and write data to the Real-Time Database,
providing developer-configurable communication links between FactoryLink tasks.
Establishing these links is the essence of creating a FactoryLink application.

Enter information in a table by opening one or more screen displays or tables that provide
predefined entry fields for information required for the task to function.

In general, two types of tables are used:


• Control tables
• Information tables

FactoryLink Programmer’s Access Kit / 45


• FACTORYLINK CONFIGURATION ARCHITECTURE
• Configuring FactoryLink


• In a control table, enter information that identifies and/or initiates an operation, such as a
read or write.
• In an information table, enter specific information about the values used in the operation
defined in the control table.

This is how the control and information tables for a particular task are related. In the following
sample Control table, specify types and priorities of read and/or write operations performed.

Then, enter the DDE item names read or written and the names of RTDB tags to receive or
supply information from/to the DDE source (Microsoft Excel spreadsheet) in the following
sample Information table, which is associated with the previous Read/Write control table.

A task may require both Control and Information tables or just an Information table.

Tag Names

Each tag has a unique, developer-defined, symbolic tag name. You assign these tag names, one
for each tag used in the application during system configuration and the system stores them in
a separate predefined data file. Tag names are linked at run time with pointers to their
associated tags, allowing their use by any task. Because the Real-Time Database is completely
memory-resident and is organized as arrays and pointers when loaded at run time, FactoryLink
does not have to keep track of tag names stored as text strings. This, in part, accounts for
FactoryLink’s high processing speed.

Tag name assignment: During configuration you create and assign a tag name to a tag by
defining at a minimum its name, data type, and possibly its domain dimension. If the tag you
referenced does not exist, the system automatically creates it. Once a tag has been defined in

46 / FactoryLink Programmer’s Access Kit


FACTORYLINK CONFIGURATION ARCHITECTURE
Configuring FactoryLink

this way, other tasks refer to this tag using its tag name, reading or writing data to or from the
tag at run time. 4
Valid tag names conform to the following grammar:
[<node>:]<name>[<dims>][.<ext>]

Configuration
Architecture
where
<node> Is limited to 8 characters.
<name> Is limited to 32 characters.
<dims> Is limited to 16 characters.
<ext> Is limited to 16 characters.

The maximum tag name length, including <node>, <name>, <ext>, and the separators : and .
is 32. Legal characters for the <node>, <name>, and <ext> strings are
• {A-Z}
• {a-z}
• {0-9}
• {@$_}

These strings cannot begin with a number or contain spaces.

Users cannot directly create a tag name with extensions, such as abc.mymember. These are
considered member tags. The Application Editor creates these automatically through the tag
definition notebook. Currently, only member tags related to scaling and deadbanding are
supported.

Syntax Samples
• Sample tag name: plc_readval
• Sample remote tag name: serverl:plc_readval
• Sample arrayed tag name: plc_readval[5][6]
• Sample member tag name: plc_readval.raw
• Sample remote, arrayed, member tag name: node name plc_readval [5][6].raw

Arrayed Tags
A tag array is a block of tags of the same type. As such, it frees the developer from having to
define large numbers of scalar tags separately. Certain FactoryLink tasks, such as Math &
Logic and Database Browser, can detect the arrayed property of a tag and can access the entire
tag array when given a reference to just one of its tags.

FactoryLink Programmer’s Access Kit / 47


• FACTORYLINK CONFIGURATION ARCHITECTURE
• Configuring FactoryLink


Defining Tag Arrays

Define tag arrays in a configuration table by using at least a two-part tag name. A two-part tag
name consists of an alphanumeric string (the arrayed tag name) followed by one set of square
brackets containing an integer (array index) for each dimension of the array. Dimension refers
to the capacity or size of the array. If an array has more than one dimension, it is called
multi-dimensional, and each tag will have as many array indices as the array has dimensions.
Think of the Cartesian coordinate system in which both vertical and horizontal indices are
specified to pinpoint a position on the spatial grid. A two-dimensional array is an array in
which each of the tags is also an array and its tags are referenced by [row,column] pairs.

The array dimensions defined within the square brackets are the sizing factors that determine
the number of tags in an array. For example, if you specify the size of a one-dimensional tag
array is 5, the Real-Time Database creates five separate tags referenced individually or as a
group. Their array tag names are the same, but they have different array indices.

The following is a sample arrayed tag name:


set_temp[2][1]

Each set of square brackets represents a dimension or spatial characteristic of the tag array,
such as length, width, or height. When you define a tag array in a configuration table, a dialog
displays showing default sizes for each dimension you can modify before pressing Enter.

The size of a default dimension is always one larger than the integer specified in the tag name
brackets because C arrays are indexed from zero to the specified dimension. For example, if
the tag name is tagname[0][0], the default dimension sizes displayed in the dialog are 1,1. If
the tag name is tagname[4][6][3], the default dimension sizes are 5,7,4.

This also means that arrays are indexed beginning at zero. For example, tagname[0] is the first
tag of the array tagname.

The number of array dimensions and the number of tags allowed in an array are constrained in
two ways:
• The tag name field limits the size of the array dimensions. Sixteen characters are allowed in
the dimension portion of a tag name. For example, the array tag name
tempset[3][1][10][1][1] contains 7 characters in the tag name portion (first field) and 16
characters (the maximum) in the dimension portion. The 16-character limit in the dimension
field allows you to specify up to five dimensions, assuming most of the dimensions are
single-digit.
• You can create tag arrays containing up to 64K (65535) numbers of tags.

Use the following formula to determine the number of tags created in an array with a given set
of dimensions:

48 / FactoryLink Programmer’s Access Kit


FACTORYLINK CONFIGURATION ARCHITECTURE
Configuring FactoryLink

axbxc
4
where
a Is the size of the first dimension.
b Is the size of the second dimension.

Configuration
Architecture
c Is the size of the third dimension.

If an array contains more than three dimensions, use the same method to multiply by the sizes
of the additional dimensions.

Example 1: Defining a One-dimensional Tag Name

If you define a one-dimensional tag name


tagarray[0]

the default size of the dimension displayed in the dialog is


1

If you modify the size of the dimension to


5

five tags are created with the following tag names:


tagarray[0]
tagarray[1]
tagarray[2]
tagarray[3]
tagarray[4]

Enter tagarray[index number] in the table for each tag referenced to reference individual tags in
the array.

Example 2: Defining a Two-dimensional Tag Name

If you define a two-dimensional tag name as


msg_tag[1][1]

the default sizes of the two dimensions displayed in the dialog are
2,2

FactoryLink Programmer’s Access Kit / 49


• FACTORYLINK CONFIGURATION ARCHITECTURE
• Configuring FactoryLink


If you modify the sizes of the dimensions to
3,2

six tags are created with the following tag names:


msg_tag[0][0]
msg_tag[0][1]
msg_tag[1][0]
msg_tag[1][1]
msg_tag[2][0]
msg_tag[2][1]

Enter msg_tag[index1][index2] in the table for each tag referenced to reference individual tags
in this array.

Example 3: Using a One-dimensional Array

Suppose you need to define message tags whose values indicate the colors the cars on one
conveyor belt are painted. If 300 cars are painted on the conveyor belt and tag arrays are not
used, you must define 300 tags individually. With tag arrays, however, you define only one
two-part tag name and specify that the name contains 300 tags by entering 299 (creating tags 0
to 299) inside the brackets, as in
color[299]

Set the integer ([299]) sizing the single dimension of the tag to one less than the desired
number since tags are numbered beginning at index zero (0). Here, the desired number of tags
(299 + 1 or 300) are created under one tag name, as in
color[0]
color[1]
color[2]
.
.
color[299]

Example 4: Using a Two-dimensional Array

Suppose you want to define tags to indicate the colors cars on three conveyor belts are painted.
You can define a two-dimensional tag array by entering one tag name, such as
paint[299][2]

50 / FactoryLink Programmer’s Access Kit


FACTORYLINK CONFIGURATION ARCHITECTURE
Configuring FactoryLink

The integer ([299]) for the first dimension indicates one fewer than the number of cars on each
conveyor. The integer ([2]) for the second dimension indicates one fewer than the number of 4
conveyors. As a result, the correct number of tags [(299 + 1) X (2 + 1) or 900] are created
under one tag name, as in
paint[0][0] paint[0][1] paint[0][2]

Configuration
Architecture
paint[1][0] paint[1][1] paint[1][2]
paint[2][0] paint[2][1] paint[2][2]
paint[3][0] paint[3][1] paint[3][2]
. . .
. . .
. . .
paint[299][0] paint[299][1] paint[299][2]

Example 5: Using a Three-dimensional Array

Suppose you must define tags whose values indicate the colors that cars on three conveyor
belts and trucks on three conveyor belts are painted. You can define a three-dimensional tag
array using one tag name as in
car_truck[299][2][1]

The third dimension ([1]) indicates the type of automobile. In this example, 1,800 tags are
created under one tag name as in
(299 + 1) X (2 + 1) X (1 + 1) = 1800

The three-dimensional array may be thought of as a cube of indexed tags with each tag having
an (x,y,z) coordinate reference, such as depth, vertical position, and horizontal position.

FactoryLink Programmer’s Access Kit / 51


• FACTORYLINK CONFIGURATION ARCHITECTURE
• Configuring FactoryLink


Tag Descriptions
A description includes optional information about the tag defined or referenced with a tag
name in a data entry table. When you enter a reference to a new tag and click Enter, the system
prompts you to define the tag. Tag definitions can include a description of up to 80 characters.
Two methods for changing descriptions are available:
• Open the Tag List in the Configuration Explorer and modify the description field.
• Place the cursor in the tag name field on the table where the field has been defined and press
Ctrl-T. The Tag Definition dialog displays, allowing you to change information about this
tag including its description.

Tag Name Storage


Tag names are stored in the {FLAPP} directory in the OBJECT database table.

Each task can have tables with tags referenced by name. These tables are converted to binary
configuration table files (CT files) and, at run time, the typical FactoryLink application
program reads its configuration table files and makes calls to read and/or write tags identified
by the tag numbers and data types listed in the CT files.

Predefined Tags
The FactoryLink starter application FLNEW comes with a set of predefined tags for internal
use. These also serve as a convenience so you can use these when configuring tasks.
Predefined tags in the USER domain contain a unique extension to the identifier of _U.

Configuration Database Tables

The model for data entered and managed by the Configuration Explorer is a set of relational
database tables including:
• DOMAIN
• TYPE
• OBJECT
• XREF
• Task-Specific

The DOMAIN, TYPE, OBJECT, and XREF database tables are reserved system tables and are
not developer-definable. The task-specific database tables, however, are developer-defined and
are only present when that task is used in the application.

52 / FactoryLink Programmer’s Access Kit


FACTORYLINK CONFIGURATION ARCHITECTURE
Configuring FactoryLink

The database tables form a set of relational databases as follows.


4
DATABASE TABLES

Configuration
Architecture
DOMAIN

TYPE

OBJECT

XREF

Task 1 Task 1 Task 2


Table 1 Table 2 Table 2

TYPE
The TYPE database table defines the segments that consist of one of the six data types and one
of the domains used in FactoryLink. Each of these types corresponds to a record in the TYPE
table.

Type Description
DIGITAL Boolean value (on or off).
ANALOG 16-bit signed integer.
LONGANA 32-bit signed integer.
FLOAT double precision floating point.

FactoryLink Programmer’s Access Kit / 53


• FACTORYLINK CONFIGURATION ARCHITECTURE
• Configuring FactoryLink


Type Description
MESSAGE Variable length binary or ASCII data.
MAILBOX Variable length data, organized as a queue.

OBJECT
The Configuration Explorer maintains the Real-Time Database tag definitions for each
application in the OBJECT database table. Knowledge of the format is generally not required
to add a new task. The OBJECT table contains a list of real-time tags defined by the developer,
but it does not contain task-specific information. Task-specific information is kept in other
tables related solely to that task.

XREF
The Configuration Explorer maintains a cross-reference table. The XREF database table
contains a record for each occurrence of a tag in any task-specific table. This information
allows the Configuration Explorer to locate all occurrences of a particular tag in the
task-specific tables quickly.

Task-Specific
A task consists of one or more developer-definable task-specific database tables. There is no
limit on the number of tables per task. If a task has more than two tables, the tables may be
related either serially or in a one-to-many fashion.

For example, suppose a PLC task consists of a Write table and a Read table. The Write and
Read tables each consist of a Control table and an Information table. The Control table
contains header records specifying the trigger information for a group of data records. The
control and information records are stored in different tables because they have different
structures.

54 / FactoryLink Programmer’s Access Kit


FACTORYLINK CONFIGURATION ARCHITECTURE
{FLAPP} Application Directory

{FLAPP} A PPLICATION D IRECTORY


4
The following files are located in the {FLAPP} directory. The subdirectories containing
program files are organized as follows.

Configuration
Architecture
Subdirectory File(s) Description

*.CDB Database tables that store information about the tags such
as name, type, number of definitions (number of writes
specified by the defining task), number of references, and
task specific information.

*.MDX Indexes used by the Configuration Explorer in


conjunction with the CDBs to order the CDB information.

\ASC *.ASC ASCII database tables that store information about the
Real-Time Database tags and task specific information.
They are used to import/export configuration data from
one application directory to another (typically, from one
platform to another platform).

*.EXP Output of CM export.

\CT *.CT Binary configuration tables. Each FactoryLink program


employs one or more configuration tables.

\LOG Error log files produced by FactoryLink processes at run


time containing debug information.

\NET GROUPS Groups on this node.

LOCAL FLLAN information.

\PROCS *.PRG Math & Logic procedures.

\RCP Files created by the Batch Recipe task.

\RPT *.RPT Report files generated by the Report Generator task.

\SPOOL Subdirectory used by the FactoryLink Print Spooler task.

FactoryLink Programmer’s Access Kit / 55


• FACTORYLINK CONFIGURATION ARCHITECTURE
• {FLAPP} Application Directory


The following files are located in the {FLAPP} directory and/or the {FLAPP}\{FLDOMAIN}
directory where the {FLDOMAIN} is either SHARED or USER. The subdirectories containing
program files are organized as follows.

Subdirectory File(s) Description

\ASC *.ASC ASCII database tables that store information about the
tags. Used to import/export configuration data from one
application directory to another (typically, from one
platform to another).

*.EXP Output of CM export.

\CML Compiled Math & Logic files.

\CT *.CT Binary configuration tables. Each FactoryLink program


employs one or more configuration tables.

\DCT External Device Interface CT files.

\DRW *.G* Graphics and PowerVB files created with the Application
*.PL* Editor and used by Run-time graphics files.

\LOG Error log files produced by FactoryLink processes at run


time containing debug information.

\NET GROUPS Groups on this node.

LOCAL FLLAN information.

\PROCS *.PRG Math & Logic procedures.

\RCP Files created by the Batch Recipe task.

\RPT *.RPT Report files generated by the Report Generator task.

\SPOOL Subdirectory used by the FactoryLink Print Spooler task.

56 / FactoryLink Programmer’s Access Kit


Chapter 5





Constructing a FactoryLink
Task 5

FactoryLink Task
Constructing a
This chapter details the procedure for constructing tasks and integrating them with the rest of
the system. Topics include:
• Overview
• Guidelines for Task Design
• Creating the Configuration Environment
• Run-Time Requirements
• Task Program Skeleton

FactoryLink Programmer’s Access Kit / 57


• CONSTRUCTING A FACTORYLINK TASK
• Overview


O VERVIEW
We recommend you follow the top-down software design model illustrated in the following
flow chart even though you are not required to follow any particular process when constructing
tasks.

58 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Overview

The top-down software design model consists of three major tasks:


• Setting up the Configuration Environment 5
• Converting Database Tables to CTs

FactoryLink Task
• Writing the Run-Time Task

Constructing a
Setting up the Configuration Environment
Setting up the Configuration Environment includes four steps:

1 Design the Database Tables(s).

2 Create the Attribute Catalog(s).

3 Create the KEY Files.

4 Test the Configuration Environment.

Design the Database Table(s)

Designing the database table(s) for the task involves laying out the table(s) opened in
Configuration Explorer, where you enter configuration information for the task. Designing
these tables involves mapping the work performed into a set of relational databases.

With the possible exception of operator selections and/or commands entered at run time, the
database table contains the information the task program needs to do its job. For example, it
serves as the storage area for the user-entered inputs when you select this task.

A table consists of one or more fixed-length database records. Each table is associated with an
index to control the logical order of the records. The task may require more than one table to
describe the work to be performed. These database tables can be related or unrelated to each
other.

Create the Attribute Catalog(s)

Create at least one Attribute Catalog (with extension .AC) for each set of database table(s) to
describe the structure of this table. In addition, it lists the table(s) displayed when the user
chooses this task.

An AC file is an ASCII text file that may be created and edited with an ordinary text editor,
such as Notepad. It tells the Configuration Explorer the format or structures of the records,
how to interpret operator input, and how to fill in the fields of the records.

Place the AC file(s) in the {FLINK}/AC directory that contains AC files for all FactoryLink
tasks. Create the translation file for the AC headings.

FactoryLink Programmer’s Access Kit / 59


• CONSTRUCTING A FACTORYLINK TASK
• Overview


Create the KEY Files

If necessary, create any KEY files referenced by the Attribute Catalog(s) or the Table file(s).
Create the KEY file(s) with a text editor, such as Notepad. Limit the alpha-numeric strings to
32 characters. This file tells the Configuration Explorer how to validate operator-entered key
words to be placed in the database table. After the KEY file(s) have been created, place them in
the /{FLINK}/KEY\EN, /{FLINK}/KEY\FR, or /{FLINK}/KEY\DE directory. Example KEY files:
flink\key\en\example.key

NULL -1 NULL
NO 0 NO
YES 1 YES
N 0 N
Y 1 Y
SLW 1 SLW
FST 2 FST

flink\key\fr\example.key

NULL -1 NULL
NON 0 NO
OUI 1 YES
N 0 N
O 1 Y
LENT 1 SLW
RAPIDE 2 FST

flink\key\de\example.key
NULL -1 NULL
NEIN 0 NO
JA 1 YES
N 0 N
J 1 Y
LANGSAM 1 SLW
SCHNELL 2 FST

60 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Overview

Test the Configuration Environment


5
Inform FactoryLink about the new task by adding the name of the AC file to the TITLES file.

FactoryLink Task
Constructing a
Using the Configuration Explorer, test the configuration environment, including the Attribute
Catalog.

Once errors or problems are analyzed and corrected, choose the task, entering a variety of
simulated data in the table(s) to be stored in the newly-created database table(s).

Convert Database Tables to CTs

When converting database tables to CTs, you must write a configuration table generator (CTG)
script that tells the CTGEN utility (generate binary CT files) how to extract data from the
database tables and combine it to produce a binary Configuration Table (CT) file. You must
also verify the script performs the desired conversion.

Writing the Run-Time Task

Ultimately, an executable must be created that reads the configuration information entered into
the task configuration databases (CDBs) and later converted into binary configuration tables
(CT). This involves writing a C program that invokes the methods provided by the
FactoryLink library.

You must remember certain high-level concepts during the design of a custom task. Proper
design enables the task to coexist efficiently with other FactoryLink programs. In addition,
designing to the PAK guidelines provides an upgrade path to other operating systems.

The following guidelines enhance your design process:

• Tasks should be designed to run concurrently with system configuration.

A custom program should not adversely affect or otherwise interfere with concurrently
running tasks, directly access system resources, such as I/O devices under the control of the
operating system, or severely degrade the performance of FactoryLink.

• Tasks should be designed to cooperate with the Run-Time Manager.

The program must conform to certain requirements imposed by the Run-Time Manager in
order for the latter to carry out its supervisory duties effectively.

FactoryLink Programmer’s Access Kit / 61


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


C REATING A C ONFIGURATION E NVIRONMENT
This section provides details for setting up the configuration environment that includes the
following tasks:
• Design the Database Table(s)
• Create the Attribute Catalog(s)
• Create the KEY Files
• Add AC File Names to TITLES file
• Test the Configuration Environment

The following figure illustrates the portion of the Task Construction Flowchart involved in
setting up the configuration environment.

62 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

Design the Database Table(s)


5
When you construct a task for a custom application, you must design one or more database
tables.

FactoryLink Task
Constructing a
Designing the Task-Specific Database Table(s)

Designing the task-specific database table(s) is the first step in task construction. The design
process should include the following considerations:
• What type of data is required for this task?
• What data must be stored in this task-specific database table.
• What other tasks require information supplied by this task?
• Are both Control and Information tables required or just an Information table?
• What is the table design, including the following items:
• Name of the table
• Table layout, such as column headings and order of information
• Data type of any tag to be entered on the table
• Editing validation required for a field, such as data type limitation or value- range check

Relationship Between OBJECT and Task-Specific Tables

Task-specific tables contain information for the Configuration Explorer to add to the other
run-time tables on behalf of the task. For example, the Alarm Supervisor configuration allows
the specification of a tag to be monitored for an alarm condition. In addition to the tag, you can
also specify alarm messages and limits. The Configuration Explorer adds the tag to the
OBJECT table if it has not already been created. In addition, the Configuration Explorer adds
the tag name and task-specific information to the Alarm Supervisor table.

Relationship between DOMAIN and Task-Specific Tables

Tasks run in one or more domains. The configuration for these tasks are normally unique per
domain; therefore, a domain is associated with each record entered into the configuration
database. Configuration in one domain is not accessible to the task executing in another
domain.

Caution: On the rare occasion a task configuration applies to all


domains, it is legal to omit specifying a domain with each
record. Be aware, however, that configuration without a
domain cannot reference any FactoryLink tags.

FactoryLink Programmer’s Access Kit / 63


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Create the Attribute Catalog(s)

An Attribute Catalog (AC) file represents one option Configuration Explorer and may or may
not represent an entire task. For example, to configure the Batch Recipe task, you choose only
one option, Recipe, and fill in the associated tables. This option corresponds to the
RECIPE.AC file.

Configuration Explorer Main Menu Option AC File Name


Recipe RECIPE.AC
System Configuration SYS.AC

Each task has multiple tables that can be configured for it. Each table corresponds to a database
table whose characteristics are specified in the AC file that corresponds to the option chosen.

An AC file indicates
• Name of the task
• Parent/Child relationship between the tables
• Relationships between the database tables
• Validation information

Each field you can edit in a database table record must be specified in the AC file. AC files are
found in {FLINK}\ac\<filename>.ac.

Because they are ASCII text files, the AC files for standard tasks are easily copied and altered
to create an AC for a new task. The best way to create an AC file is
• Copy an existing AC file from the {FLINK}/ac directory
• Make necessary changes to this file
• Save it with a new name

Note: Text files (*.txt) are now stored in one of the following directory
paths:
\flink\msg\en
\flink\msg\de
\flink\msg\fr
The text files were previously found in the \flink\msg or
\flink\msg\english directory paths.

Fl_xlate automatically loads from the correct subdirectory based on the


language you select.

64 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

AC File Format
5
In an AC file, each statement begins with a keyword followed by one or more parameters
separated by commas. Comments may be included in the AC file by beginning the line with an
asterisk. The comment continues to the end of the line. Blank lines and leading spaces are

FactoryLink Task
Constructing a
ignored. A statement may be split over multiple lines. The keyword DELETE may not be used
in an AC file. It is reserved for an internal function and is not available to the programmer.

Note: The first non-comment line of the AC file should contain an


XLATES directive that tells where the token translations are located. For
example, in the Report Generator AC file (rpt.ac), the XLATES directive
is XLATES rpt_ac.txt, which tells the system to look in file rpt_ac.txt for
translation for this file.

The general format of an AC file follows. Brackets ([ ]) indicate optional entries.

XLATES “xlatefilename”

TASK name, {title}


CT table_name, file_name, “{titletokenstring}”
[EDIT type [, editor]]
[VALIDATE type]
PANEL panel_file, x, y, width, height
FIELD name, type, width, field_prec, key_file, default,
low, high, flags
[HEADING “{tokenstring}”, width ]
[RELATE CDB_name, field_name, index_file ]
DOMAIN “DOMAIN”, 8
SELECT field_name , width [<HEADING {heading_string}> , width]
SEQ field_name , width
INDEX index_file, key_expression, key_length
END

The following sections describe each statement in the AC file.

XLATES
XLATES “filename”

Filename is the name of the file in \flink\msg\en, \flink\msg\fr, or \flink\msg\de that contains
the tranlsations of the tokens used in the AC.

FactoryLink Programmer’s Access Kit / 65


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


TASK

TASK name, {title}

The TASK statement defines the task name and title for the task list. Only one TASK statement
is included in an AC file.

Parameter Description Valid Entries


name Name of task as displayed in the Task Name Alphanumeric string of up to
field on the System Configuration 8 characters.
Information table.
{title} Name of the task as displayed in the Alphanumeric string.
Configuration Explorer, from translation of
the tokens used in the AC.

Note: Tokens in AC files must be enclosed


in braces { }.

CT
CT table_name, file_name, “{titletokenstring}”

The CT statement defines a database table. A task may have as many CT statements as needed,
one per table.

Parameter Description Valid Entries


table_name Name of the Valid table name.
database table.
file_name Name of the If name refers to: Then enter:
database table or Database table Same name as
file specification. specified above in
table_name.
File spec. TEXT or EXECUTE
type in EDIT statement:
File name(s) to edit.
{titletokenstring} Title of the table Alphanumeric string.
from translation of
the tokens used in
the AC.

66 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

EDIT
[EDIT type [, editor]]
5
The EDIT statement defines a module or program used to edit this database table. If the EDIT

FactoryLink Task
statement is not included, the Configuration Explorer uses the default edit procedure.

Constructing a
Parameter Description Valid Entries
type Determiner of the DEFAULT (Standard panel edit procedure, which
module or program means you complete the columns and rows of the
used for editing. table using the Tab key or arrow keys to move from
field to field or row to row.)

TEXT (Text panels where you press the Enter key


to move to the next line of text.)

EXECUTE (Any executable program loaded as an


editor.)

EXTERNAL (The EXTERNAL entry for the type


parameter of the EDIT.)
editor Editor to be used on If the type is:
this database table;
depends on the type DEFAULT: no entry
parameter.
TEXT: no entry

EXECUTE: name of executable to launch

EXTERNAL: Internal use only

FactoryLink Programmer’s Access Kit / 67


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


VALIDATE
[VALIDATE type]

The VALIDATE statement defines the level of editing you are allowed when completing a
configuration table and the program or module that performs the editing.

Parameter Description Valid Entries


type Type and level of DEFAULT Validation done internally by the
editing performed Configuration Explorer.
on a configuration
table. EXTERNAL Validation performed by an external
function.

READONLY You can only view table; editing


not allowed.

NOEDIT Do not use this entry: it is reserved.


NOEDIT means you cannot edit or
view the table.

PANEL
PANEL panel_file, x, y, width, height

The PANEL statement defines the display/edit window(s) for the database table. If the PANEL
statement is not included, you cannot edit records in the table with the Configuration Explorer
default edit functions.

Parameter Description Valid Entries


panel_file Name of a file containing the table Valid file name.
definition.
x Initial horizontal position of the lower 0-1000 where the position:
left corner of the table or of the default 0,0 is lower left corner of screen
table if the panel_file is not used. 1000,1000 is upper right corner of
screen.
y Initial vertical position of the lower 0-1000 where the position:
left corner of the table or of the default 0,0 is lower left corner of screen
table if the panel_file is not used. 1000,1000 is upper right corner of
screen.

68 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

Parameter Description Valid Entries


5
width Width of the table. 0-1000.
height Height of the table. 0-1000.

FactoryLink Task
Constructing a
FIELD
FIELD name, type, width, field_prec, key_file, default, low, high, flags

The FIELD statement defines one editable field in the database.

Parameter Description Valid Entries


name Field name as stored in the Valid field name with 10 characters
database table definition. maximum.
type Type of field. The Configuration CHARCTER
Explorer performs validation on NUMBER
the field based on the type. KEY
TAG
TAGCHAR
TAGNUM
TAGKEY
width Maximum field length. 255 characters maximum.
field_prec Numeric precision of field. 0 (floating points only).
key_file KEY or TAG types only: Name of the key file; do not use the
Name of a keyword file used to extension; no entry.
validate the value in the field.
default Default value for the field. String. If the type is KEY, then the
entry must be included in the key_file.
If the type is TAG, then the entry must
be a valid tag type.
low NUMBER or TAGNUM type Number; must match radix indicated
only: in flags parameter.
Lowest value allowed in this
field.
high NUMBER or TAGNUM type Number; must match radix indicated
only: in flags parameter.
Highest value allowed in this
field.

FactoryLink Programmer’s Access Kit / 69


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Parameter Description Valid Entries
flags Edit options. b allow blank field.
v validate using min/max.
r read-only field.
o octal field.
x hexadecimal field.
u force field to upper case.

Tag-Constant Extensions to the Field Definition

Tag constants provide a means wherein a user can enter a tag name or a constant value within a
single field. This increased flexibility in field types often simplifies the configuration of a task
by reducing the number of fields to be configured.

Configuration Explorer has three distinct types of tag constant fields:


• TAGNUM. Fields that accept numeric constants or tag names
• TAGCHAR. Fields that accept character constants or tag names
• TAGKEY. Fields that accept key file verification or tag names

Visual Indication to the USER

Configuration Explorer automatically precedes all field descriptions in the displayed table with
an asterisk to eliminate confusion as to whether a tag name, value, or both may be entered into
a field.

Determining the Tag-Constant Field’s Data Type

Inputs into TAGCHAR and TAGKEY type fields, which allow tag names or character
constants as input, need a way for Configuration Explorer to distinguish a tag name from a
character constant. To do this, Configuration Explorer requires any constant value entered into
a TAGCHAR and TAGKEY type field to be preceded by a single quotation mark (').

70 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

Specifying Validation Criteria for a Tag-Constant Field


5
The affect of tag constant type on valid entries for the following field parameters follow.

FactoryLink Task
Parameter Valid Entries

Constructing a
key_file Since a tag constant field allows entry of tag names or constant values,
there may be more than one validation file for TAGKEY type fields. One
key file specifies the allowable tag types. The other key file specifies the
valid key constant entries. As such, concatenate both key file names into
this parameter with a | dividing the names.

Example: “<tag_types_key>|<constants_key>”
default The default parameter has a | dividing the default tag type from the default
value for a constant. The default tag type precedes the default constant
value.

Example: “<tag_type_default>|<constant_default>”
low/high These parameters are still applied to constant value validation. The only
tag constant twist applies to the TAGCHAR type fields where the low and
high parameters specify the minimum and maximum number of characters
allowed in the character string.

Examples
FIELD "YEAR", "TAGNUM", 48, 0, "TYPEAL", "ANALOG|1992", 1980, 2200, "bv"
HEADING "{Yearhd}", 44
FIELD "MONTH", "TAGKEY", 48, 0, "TYPEAFML|MONTH", "MESSAGE|JAN", 0, 0, "bu"
HEADING "{Monthhd}", 44
FIELD "DOW", "TAGCHAR", 48, 0, "TYPEM", "MESSAGE|MON", 0, 3, bu"
HEADING "{DOWhd}", 44

FactoryLink Programmer’s Access Kit / 71


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


HEADING
[HEADING “{tokenstring}”, width]

The HEADING option defines the text used as a field heading and the character width for the
column. If you do not specify a heading, the field name is used as the field heading and the
width is calculated based on the number of characters in the field. The Configuration Explorer
allows an unlimited number of lines of text for the HEADING parameter. Delimit lines with
the vertical bar on the first line and Heading on the second line.

Parameter Description Valid Entries


{tokenstring} Field heading as displayed on the table from Text string.
translation of the tokens used in the AC.
width Width of the heading in pixels. Number of pixels.

RELATE
[RELATE CDB_name, field_name, index_file]

A RELATE entry indicates this field is used as a relational field. The current value of the field
is used to select records in another database table. The index file is currently unused.

Parameter Description Valid Entries


CDB_name Name of the database table related Table_name parameter entry
records are to be selected from (for of another CT statement in
example, associated data in another table this AC file.
about a specified table).
field_name Name of field to set using data from this Name parameter entry of a
field. FIELD statement in related
CT in this AC file.
index_file Name of index to use for ordering; not Index_file parameter entry of
currently implemented. an INDEX statement in
related CT in this AC file.

Note: In .AC files, do not use RELATE statements with a field of type
TAG.

72 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

TYPE
5
[Type “field_name”]

The TYPE statement causes the TAG type of a TAG field to be displayed.

FactoryLink Task
Constructing a
Parameter Description Valid Entries
field_name TAG field associated with the String containing the name of a
type. field of type TAG in this CT.

DESC
[DESC “fieldname”]

The DESC statement indicates the description of an OBJECT field should be displayed.

Parameter Description Valid Entries


field_name TAG field associated with this String containing the name of a field
description. of type TAG in this CT.

DOMAIN
DOMAIN “DOMAIN”, 8

Enter the DOMAIN statement exactly as shown above for each configuration table in each AC
file. Do not change this statement.

After you configure a table, the task-specific CDB file DOMAIN statement contains SHARED
or USER, depending on the domain selected in the Domain Selection box. The OBJECT.CDB
associates each tag with the domain defined in the Tag Definition pop-up table.

This statement must be included for each configuration table defined in an AC file for
FactoryLink to operate correctly.

FactoryLink Programmer’s Access Kit / 73


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


SELECT
SELECT field_name , width [<HEADING {tokenstring}> , width]

The SELECT statement defines a selection field. Each CT may have one or more select fields
that determine whether or not a record in the CT is displayed and edited by matching the
current value of the selection with the value contained in the database. Normally, select fields
are not listed in the FIELD statements and you cannot change them. The first select field,
however, is displayed at the bottom of the table and you may change it. The HEADING option
allows a string to be defined to label the select input box. Any other select fields should be set
by a RELATE statement in another CT.

Parameter Description Valid Entries


field_name Name of the field. String; valid database field name.
width Field length. Maximum database field width.
HEADING {tokenstring} Heading; displayed as Text string.
prompt for select input field
from translation of the
tokens used in the AC.
HEADING width Width of the heading in Number of pixels.
pixels.

SEQ
SEQ field_name , width

The SEQ statement defines a field that contains a sequence number for the records. Sequence
numbers can be included in the primary key for the database so that records are sorted in the
same order they were entered. The Configuration Explorer automatically generates the
sequence number.

Parameter Description Valid Entries


field_name Name of the field containing a sequence Valid database field name.
number for the records.
width Field length. 0 - maximum field width.

74 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

INDEX
INDEX index_file, key_expression, key_length
5
The INDEX statement defines an index for the database. The first INDEX statement defines

FactoryLink Task
the primary index and controls the order of records on the screen. If needed, define additional

Constructing a
indices for use by external programs, such as CTGEN. The Configuration Explorer updates all
indices whenever a database record is updated.

Parameter Description Valid Entries


index_file Name of the index. Valid index name.
key_expression List of fields used to form the key Entry format is:
for the database. A field contained “FIELD+FIELD2+...FIELDN”
in the key should not be listed in
the FIELD statements.
key_length Length of the key. Integer equal to the sum of the
lengths of the fields contained in
the key.

END
END

The END statement terminates a CT definition; therefore, one END statement corresponds to
each CT statement in the AC file.

FactoryLink Programmer’s Access Kit / 75


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Naming Considerations

PAK currently uses a dBASE-compatible database library that dictates the following
parameters.

Entries Maximum Length/Width


All table and index names. 8 characters
Field names. 10 characters
Field width. 255 characters

Sample AC File

The following code sample shows the Attribute Catalog for the FactoryLink Logger task:
* Attribute Catalog for Logger Task
xlates “loggerac.txt”
TASK "LOGGER", "{Logger_Task}" * Task name and Title

* CT"logtags", "logtags", "{Logger_Info}"


EDIT DEFAULT * Default Editing
VALIDATE DEFAULT * Default Validation
PANEL "", 100, 100, 700, 700 * Initial Position
FIELD "TAG", "TAG", 48, 0, "", "", 0, 256, "v"
HEADING "{Value_Tag}", 96
FIELD "WIDTH", "NUMBER", 3, 0, "", "", 0, 256, "v"
HEADING "{Field_Width}", 96
DOMAIN "DOMAIN", 8
SELECT "TABLE_NAME", 16 * Primary Key
SEQ "TABLE_NBR", 10 * Sequence Number
INDEX "logtags", "DOMAIN+TABLE_NAME+TABLE_NBR", 34 * Index file, key
END

* CT Name Database Title

CT "logtrig", "logtrig", "{Logger_Cntl}"


EDIT DEFAULT * Default Editing
VALIDATE DEFAULT * Default Validation
PANEL "", 200, 0, 700, 700 * Initial Position
FIELD "TABLE_NAME", "CHARACTER", 16, 0, "", "", 0, 0, ""
HEADING "{Table_Name}", 96
RELATE "logtags", "TABLE_NAME", "logtags"
FIELD "TRIGGER", "TAG", 48, 0, "", "", 0, 0, ""
HEADING "{Trigger Tag}", 96
FIELD "PATH", "CHARACTER", 64, 0, "", "", 0, 0, ""
HEADING "{PATH}", 96
DOMAIN "DOMAIN", 8
SEQ "TABLE_NBR", 10 * Sequence Number
INDEX "logtrig", "DOMAIN+TABLE_NBR", 18 * Index file, key
END

76 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

The following table shows the tokens for an internationalized LOGGER.AC file.
5
Language Name Description
EN Logger_Task Logger Task.

FactoryLink Task
Constructing a
FR Logger_Task Tache du consignateur.
DE Logger_Task Logger Task.
EN Logger_Info Logger Information.
FR Logger_Info Informations du consignateur.
DE Logger_Info Logger-Information.
EN Value_Tag Value Tag.
FR Value_Tag Tag de valeur.
DE Value_Tag Wert-Tag.
EN Field_Width Field_Width.
FR Field_Width Largeur du champ.
DE Field_Width Feldbreite.
EN Logger_Cntl Logger Control.
FR Logger_Cntl Controle du consignateur.
DE Logger_Cntl Logger-Kontrolle.
EN Table_Name Table Name.
FR Table_Name Nom table.
DE Table_Name Tabellenname.
EN Trigger_Tag Trigger Tag.
FR Trigger_Tag Tag declencheur.
DE Trigger_Tag Trigger-TAG.
EN Path Path.
FR Path Chemin.
DE Path Pfad.

FactoryLink Programmer’s Access Kit / 77


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


The next three tables show the tokens for internationalized English, French, and German
LOGGER.AC files generated from the previous code.

Name Description
Logger_Task Logger Task
Logger_Info Logger Information
Value_Tag Value Tag
Field_Width Field Width
Logger_Cntl Logger Control
Table_Name Table Name
Trigger_Tag Trigger Tag
Path Path

Name Description
Logger_Task Tache du consignateur
Logger_Info Informations du consignateur
Value_Tag Tag de valeur
Field_Width Largeur du champ
Logger_Cntl Controle du consignateur
Table_Name Nom table
Trigger_Tag Tag declencheur
Path Chemin

Name Description
Logger_Task Logger-Task
Logger_Info Logger-Information
Value_Tag Wert- Tag
Field_Width Feldbreite
Logger_Cntl Logger-Kontrolle
Table_Name Tabellenname
Trigger_Tag Trigger-Tag
Path Pfad

78 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

The next table contains the tokens for internationalized English, French, and German
LOGGER messages. These tokens are not related to the AC file, but they are part of the Logger 5
Task.

FactoryLink Task
Language Name Description

Constructing a
EN START Starting
FR START Demarrage
DE START Startet
EN RUN Running
FR RUN Execution
DE RUN Lauft
EN STOP Normal shutdown
FR STOP Arret normal
DE STOP Normaler Shutdown
EN NOMEMORY Out of RAM
FR NOMEMORY Memoire RAM saturee
DE NOMEMORY Kein Arbeitsspeicher mehr
EN NOCT Can’t open CT
FR NOCT Impossible d’ouvrir la TC
DE NOCT CT Kann nicht geoffnet werden
EN NOTRIGGERS No triggers defined
FR NOTRIGGERS Aucun declencheur defini
DE NOTRIGGERS Keine Trigger definiert
EN CTINDEX Error reading CT index
FR CTINDEX Erreur lors de la lecture de l’index de la TC
DE CTINDEX Fehler beim Lesen von CT-Index
EN CTHEADER Error reading CT header
FR CTHEADER Erreur lors de la lecture de l’en-tete de la TC
DE CTHEADER Fehler beim Lesen von CT-Kopf
EN BADTAG Invalid trigger tag
FR BADTAG Tag declencheur incorrect
DE BADTAG Ungultiges Trigger-TAG
EN CTRECORD Error reading CT record

FactoryLink Programmer’s Access Kit / 79


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Language Name Description
FR CTRECORD Erreur lors de la lecture de l’enregistrement de la TC
DE CTRECORD Fehler beim Lesen von CT-Datensatz
EN CANTOPEN Can’t open: %s
FR CANTOPEN Impossible d’ouvrir : %s
DE CANTOPEN Kann nicht geoffnet werden : %s
EN TRIGCRE Error creating trigger manager
FR TRIGCRE Erreur lors de la creation du gestionnaire de
declencheurs
DE TRIGCRE Fehler beim Erstellen des Trigger-Managers
EN TRIGINS Error inserting trigger into manager
FR TRIGINS Erreur lors de l’insertion du declencheur dans le
gestionnaire
DE TRIGINS Fehler beim Einfugen des Triggers in den Manager

80 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

The next three tables show the internationalized English, French, and German token files
generated from this message .AC file. 5
Name Description

FactoryLink Task
Constructing a
START Starting
RUN Running
STOP Normal shutdown
NOMEMORY Out of RAM
NOCT Can’t open CT
NOTRIGGERS No triggers defined
CTINDEX Error reading CT index
CTHEADER Error reading CT header
BADTAG Invalid trigger tag
CTRECORD Error reading CT record
CANTOPEN Can’t open: %s
TRIGCRE Error creating trigger manager
TRIGINS Error instering trigger into manager

Name Description
START Demarrage
RUN Execution
STOP Arret normal
NOMEMORY Memoire RAM saturee
NOCT Impossible d’ouvrir la TC
NOTRIGGERS Aucun declencheur defini
CTINDEX Erreur lors de la lecture de l’index de la TC
CTHEADER Erreur lors de la lecture de l’en-tete de la TC
BADTAG Tag declencheur incorrect
CTRECORD Erreur lors de la lecture de l’enregistrement de la TC
CANTOPEN Impossible d’ouvrir : %s
TRIGCRE Erreur lors de la creation du gestionnaire de declencheurs
TRIGINS Erreur lors de l’insertion du declencheur dans le gestionnaire

FactoryLink Programmer’s Access Kit / 81


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Name Description
START Startet
RUN Lauft
STOP Normaler shutdown
NOMEMORY Kein Arbeitsspeicher mehr
NOCT CT kann nicht geoffnet werden
NOTRIGGERS Keine Trigger definiert
CTINDEX Fehler beim Lesen von CT-Index
CTHEADER Fehler beim Lesen von CT-Kopf
BADTAG Ungultiges Trigger-TAG
CTRECORD Fehler beim Lesen von CT-Datensatz
CANTOPEN Kann nicht geoffnet werden : %s
TRIGCRE Fehler beim Erstellen des Trigger-Managers
TRIGINS Fehler beim Einfugen des Triggers in den Manager

82 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

Skeleton Task Sample


5
A complete AC file for the Skeleton Task is in the PAK software at file, SKEL.AC.

FactoryLink Task
If you have not yet integrated the skeleton task into your FLINK system, execute the steps in

Constructing a
“Skeleton Task” on page 21 prior to proceeding with the following procedure.

In your application, open Other Tasks > Skeleton FL Task > Trigger Tags. As described
in the CT statements in the SKEL.AC file, the Trigger Tags displays.

The second CT definition describes the Trigger Tags table; therefore, it is the parent table to
the Tag List table, which is the child table.

As described in the FIELD statements for the Trigger Tags table, the table contains two fields,
Trigger Tag and Table Name. Since the type parameter in the FIELD statement is TAG and
the key_file parameter is TYPED (digital) in the Trigger Tag field, you enter the name of a
digital tag when configuring the task. Since the type parameter in the FIELD statement is
CHARACTER and the width parameter is 16 in the Table Name field, enter a string of 1-16
characters when configuring the task.

FactoryLink Programmer’s Access Kit / 83


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


As described in the RELATE statement for the Trigger Tags table, the two panels are related to
each other by the TABLE_NAME field. Once the Trigger Tags table is complete, select the
Table Name you want to complete a tag list for and then complete the Tag List table for that
table name.

After you complete the Trigger Tags table, choose the desired Table Name, and open the Tag
List table, the chosen Table Name displays in the field above Cancel on the Tag List table.

As described in the FIELD statement for this table, you complete only one field, Tag Name,
by entering the name of a tag (TAG type in FIELD statement) of any data type.

Associating Help with the Task Attributes Catalog

Both table and field help should be created for all ACs. This equates to creating a formatted
text file and placing the results in directory {FLINK}\msg\en, {FLINK}\msg\fr, or
{FLINK}\msg\de for each supported language. AC help files have a .hlp extension.

The help format is very simple. It contains several repeating blocks of the following:

<CT name>, <Field name>, <Help title>

<Description text>

Whenever field help is requested, Configuration Explorer locates the entry associated with the
selected field and displays the description text in a message box. The title of the message box
is <Help title>. To locate the help text, the values for <CT name> and <Field name> must
match the names entered in the corresponding AC exactly.

Use the string TABLE_HELP for <Field name> to create table help for a CT.

Execute command “mkhelp -v” from the system prompt to integrate the help file into the
FactoryLink system. This rebuilds the index of help entries that Configuration Explorer
references later.

Note: The HLP and VHS files have been moved to a new directory
structure, \flink\help\{EN, FR, DE}\ *.{hlp, vhs}, where the EN, FR and
DE subdirectories contain the English, French, and German translations,
respectively. There are no other changes to the HLP or VHS files.

84 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

Executing an Editor Program from the Configuration Explorer


5
The Configuration Explorer can load any executable program as an editor; therefore, to run an
editor from the Configuration Explorer, create an AC file for the external editor program.
Remember to add the name of the AC file to the TITLES file. Refer to “Testing the

FactoryLink Task
Constructing a
Configuration Environment” on page 88 for more information.

An AC file for an external program has the following format:


Task name, {task_title}
CT ct name, file spec, “”
EDIT EXECUTE executable, cmd arguments, format string
VALIDATE DEFAULT
END

The following table describes each statement of this format.

Parameter Description
task Name of the FactoryLink run-time task.
task_title Text displayed in Configuration Explorer.
ct_name Name of the configuration table.
file_spec Specifics for the file to edit.
executable Editor executable.
cmd_arguments Argument strings to be passed to the editor.
format_string Format string for command arguments. If %s is displayed in the
format string, it is replaced with the file spec option and passed to the
editor as a command line argument.

The following sample AC file loads the system E.EXE to edit FactoryLink Math & Logic files.
TASK “IML”, “Edit Math Procedures with System Editor”
CT “iml”, “%s/procs/*.prg”, “”
EDIT EXECUTE “e.exe”, “”, “%s”
VALIDATE DEFAULT

END

Since the file specification contains a wildcard character, the screen displays a list box of all
PRG files in the {FLAPP}/procs directory. You select a file name from this list to be passed to

FactoryLink Programmer’s Access Kit / 85


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


the editor. If the file spec contains wildcard characters and is not a full path name, the current
application directory is added to the front of the file name to make a full path name.

The string specified as the format string is passed to the C-language function SPRINTF. Only
one % can be specified. Also, if a percent sign must be passed as an argument, denote this by
using two percent signs.

If the file spec option does not contain any wildcard characters, then the display does not
contain the file list box and the file spec option is used exactly as it is displayed in the AC file.

Note: This is slightly inconsistent. The format string should be used in


either case, but it is used only if the file spec contains wildcard characters.
Currently no easy way exists to pass wildcard characters on to the external
editor.

If you select MYPROC.PRG from the file list box, the following command is executed:
e.exe {FLAPP}/SHARED/PROCS/MYPROC.PRG

Create the KEY Files

KEY files are used to validate table entries. The CTGEN utility that generates the binary CT
files also uses key files to translate ASCII values into binary values. If a KEY file does not
exist that contains the desired values, create a new KEY file with an ordinary text editor, such
as Notepad on Windows.

Construction of a Key File

Each active line of a KEY file specifies a text-to-binary value conversion. Comment lines,
which are not used by the system and are for information and documentation purposes only,
begin with an asterisk.

By convention, the text and its associated value are displayed on the same line separated from
each other by a vertical bar. The Configuration Explorer ignores any leading and trailing
blanks surrounding the text or the value. The binary values in the KEY file must be entered in
decimal notation.

The Key files are found in {FLINK}\key\en, {FLINK}\key\fr, or {FLINK}\key\de.

The third column of the *.KEY files contains English versions of the string. This English string
is what is stored in the MPS files. In FactoryLink the English string is mapped for display to
the proper language, based on the current language setting in flink\install\fllang.lst. This allows
applications to be saved on a system using one language and restored on a system using
another language.

86 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Configuration Environment

The best way to create a KEY file is


• Copy an existing key file 5
• Make the necessary changes to it

FactoryLink Task
• Save it with a new name

Constructing a
Sample KEY File

A sample KEY file is MONTH.KEY, used for translating abbreviations of the names of the
months to numeric values:
* MONTH, KEY

*NAME | NUMBER

NULL | -1 | NULL

JAN | 1 | JAN

FEB | 2 | FEB

MAR | 3 | MAR

APR | 4 | APR

MAY | 5 | MAY

JUN | 6 | JUN

JUL | 7 | JUL

AUG | 8 | AUG

SEP | 9 | SEP

OCT | 10 | OCT

NOV | 11 | NOV

DEC | 12 | DEC

Informing FactoryLink about the Task

You must configure FactoryLink to load and start up the task to fully integrate the new task
with FactoryLink. Complete the following to inform FactoryLink about the task:
• Add the name of the AC file to the TITLES file to make the task accessible in Configuration
Explorer.
• Execute acctmgr -c -d at the system prompt to update the AC map with the latest edition of
the TITLES file.

FactoryLink Programmer’s Access Kit / 87


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Configuration Environment


Adding the Name of the AC File to the TITLES File

When the Configuration Explorer starts, it reads the file


{FLINK}/ac/titles that contains a list of all AC files for the Configuration Explorer to load, so
the name of the AC file must be added to the TITLES file. Perform the following steps to open
the task configuration table(s):

1 Open {FLINK}\ac\titles with a text editor.

2 Add filename.AC to the TITLES file. The entry location of the new AC file in the TITLES file
reflects the location of that task selection.

3 Save the tables file and close the editor.

4 Execute acctmgr -c -d to update the map with the latest TITLES file.

5 If Configuration Explorer is already open, close and reopen it.

Testing the Configuration Environment

Test the Attribute Catalog using the Configuration Explorer and a dBASE-compatible database
manager.

Choose the new task in the Configuration Explorer. If an error exists in the AC file or if it
cannot locate a KEY file referenced by the AC file, it displays an error table stating the nature
of the problem.

Once any errors are analyzed and corrected, invoke the Configuration Explorer repeatedly,
each time entering a variety of simulated data in the panels, and, therefore, in the
developer-created database tables. Using a compatible database manager or the CDBLIST
utility included with the PAK, examine the resulting database table(s) to ensure the
Configuration Explorer is generating the correct and expected data and placing it in the proper
location within the table.

If the Configuration Explorer finds a syntax error in the AC file or if it cannot locate a
KEY file referenced by the AC file, it displays an error message stating the nature of the
problem. Return to the AC file and correct this error. Reopen the Configuration Explorer.

If no problems exist or once any problems have been resolved, the name specified in the
title parameter of the TASK statement in the AC file is displayed as a selection in the
Configuration Explorer.

88 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

Verify the following items are correct:


• Item name 5
• Name in table header
• Names of fields

FactoryLink Task
Constructing a
Viewing Contents of a Configuration Database without Configuration Explorer
• CDBLIST dumps the contents of configuration database. The command line is:
cdblist [-d] <file.cdb> [<file.mdx]

where
-d Shows the database schema (field names, and optionally, the index
expressions).
<file.cdb> Is the database file to show contents.
<file.mdx> Is the index for the given database.

C REATING A S INGLE P OINT C ONFIGURATION E NVIRONMENT

Extending the Single Point Dialog


The Single Point Tag Definition dialog within the Application Editor program can be extended
through a combination of AC file modifications and the use of the Single Point Page Editor
(PAGEDIT). The AC files must follow some basic design constraints and must be modified to
make use of new extensions to the AC definition required by the Graph task.

PAGEDIT is a standalone utility that allows for the creation of additional pages for the Single
Point Dialog. As the new notebook page is created, the fields on the notebook page are
connected to fields in the AC file.

Adding a page to the Single Point Tag Definition dialog allows for tags to be configured
within APPEDIT and creates entries in Configuration Explorer panels/databases for each
configured tab page. These entries are fully compatible with those in Configuration Explorer.

FactoryLink Programmer’s Access Kit / 89


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


AC file Language Extensions
The following AC file statements have been newly created or modified from their original
definition. The changes apply only to AC files used to define information for pages that will be
added to the Single Point Dialog. The statements must be used in those AC files.

TASK “GTITLE” substatement


Format GTITLE "R/W Information CT name", "Tab Title String"
"R/W Information Defines the CT used to fill in the page.
CT name"
"Tab Title String" Defines the title to display on the notebook page tab.

DEFINES statement
Format DEFINES "ACname.h"
"ACname.h" Include file that defines necessary ID numbers.

Note: ACname represents the base name of the AC file.

ID statement
Format ID CTID, Flags
CTID Unique ID number for this CT. It should be unique at least within the CT.
User configured IDs start above 7000. Current FactoryLink supported ACs
use the 6000 range.

Note: If you might use this extension with other third party extensions,
a range of unique ID numbers should be obtained from Siemens.
Flags 0x10 = Multiple records can be entered for this page (Alarm Information
only)
0x20 = Read/Write Control Table
0x80 = FIELD/SELECT format (statements contain IDs and graphics type)

Note: All Single Point Extension ACs must set this bit.

DIALOG statement
Format: DIALOG CTID, "ac/ACname.acr"
CTID Use the same unique ID number as in the ID statement for this CT. It should
be unique at least within the CT. User configured IDs start above 7000.
Current FactoryLink supported ACs use the 6000 range.

90 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

"ac/ACname.acr" Name of the file in %FLINK%/ac that contains the custom notebook page
information. The ac/ prefix must be included in the filename. 5
FIELD statement

FactoryLink Task
Format FIELD Field_ID, GraphType, "Field Name", FieldType, ...

Constructing a
Example:
FIELD XXXXTAG, TEDIT, "TAG", CT_PTAG, ...
Field_ID Unique number for each field within the AC file that links the Single Point
Dialog to column data. This value also serves as the unique object name in
the translate file for title substitution on the table.
GraphType TEDIT, LISTBOX, TOGGLE. This is used to define the field graphical
representation.
FieldType CT_PTAG, CT_TAG, CT_NUMB, CT_KEY, CT_CHAR,
CT_TAGNUM,CT_TAGCHAR, CT_TAGKEY

CTRLFLD statement
Format CTRLFLD Field_ID, "SELECT Name", “Field Name", FieldSize
Example:
CTRLFLD XXXX__WRITETRIG, "TABLE_NAME", "WRITETRIG", 48
Field_ID Unique number within the AC file that refers to a field within the control
table displayed on the page in a read-only field.
"SELECT Name" Control table entry Field_ID is obtained from.
"Field Name" Field name as it is in the database.
Field Size Field size as it is in the database.

A simple example follows that defines a tag-based table with four fields of information and
also defines a control table with five fields. All five fields from the control table are displayed
read-only on the new notebook page. Information from the control table need not be displayed
on the notebook page. This example is designed as a template to allow you to change the
XXXX to any string of your choice and also to change the words Template and temp to
something more meaningful.

To use the template, read the next section and make the necessary changes to template.acr.
Then,
• Add template.ac to the TITLES file
• Use Configuration Explorer to define a control table
• Start APPEDIT and add tags using the Single Point Dialog

FactoryLink Programmer’s Access Kit / 91


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


template.H
#define ID_RWC_XXXX 6013
#define ID_RWI_XXXX 6014
#define ID_STC_XXXX 6015

#define XXXXTAG 6500


#define XXXXSTATION 6501
#define XXXXADDRESS 6502
#define XXXXDATATYPE 6503
#define XXXXTABLE_NAME 6504
#define XXXXUNSOLRD 6505
#define XXXXEXCEPWR 6506
#define XXXXREADTRIG 6507
#define XXXXWRITETRIG 6508
#define XXXXCOMMENT 6509

#
# template.AC
#
XLATES “templ_ac.txt”

TASK “EDI”, “{TEMPLATE_TASK}”


GTITLE “temp_1”, “{TEMPLATE_GTITLE}”

DEFINES “ac/template.h”

CT “temp_sta”, “temp_sta”, “{TEMP_STA_TITLE}”


ID ID_STC_XXXX, 0xA0
EDIT DEFAULT
VALIDATE DEFAULT
PANEL “temp_hdr”, 50, 225, 850, 599
FIELD XXXXSTATION, TEDIT, “STATION, CT_NUMB, 3, 0, ““, “0, 0, 999, “v”
HEADING “{STATION1}”, 54
FIELD XXXXCOMMENT, TEDIT, “COMMENT”, CT_CHAR, 40, 0, ““, ““, 0, 0, “b”
HEADING “{COMMENT2}”, 128
SEQ “TABLE_NBR”, 10

DOMAIN “DOMAIN, 8

INDEX “temp_sta”, “DOMAIN+TABLE_NBR, 18

END

CT “temp_1”, “temp_1”, “{TEMP_1_TITLE}”


ID ID_RWI_XXXX, 0x80
EDIT DEFAULT
VALIDATE DEFAULT
PANEL “temp_1”, 100, 150, 850, 599
DIALOG ID_RWI_XXXX, “ac/template.acr”

92 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

FIELD XXXXTAG, TEDIT, “TAG”, CT_PTAG, 48, 0, “type”, “DIGITAL”, 0, 0, ““


HEADING “{TAG3}”, 96
FIELD XXXXSTATION, TEDIT, “STATION”, CT_NUMB, 3, 0, ““, “0”, 0, 999, “V”
5
HEADING “{STATION4}”, 54

FactoryLink Task
VALIDLIST “temp_sta”, “STATION, “COMMENT”

Constructing a
FIELD XXXXADDRESS, TEDIT, “ADDRESS”, CT_CHAR, 22, 0, ““, ““, 0, 0, “u”
HEADING “{ADDRESS5}”, 160
FIELD XXXXDATATYPE, LISTBOX, “DATATYPE”, CT_KEY, 7, 0, “type”, “ANALOG”, 0, 0, “u”
HEADING “{DATATYPE6}”, 60
CTRLFLD XXXXWRITETRIG, “TABLE_NAME, “WRITETRIG”, 48
CTRLFLD XXXXREADTRIG, “TABLE_NAME, “READTRIG”, 48
CTRLFLD XXXXEXCEPWR, “TABLE_NAME, “EXCEPWR”, 3
CTRLFLD XXXXUNSOLRD, “TABLE_NAME, “UNSOLRD”, 5

SELECT XXXXTABLE_NAME, “TABLE_NAME”, 16


HEADING “{TABLE_NAME7}”, 96
SEQ “TABLE_NBR”, 10
DOMAIN “DOMAIN”, 8

INDEX “temp_1”, “DOMAI+TABLE_NAME+TABLE_NBR”, 34


INDEX “temp_idx”, “TABLE_NAME+TABLE_NBR”, 26
END

CT “temp_hdr”, “temp_hdr”, “{TEMP_HDR_TITLE}”


ID ID_RWC_XXXX, 0xA0
EDIT DEFAULT
VALIDATE DEFAULT
PANEL “temp_hdr”, 150, 75, 850, 599
FIELD XXXXTABLE_NAME, TEDIT, “TABLE_NAME”, CT_CHAR, 16, 0, ““, ““, 0, 0, “u”
HEADING “{TABLE_NAME8}”, 96
RELATE “temp_1”, “TABLE_NAME”, “temp_idx”
FIELD XXXXUNSOLRD, TEDIT, “UNSOLRD”, CT_KEY, 5,0, “ediunsol”, “NO”, 0, 0, “bu”
HEADING “{UNSOLRD9}”, 88
FIELD XXXXEXCEPWR, TOGGLE, “EXCEPWR”, CT_KEY, 3,0, “yesno”, “NO”, 0, 0, “bu”
HEADING “{EXCEPWR10}”, 72
FIELD XXXXWRITETRIG, TEDIT, “WRITETRIG”, CT_TAG, 48, 0, “typed”, “DIGITAL”, 0, 0, “b”
HEADING “{WRITETRIG11}”, 88
FIELD XXXXREADTRIG, TEDIT, “READTRIG”, CT_TAG, 48, 0, “typed”, “DIGITAL”, 0, 0, “b”
HEADING “{READTRIG12}”, 80
SEQ “TABLE_NBR”, 10

DOMAIN “DOMAIN”, 8

INDEX “temp_hdr”, “DOMAIN+TABLE_NBR”, 18


END

FactoryLink Programmer’s Access Kit / 93


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


Using PAGEDIT
Configuration tables consisting primarily of tag based information are information tables and
can be added to the Single Point Dialog provided they have a defined parent configuration
table, also called control table. When this is the case, you can use the PAGEDIT utility to
define new custom notebook pages that represent the information tables and display as tabs on
the Single Point Dialog.

The PAGEDIT utility is a graphical interface builder that specializes in building pages for the
Single Point Dialog. The basic page is constructed using drag and drop operations placing
fields and labels where appropriate. Once an item has been placed, double-clicking it displays
a Property Window dialog that allows you to edit the various attributes of the variable. This is
where the object is linked to the appropriate field within the AC file.

PAGEDIT is started by entering pagedit at the command prompt. Once PAGEDIT is started,
you can click the folder icon to bring up a file chooser to locate and open an ACR file. A
template ACR file, named template.acr is included to work with the template.ac file. Figure
2-1 shows PAGEDIT's main window that lists any opened pages in the ACR file, in this case
template.acr.

The Type and Tag are displayed together on a line. The Tag is also displayed in an editable
field across the bottom. Select the page line, and in the edit field, change the Tag value to
match the CTID specified in the ID statement in the AC file. To test the template, replace the
XXXX with the same string used in the AC file. This links the page to the information table.
To continue, double-clicking the page entry will allow you to edit the page.

94 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

FactoryLink Task
Constructing a
The Field_ID and GraphType entries added to the FIELD statement in the AC file serve as
each field connection to the notebook page. An object created in PAGEDIT is given Field_ID
as its tagname and GraphType is set in the AC file based on the type of graphical object used to
display the field.

FactoryLink Programmer’s Access Kit / 95


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


The following screen shows the PAGEDIT utility as it displays the page from template.acr
that corresponds to the template AC file.

The Item Palette shown depicts the various objects you can place in any arrangement on the
page. You add objects by pressing the left mouse button on an object in the palette and
dragging it onto the page. The object can then be moved around on the page as needed.

96 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

Notice the tag-based information is arranged at the top, and several fields from the control
table are displayed in a read-only section at the bottom of the page. Since Table Name is the 5
key field for the control table, it is represented as a pulldown listbox that allows the user to
select the table the tag being input is placed into. No information from the control table need be
displayed, nor is it required that all fields from the information table be displayed.

FactoryLink Task
Constructing a
This palette button is used to place label items on the page. Label items are static and
do not relate to a field in the AC file. The value of the label is set by editing the Title
field in the object Property Window.

This palette button is used to place editable text fields on the page. This field type can
be used for any type of alpha-numeric input. Validation of the field will be performed
by a call to the CM validation. When using this object, set GraphType to TEDIT.

This palette button is used to place checkbox items on the page. The checkbox's label
works like a label item. When using this object, set GraphType to TOGGLE.

This palette button is used to place drop-down listboxes on the page. Drop-down lists
are good for providing lists of key values. When using this object, set GraphType to
LISTBOX.

This palette button is used to place boxes on the page. Boxes are used to group
related fields together.

This palette button is used to place buttons on the page.

This palette button is used to place listbox items on the page. Use this object when
you want the list to remain visible. When using this object, set GraphType to
LISTBOX. (This is not implemented yet.)

This palette button is used to place combo-boxes on the page. The combo-box allows
for text entry in the field, or selection from a drop-down list. When using this object,
set GraphType to LISTBOX. (This is not implemented yet.)

FactoryLink Programmer’s Access Kit / 97


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


Double-clicking an object on the page displays the Property Window dialog. Figure 2-3 shows
the Property Window dialog for the text field that displays the value of the Address field. The
text field is linked to the AC field by setting the object Tag to the Field_ID used for this item in
the AC file. The GraphType is set in the AC file based on the type of object used to represent
the field. In this case, because an editable text field is used, GraphType is set to TEDIT.

Each field on the page should have a tag value that references an item in a configuration table.
The Enabled checkbox determines whether or not you can the field. For read-only fields from
the control table, the checkbox should be unselected. The Click Focusable checkbox controls
whether the field can gain focus by clicking with the mouse or by pressing the Tab key to move
to the field. The buttons display choosers to set the Foreground or Background colors and
change the font used in the field.

Once all fields have been added and their tags have been set, save the ACR file and quit
PAGEDIT.

Note: You can reorder the items in your list, by selecting an entry to be
moved with the mouse, then holding down both the left and right mouse
buttons and dragging the item to the desired location in the list.

98 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

Adding Help to Your Page


5
Context-sensitive help can be added to your new notebook pages. Your help will appear
exactly as the standard FactoryLink notebook pages help does, providing seamless integration.
The help can be associated with the entire page or with specific dialog items on the page. To

FactoryLink Task
Constructing a
accomplish this you need to create an ASCII file containing the information required by
APPEDIT to implement the help. After the file is created you must run the mkhelp utility to
build the new help source into the APPEDIT help system and move the new files into the
appropriate directory. The help system supports English, French and German language
versions of the help.

The ASCII text file you create to define your help must conform to the syntax described in
“Source Syntax for Tag Dictionary Notebook Page Help” on page 101. The file must have the
extension .ahs and the English language version must be placed in the {FLINK}\help\en\
directory. The French and German language versions must be placed in the {FLINK}\help\fr\
and {FLINK}\help\de\ directories, respectively.

It is recommended that you create your .ahs file by copying the template file provided and
modifying it to describe your page. For example, to copy the three template files to
mypage.ahs you would enter the following commands at the command prompt:

copy {FLINK}\help\en\template.ahs {FLINK}\help\en\mypage.ahs

copy {FLINK}\help\fr\template.ahs {FLINK}\help\fr\mypage.ahs

copy {FLINK}\help\de\template.ahs {FLINK}\help\de\mypage.ahs

The Template Source File

The contents of the template help source file provided with FactoryLink are shown below.
Keywords are those that begin with the @ symbol. Definition constants are those words that
are fully capitalized. Many of these definitions are derived from entries from within the related
AC file.

For example, the identifier for the template dialog is specified in the template AC file as
ID_RWI_XXXX. This identifier is referenced many places within the page help source file to
associate the help with the appropriate page. This applies to the definition constants (i.e.
XXXXDATATYPE) associated with field definitions.

@comment(****** start of section for CT 'ID_RWI_XXXX' ******)


@section(ID_SPTDLG_ID_RWI_XXXX_GFI_HELP Help on Template Definitions)
@parent(ID_SPTDLG_GFI_HELP)
@context(Context_XXXXPAGEOVERVIEW)
@italic(Template Page Overview)

FactoryLink Programmer’s Access Kit / 99


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


Description of the Template page goes here...

@begin(literal)
@relmargin(36 8)
@popup(STATION Logical Station)
@popup(TABLE_NAME Table Name)
@link(Context_XXXXADDRESS Address)
@link(Context_XXXXDATATYPE Data Type)
@popup(CANCEL_BUTTON Cancel)
@popup(CLEAR_BUTTON Clear)
@popup(WRITETRIG Write Trigger)
@popup(READTRIG Read Trigger)
@popup(EXCEPT_WRITE Exception Write)
@popup(UNSOL_READ Unsolicited Read)
@end(relmargin)
@end(literal)

@comment(** section for field 'XXXXADDRESS' in CT 'ID_RWI_XXXX' **)


@section(ID_SPTDLGFI_TAGNOTEBKID_RWI_XXXXXXXXADDRESS Address)
@parent(ID_SPTDLG_ID_RWI_XXXX_GFI_HELP)
@context(Context_XXXXADDRESS)
@italic(Address)

@begin(literal)

Address description goes here.

@end(literal)

@comment(** section for field 'XXXXDATATYPE' in CT 'ID_RWI_XXXX' **)


@section(ID_SPTDLGFI_TAGNOTEBKID_RWI_XXXXXXXXDATATYPE Data Type)
@parent(ID_SPTDLG_ID_RWI_XXXX_GFI_HELP)
@context(Context_XXXXDATATYPE)
@italic(Data Type)

@begin(literal)

Data Type description goes here.

@end(literal

100 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Creating a Single Point Configuration Environment

Source Syntax for Tag Dictionary Notebook Page Help


5
@comment(<comment string>)

These entries add comments to the help source, allowing for easier maintenance of the source.

FactoryLink Task
Constructing a
These do not affect the contents or presentation of the page help.

@section(ID_SPTDLGFI_<AC DIALOG define>_GFI_HELP <description>)


@section(ID_SPTDLGFI_<AC DIALOG define><AC FIELD define> <descr.>)

Every help topic is called a section, and the section keyword associates a name and a
description string to each topic.

For APPEDIT’s help to associate a topic with a notebook page, the help section's name is built
from the AC's dialog identifier. For example, the section describing the template's page has the
name ID_SPTDLG_ID_RWI_XXXX_GFI_HELP, where ID_RWI_XXXX is the identifier of
the template AC's dialog.

For Appedit's help to associate a topic with an item on a notebook page, the help section's
name is built from a combination the AC's dialog identifier and the AC's field identifier for the
related item. For example, the section describing the template's page ADDRESS text input
field has the name ID_SPTDLG_ID_RWI_XXXXXXXXADDRESS where ID_RWI_XXXX
is the identifier of the template AC's dialog and XXXXADDRESS is the identifier of the
template AC's ADDRESS field.

@parent(ID_SPTDLG_GFI_HELP)
@parent(ID_SPTDLG_[<AC DIALOG define>]_GFI_HELP)

The parent keyword establishes the help section hierarchy. All page overview help sections
have the same help section parent, denoted by the section name ID_SPTDLG_GFI_HELP.

The parent of a field help section is the help overview section for the page, and the name of the
page's overview help section name should be used.

@context(Context_<AC FIELD define>)

The context keyword creates subtopic within the current section for the given name.

For the help section describing an item on a page, the context name must have the name of
"Context_" concatenated with the AC identifier for the field item.

@link(Context_<AC FIELD define> <link title>)

The link keyword establishes a jump from the current context to the given context.

FactoryLink Programmer’s Access Kit / 101


• CONSTRUCTING A FACTORYLINK TASK
• Creating a Single Point Configuration Environment


@popup(<internal define> <link title>)

The popup keyword establishes a jump from the current context to the given context, but
creates a popup window to show the linked information. The APPEDIT convention for popup
help is to display help that is common to several pages. The template example shows the help
definition names useful for displaying common descriptions, such as for the CANCEL button.

@italic(<description string>)
@begin(literal)
@end(literal)
@relmargin(<left_margin> <right_margin>)
@end(relmargin)

These keywords affect the presentation of the help text in the manner that the keyword
suggests.

Building Your Notebook Page Help into APPEDIT

Once your .ahs file has been created you must build it into the APPEDIT help system. When
you distribute your application to users, this process occurs automatically during the
installation procedure. During development you need to use the mkhelp utility to build your
help into the APPEDIT help system. Enter the following at the command prompt to run
mkhelp:

mkhelp -c

If an error associated with your help file occurs during the build process the error messages are
written to the file vdebug.log and the appropriate {FLINK}\help\<en\fr\de> directory.

Running the mkhelp program builds the appedit.vhs file for each language and places it in the
appropriate {FLINK}/dll/<en\fr\de> directory. A copy of the file corresponding to the current
language is placed in the {FLINK}\bin directory.

102 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Preparing Configuration for Run Time

P REPARING C ONFIGURATION FOR R UN T IME


5
This section provides details for setting up the configuration environment that includes the
following tasks:

FactoryLink Task
• Convert Database Tables to CTs

Constructing a
• Create the CTG Conversion Scripts
• Test the Conversion Process

The figure below illustrates the portion of the Task Construction Flowchart involved in
converting database tables to CTs.

Create CTG
Conversion Script

Run CTGEN

Examine Binary
CT File

Problems
Yes Edit Script
with CT Files?

No

FactoryLink Programmer’s Access Kit / 103


• CONSTRUCTING A FACTORYLINK TASK
• Preparing Configuration for Run Time


Create the CTG Conversion Scripts

Conversion Overview

The conversion process translates database tables into run-time, binary configuration tables.
The binary tables are arrays of records with a format that matches the internal C-structure
within the target task. This enables FactoryLink run-time tasks to load the tables with little or
no additional processing. The task simply copies the data into its internal structure.

All run-time CTs use a common archive format. The term archive refers to the binary CT file
containing data for more than one database table. For example, the TIMER.CT file contains
information for the event timer and interval timer database tables.

The following information is created in a CT file:

1. Each CT file begins with an archive header indicating the number of CTs in the archive.

2. The header is followed by an index entry for each CT. Each CT consists of an optional
header section followed by zero or more records. Each record within a CT has the same
format:

[CT archive header]

[CT index 0]

[CT index 1]

[CT index n]

[CT 0 header]

[CT 0 records]

[CT 1 header]

[CT 1 records]

[CT n header]

[CT n records]

Library services are provided that enable a task to read the CT files. The developer determines
the contents of the CT header and CT records that vary according to the database table.

104 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Preparing Configuration for Run Time

Conversion Script Format


5
A conversion script, which is processed by the CTGEN utility, controls conversion of database
table information into CT files. Generally, design the conversion script so the output from
CTGEN matches the run-time task data structures. This allows the run-time task to read the

FactoryLink Task
Constructing a
binary data from the CT archive directly into memory. The /{FLINK}/CTGEN directory
contains sample CT conversion scripts.

The format of a conversion script is


TABLE type, name, hdrlen, reclen
HEADER database, namefield

SORT “FIELD1”,”FIELD2”
DOMAIN “DOMAIN”, S, 8
FIELD name, format, storage, [options]
RECORD database, namefield, indexfile

SORT “FIELD1”,”FIELD2”,”FIELD3”
DOMAIN “DOMAIN”, S, 8
FIELD name, format, storage [option] [DEFAULT dfltval]
SKIP count, value

The following paragraphs describe this format.

TABLE
TABLE type, name, hdrlen, reclen

The TABLE statement defines one CT type in the archive. The values of the parameters are
placed in the appropriate fields in the CT index record. A single TABLE definition may result
in multiple CT index entries. The HEADER database determines the number of times the table
is repeated.

Multiple TABLE definitions may exist in the script. Each one is processed in order.

Parameter Description Valid Entries


type Table type ID. Integer ordinal (0-65536).
name Table name String of up to 10 characters.
hdrlen Number of bytes of a header 0 (CTGEN automatically calculates
record. this value.
reclen Number of bytes of a data record. 0 (CTGEN automatically calculates
this value.

FactoryLink Programmer’s Access Kit / 105


• CONSTRUCTING A FACTORYLINK TASK
• Preparing Configuration for Run Time


HEADER
HEADER database, namefield

The HEADER statement defines the format of the header section of the CT. No more than one
header record is written for a CT; however, the header record may be non-existent.

Parameter Description Valid Entries


database Name of the database table to be Valid database table name (string of
used. characters enclosed in quotes).
namefield Controller of the repeated Null or non-null string
record section.
If the value is: Then:

null string: all records in the repeated


section are written.

non-null string: the value of the indicated


field is used to fill in the
name member of the CT index record and
to select repeated records.

RECORD
RECORD database, namefield, indexfile

The RECORD statement defines the format of the repeated record entries in a CT. Multiple
RECORD statements are allowed. Each is processed in order.

Parameter Description Valid Entries


database Name of the database table to be Valid database table name.
used.
namefield Field in the RECORD database that Valid field name.
must match the Namefield field in
the current record of the HEADER.
If this parameter is not specified, the
HEADER namefield is not specified,
or the HEADER is non-existent,
then all records in the RECORD
database are written to the CT. This
field should be the primary key.

106 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Preparing Configuration for Run Time

Parameter Description Valid Entries


5
indexfile Name of the index file used to read Index containing namefield as the
the records. primary key.

FactoryLink Task
Constructing a
DOMAIN
DOMAIN “DOMAIN”, S, 8

Enter the DOMAIN statement exactly as shown above for each configuration table in each
CTG file if the source database table has a DOMAIN field. Do not change the statement.

where
DOMAIN References the domain field in the database in the CDB file, which is
created by the DOMAIN statement of the corresponding AC file. For
additional information about AC files, refer to “Create the Attribute
Catalog(s)” on page 64.
S Indicates the domain directory name consists of a character string.
8 Is the number of characters in the domain directory name. This number
must be the same as the number in the DOMAIN statement of the
corresponding AC file.

The DOMAIN statement in the CTG file places the CT file in the domain-specific path
specified in this parameter, which is {FLAPP}/{FLDOMAIN}/*.CT.

Failing to put this statement in means the configuration is domain independent resulting in the
CT being placed at {FLAPP}/ct. This usage is the exception rather than the rule.

FactoryLink Programmer’s Access Kit / 107


• CONSTRUCTING A FACTORYLINK TASK
• Preparing Configuration for Run Time


FIELD
FIELD name, format, storage [option] [DEFAULT dftval]

The FIELD statement defines the translation of one field in the database table to bytes in the
CT entry. Include as many FIELD statements as necessary.

Parameter Description Valid Entries


name Field name of the database Valid field name.
field to be used.
format Output format for the T Data is a two-word TAG C-structure
database field. The format is containing segment and offset. Use
specified by a single only for Tag Fields.
character. S ASCII string.
D Binary output. The database field is
considered to be a string of numerical
digits representing a decimal value.
X Binary output. Field assumed to
contain hexadecimal number string.
O Binary output. Field assumed to
contain octal number string.
F Double output. Field assumed to
contain a precision float number
string.
storage Number of bytes in the Number of bytes.
output record the value For format: Then:
occupies. The database value
T TAG structure byte size is 4.
is truncated or null-padded
to fit the output field width. S String length (add 1 to guarantee
termination)
D Integer length: 2 for i16; 4 for i32
X Integer length: 2 for i16; 4 for i32
O Integer length: 2 for i16; 4 for i32
F Double byte size is 8.

108 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Preparing Configuration for Run Time

Parameter Description Valid Entries


5
option Specifier of additional Option keywords:
information about how the TAG Output as a name,
data in the input field is

FactoryLink Task
segment and offset as

Constructing a
converted. binary as numerical
values.
DIM The dimensions of the
TAG contained in the
database field is used
as the output data.
TYPE The type of the TAG
contained in the
database field is used
as the output data.
KEY <keyfile> Specifies the keyfile
to use to translate
the field string value
into a numeric value.
dftval Default value. Specifies the default value to be used if the
database field contains a NULL string.

Handling Tag Constant Fields

Generally, each tag constant field in the AC file results in two references to that field within the
CTG script. One field reference outputs the field as a tag and the other reference outputs the
field as a constant value. When outputting the constant value, append to the CONST or
KEYCONST keyword so the field value returns as 0 or a NULL string if a tag name has been
entered in the field. The CONST option applies to character or numeric constants and the
KEYCONST option applies to key constants. When outputting a constant value as a TAG, the
returned tag equals the invalid tag identifier {-1, -1}.

CTG File Example


FIELD “YEAR”, T, 4, TAG

FIELD “YEAR”, D, 2, CONST DEFAULT -1

FIELD “MONTH”, T, 4, TAG

FIELD “MONTH”, D, 2, KEYCONST “month” DEFAULT NUL

FIELD “DOW”, T, 4, TAG

FIELD “DOW”, S, 4, CONST

FactoryLink Programmer’s Access Kit / 109


• CONSTRUCTING A FACTORYLINK TASK
• Preparing Configuration for Run Time


SKIP
SKIP count, value

A SKIP statement causes one or more bytes to be written to the output. The SKIP statement
allows padding of fields to match the task data structures as well as insertion of specific binary
data into the CT file. Include as many SKIP statements as needed. FIELD and SKIP statements
may be mixed in any order.

Parameter Description Valid Entries


count Number of bytes to output. Integer value greater than 0.
value (Optional) Byte value used to fill the Value of the byte (default = null).
output record.

SORT

The SORT statement defines the order records are read in from the configuration databases and
written to the binary CTs or the repeated header or record entries in a CT. The SORT
immediately follows the HEADER or RECORD it applies to and may contain one or more
field names to be used to sort the entries. Only one SORT statement is allowed per HEADER
or RECORD entry.

Parameter Description Valid Entries


sort field Field names. TABLE_NBR, DOMAIN, or any field name
in the header or record being sorted.

By default, the order of CT information conform to ordering viewed from the configuration
database.

Sample Conversion Script

The following file is a sample conversion script included in the PAK software as SKEL.CTG.
It is found in the {FLINK}\src\examples\skeleton directory.
TABLE 0, “”, 4, 4
HEADER “SKELTRIG.CDB”, “TABLE_NAME”
FIELD “TRIGGER”, T, 4, TAG
DOMAIN “DOMAIN”, S, 8

RECORD “SKELTAGS.CDB”, “TABLE_NAME”, “SKELTAGS,CDX”


FIELD “TAG”, T, 4, TAG
DOMAIN “DOMAIN”, S, 8

110 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Preparing Configuration for Run Time

Creating FactoryLink Configuration Tables (CTs)


5
The binary CT file contains the information specified in the task database table(s). The
CTGEN utility binds (converts) the tag names specified in the database tables to tag numbers
maintained by the Real-Time Database. At run time the task loads the CT file and builds any

FactoryLink Task
Constructing a
internal structures required to perform the job. To improve performance, tasks use the tag
number from the CT instead of the tag names in the database table(s) to access the Real-Time
Database.

Integrating a Conversion Script into FactoryLink

Conversion scripts must reside in directory {FLINK}\ctgen. For the system to be aware of and
process a conversion script, an entry for it must be appended to the CTLIST file that resides in
{FLINK}/ctgen. With a text editor, append a line in the following format:

<task>: <cdb> <cdb> …

The <task> entry is the name of the conversion script without the .ctg extension. The names
that follow are the configuration database file names without the .cdb extension referenced
within the conversion script. This equates to a dependency list where, if the binary CT for the
task is older than any of the listed CDBs, regenerate the binary CT.

For example, the entry for the skeleton task is:

skel: skeltrig skeltags

The Binary CT Generation Utility - CTGEN

CTGEN uses the CTLIST file to build CTs and rebuild all CTs whose database tables have
changed. CTGEN can be run stand-alone or with a combination of parameters.

To run CTGEN, enter the following command at the DOS prompt:


ctgen <Enter>

To run CTGEN with parameters, enter the following command at the DOS prompt:
ctgen [-i<name.ctg>][-a <flapp>] [-o<ouput path>] -c -r -v(#) <Enter>
where
-i Indicates only those CTs referenced within the specified CTG file are to be
rebuilt. Next to -i, enter the file name of the CTG file to be used.
({FLINK}/CTGEN is the default directory.)
-a CTs in alternate FLAPP directories.

FactoryLink Programmer’s Access Kit / 111


• CONSTRUCTING A FACTORYLINK TASK
• Preparing Configuration for Run Time


-o Indicates the output is to be redirected to the specified file. (The default is
{FLAPP}/CT/NAME.CT.)
-c Indicates all tag numbers (segments and locations) are to be cleared before
the CT is generated. (Must be followed by -r).
-r Indicates all files are to be rebuilt. (Usually preceded by -c).
-v (#) Indicates verbose mode and level. Each verbose level displays cumulative
messages. For example, v2 displays general activity messages and historian
and client task messages. Choose v1 for general viewing. Use v2-v4 for
debugging..

Valid Entries Descriptions


v1 Displays general activity messages.
v2 Displays historian and client task messages.
v3 Displays the parsing of .CTG file tokens.
v4 Displays tag names as they are written to the
database.

Debugging the Conversion Process


CTLIST, a command line utility that dumps the contents of a binary CT into a readable format,
is useful for debugging purposes. Developers use this tool to view how CTGEN translated the
CDBs into a collection of headers and records according to their CTG scripts and then to adjust
these scripts accordingly. The actual binary data within the records are presented as
hexadecimal with paired bytes in reverse order.
Usage: ctlist <file.ct>

where
<file.ct> CT file to dump.

112 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Writing the Run-Time Task

W RITING THE R UN -T IME TASK


5
For the Run-Time Manager to effectively perform FactoryLink task management duties, each
FactoryLink task must adhere to certain run-time requirements so the Run-Time Manager

FactoryLink Task
monitors specific database tags in the Real-Time Database on a per-task basis.

Constructing a
The requirements include:
• Initialization
• Kernel Check
• Error Handling
• New Configuration Notification
• Termination Notification
• Orderly Shutdown

In addition, for proper operation in a foreign language environment, the task should use
fl_xlate to translate any output messages into the language being used and fl_xlate_init to load
the translations when the task is started.

FactoryLink Programmer’s Access Kit / 113


• CONSTRUCTING A FACTORYLINK TASK
• Writing the Run-Time Task


The following figure illustrates the portion of the Task Construction Flowchart involved in
completing run-time requirements.

Create Source
Modules

Compile Source
Modules

Problems Edit Source


Yes
Compiling? Modules

No

Link Object
Modules

Problems Edit Source and


Yes
Linking? Link Files

No

Execute Program

Problems
Yes Debug Program
Found?

No

Create Installation
Medium

114 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Initialization

I NITIALIZATION
5
First, the task attaches with the Real-Time Database (or Kernel) by calling FLIB function
fl_proc_init( ) to obtain a task id (taskid). Function fl_proc_init( ) uses environment variables

FactoryLink Task
{FLNAME}, {FLDOMAIN}, and {FLUSER} to determine which Real-Time Database to

Constructing a
attach. If the task needs to attach elsewhere, FLIB function fl_proc_init_app( ) can be called.

If the call fails (taskid = ERROR), the task writes an appropriate error message to STDOUT
and calls EXIT.

If the call succeeds (taskid! = ERROR), the task obtains the task environment tags by calling to
fl_get_env( ). The environment tags, which are used to communicate with the Run-Time
Manager, include the following information:
• Status tag for reporting task status as an ANALOG value
• Message tag for reporting task status as a MESSAGE
• Application path specification
• Program path specification
• Command line arguments

Then, the task writes FLS_ACTIVE to its status tag and Running to its message tag. This
causes the Active symbol to be displayed in the STATUS column and Running to be displayed
in the MESSAGE column of the Run-Time Manager display.

K ERNEL C HECK (C ONDITIONAL )


If proper execution of the task depends on the version of the Kernel installed on the system,
obtain the Kernel's version and release number by calling fl_get_version( ). Check the values
obtained against your own list of compatible values. As a rule, an unacceptable version or
release number should be considered a fatal error. If this occurs, write an appropriate error
message to STDOUT and call EXIT.

E RROR H ANDLING
If the task encounters any errors, failures, or other problems during execution, it reports
appropriate error messages to its environment STATUS and MESSAGE tags.
• In case of a fatal error, the task exits following the shutdown procedure described in the
Orderly Shutdown requirement.
• In case of a non-fatal error, the task sets its environment STATUS tag to FLS_ERROR. This
indicates to the Run-Time Manager the task encountered problems but is continuing

FactoryLink Programmer’s Access Kit / 115


• CONSTRUCTING A FACTORYLINK TASK
• New Configuration Notification


execution, and the Run-Time Manager displays ERROR in the STATUS column of its
display. The task writes a description of the problem to its environment MESSAGE tag

N EW C ONFIGURATION N OTIFICATION
Custom tasks developed by users and 3rd party vendors can be enabled for online
configuration simply by creating an RTM file for each task that gets installed into the
{FLINK}\CTGEN directory. The format for the RTM files is described below:

RTM File and Task Bumping Determination


A new file type, the RTM file, lists the bump dependencies for individual tasks. If any file in
the list is newer than when the task last started, RUNMGR needs to bump the associated task.

RTM file format:

The syntax is as follows:

BUMP <bumpname>
METHOD <CYCLE | SIGNAL>
[FILE_DEPENDENCY <filespec> [, <filespec>]]
[BUMP_DEPENDENCY <bumpname> [, <bumpname>]]
ENDBUMP

GROUP <bumpname>
BUMP_DEPENDENCY <bumpname> [, <bumpname>]]
ENDGROUP
* <comment>

The BUMP keyword establishes a record that holds the criteria for when a task should be
bumped. Token <bumpname> should match the task name used to obtain a task ID from the
kernel (fl_proc_init()). The ENDBUMP keyword closes the record definition.

The METHOD keyword indicates what method is used to update the given task with online
configuration. If the following keyword is CYCLE, the task will be stopped and restarted. If
the following keyword is SIGNAL, the task will be sent the kernel signal
FLC_SIG_NEWCONFIG. If a task is to be signaled instead of cycled, then the developer must
modify the task code to recognize the signal and dynamically reload its configuration
information. Only one method definition is allowed and required per bump record definition.

The FILE_DEPENDENCY keyword precedes the comma-delineated list of files on which the
task is dependent. The <filespec> entry is a file specification relative to the current FLAPP,
although full paths can be specified. Wildcards are allowed, as are environment variables

116 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
New Configuration Notification

denoted by braces. One or more file dependency lists can be included within a single bump
record definition. 5
The BUMP_DEPENDENCY keyword precedes the comma-delineated list of additional bump
record names on which the task is dependent. The <bumpname> entry should match the

FactoryLink Task
Constructing a
<bumpname> used to define a separate BUMP record or group. One or more bump
dependency lists can be included within a single bump record definition.

The GROUP keyword establishes a collection of dependencies that are not tied to any
particular task. Hence, token <bumpname> should not match any task name. However, these
groups can be referenced in other record or group bump dependency lists, thereby reducing the
amount of information duplicated across the individual task bump record definitions. An
example of where this is useful is the historian and client tasks. All the client tasks are
dependent on the historians and must be bumped if an historian is bumped. Using the GROUP
method the individual historian task names do not need to be referenced in the RTM file for
each client. In addition, if a new historian is defined, only one file needs to be updated instead
of several. The ENDGROUP keyword closes the group definition.

Finally, more than one bump records can exist in an RTM file. Also, comment lines are
denoted an asterisk (*) at the beginning of the line.

Examples:

SKEL.RTM:
* RTM file for the Skeleton task
BUMP skel
METHOD CYCLE
FILE_DEPENDENCY ct\skel.ct*
ENDBUMP

PERSIST.RTM:
BUMP persist
METHOD SIGNAL
FILE_DEPENDENCY ct\persist*, ct\object.ct*
ENDBUMP
HISTRIAN.RTM:
GROUP historians
BUMP_DEPENDENCY or7_hist, db4_hist, syb_hist, odbchists
ENDGROUP

DPLOGGER.RTM:
BUMP dplogger
METHOD CYCLE
FILE_DEPENDENCY ct\dplogger.ct*

FactoryLink Programmer’s Access Kit / 117


• CONSTRUCTING A FACTORYLINK TASK
• Termination Notification


BUMP_DEPENDENCY historians
ENDBUMP

Signaled Task Requirements

If a custom task is to be signaled instead of stopped and restarted, the developer must modify
the task code to be able to receive signals and recognize the newly added online configuration
signal. See the fl_hold_sig() and fl_recv_sig() API functions for information to implement
signal handling. FLC_SIG_NEWCONFIG supports signaling tasks during an online update.
Upon receiving the FLC_SIG_NEWCONFIG signal, a task can adjust its configuration in
accordance to the latest CT files. Exactly what this entails and how it is actually done is totally
up to the developer and specific to each task design and requirements.

TERMINATION N OTIFICATION
A task must shut down when the Run-Time Manager notifies it to do so. Tasks must check the
current status of the task termination flag often. They do this by calling fl_test_term_flag ( ).
• If the value of the flag is 1 (ON), the task goes through the shutdown procedure in and
writes normal shutdown to its environment MESSAGE tag.
• If the value of the flag is 0 (OFF), the task continues execution.

You can terminate the task from the Run-Time Manager. The task terminates along with its
associated FactoryLink session.

118 / FactoryLink Programmer’s Access Kit


CONSTRUCTING A FACTORYLINK TASK
Orderly Shutdown

O RDERLY S HUTDOWN
5
The task performs the following actions before calling EXIT:
• Writes a message explaining the reason for termination to its environment MESSAGE tag,

FactoryLink Task
which is then displayed in the MESSAGE column of the Run-Time Manager display.

Constructing a
• Sets its environment STATUS tag to FLS_INACTIVE, which causes the Inactive symbol to
display in the STATUS column of the Run-Time Manager display.

The task then terminates execution via fl_proc_exit( ).

Message Translation
Rather than using hard-coded messages, tasks should translate error and informational
messages so multiple languages can be supported. Instead of saying “showerr (“error:out of
memory”), the task should say “showerr (fl_xlate (“NORAM”)). Then, the following records
should correspond to the following files:

{FLINK}/MSG/EN/taskname.txt: record NORAM out of memory

{FLINK}/MSG/FR/taskname.txt: record NORAM Memoire insuffisante

{FLINK}/MSG/DE/taskname.txt: record NORAM Nicht genug Speicher

TASK P ROGRAM S KELETON


A sample FactoryLink program written in the C language resides in
{FLINK}/Src/examples/skeleton. This program demonstrates proper programming practices,
standards, and conventions. It illustrates the interaction of the program with the Run-Time
Manager. Use it as a base to build your custom tasks from.

FactoryLink Programmer’s Access Kit / 119


• CONSTRUCTING A FACTORYLINK TASK
• Task Program Skeleton

120 / FactoryLink Programmer’s Access Kit


Chapter 6





PAK Library Services
6

PAK Library Services


The FactoryLink Library (FLIB) contains a set of callable software services that FactoryLink
builds tasks with. The library services are divided into the following categories:
• Kernel Interface
• Task/Session Management
• Real-Time Database Access
• Calling and Return Conventions
• CT Access
• Object CT Access
• Direct Tag Processing
• Normalized Tag Reference
• Path Manipulation
• Message Translation

This guide assumes you develop client processes in the C Programming Language or in a
language that provides a calling sequence compatible with the C language. This chapter
includes information about the service functions and how to use them.

Function names are case-sensitive. All API function names are entirely lower-case. For
example, a client process calls fl_proc_init( ) with the following command:
taskid = fl_proc_init(“RUNMGR”, “Run-Time Manager”) ;

Note: In general, always include FactoryLink headers after system


headers to avoid any definition conflicts.

FactoryLink Programmer’s Access Kit / 121


• PAK LIBRARY SERVICES
• Kernel Interface Services


K ERNEL I NTERFACE S ERVICES
The Kernel interface services enable tasks to attach to the Kernel and to transact data transfers
with the Real-Time Database. In other words, these are the hooks that allow your program to
ride FactoryLink’s software bus. The discussion on the Kernel interface services is divided into
three areas:
• Kernel/Task Session Management
• Real-Time Database Access
• Calling Conventions and Exception Reporting

Task/Kernel Session Management


The Kernel/Task Session Management discusses task interaction with the Kernel. Topics
covered are
• Attaching to and Detaching from the Kernel
• Obtaining Task Environment Information
• Locking and Unlocking the Kernel
• Signals
• Miscellaneous Kernel Services

Attaching/Detaching from Kernel

Function Description
fl_proc_init Attach to the Kernel.
fl_proc_exit Detach from the Kernel.
fl_set_term_flag Sets the termination flag of a client process.
fl_test_term_flag Asks the Kernel the status of current task termination
flag.

These functions help the Kernel and the Run-Time Manager control client processes. Since a
prospective client must make itself known to the Kernel before doing anything, it must
successfully call fl_proc_init( ) that assigns a FactoryLink ID before calling any other Kernel
service. An exception to this rule is any functions that do not have the FactoryLink ID as one
of the arguments. A client process may not call any other Kernel service after calling
fl_proc_exit ( ), which releases to the system or renounces the caller's FactoryLink ID.

122 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

Using Task/Kernel Management Functions


6
The process management functions are C functions callable by C-language application and
system programs. The library functions make calls to the FactoryLink Kernel. It is the duty of

PAK Library Services


the Kernel to maintain a task table. The task table holds all information relevant to running
tasks and furnishes services allowing access to and limited manipulation of the data stored in
this table.

FactoryLink tasks process real-time data until it detects its termination flag has been set. This
is accomplished by frequently calling function fl_test_term_flag( ).

Sample Task Attachment/Detachment

The following example illustrates the use of the process-management functions. It does not
illustrate the interaction of a task with the Run-Time Manager.
#include “FLIB.H”
char name[] = “MYNAME”; /*my name(name of this task)*/
int taskid; task number to be assigned*/

main() /*PROGRAM ENTRY POINT */


{
/*————————-WITHIN START-UP CODE—————————*/
if ((taskid = fl_proc_init(name,desc)) == ERROR)
/* first library call: */
{ /* tell the Kernel who I am */
printf(“Cannot get task number\n”);
exit(1); /*abort for stated reason */
}
while (fl_test_term_flag(taskid) == OFF)
/* continue execution until */
{ /* flag is turned ON */
/*——————-MAIN LOOP OF TASK-DEPENDENT CODE—————*/
/*————————————-GOES HERE——————————-*/
}
/*—————————-WITHIN CLEAN-UP CODE————————*/
fl_proc_exit(taskid); /* tell Kernel I'm exiting */
/
exit(0)/* exit to OS */
}

FactoryLink Programmer’s Access Kit / 123


• PAK LIBRARY SERVICES
• Kernel Interface Services


Obtaining Task Environment Information

The Kernel provides read-only access to the FactoryLink environment attributes. The
environment access services consist of the following functions.

Function Description
fl_get_env Returns KENV structure of the client process.
fl_get_ctrl_tag Returns control tag for the specified process.
fl_get_stat_tag Returns value of the Real-Time Database analog status tag for the
specified process.
fl_get_msg_tag Returns value of the Real-Time Database message tag for the
specified process.
fl_get_pgm_dir Returns program directory for the specified process.
fl_get_app_dir Returns application directory for the specified process.
fl_get_cmd_line Returns command line for the specified process.
fl_get_title Returns pointer to the name of the product (FactoryLink).
fl_get_copyrt Returns a pointer to a copyright message.
fl_get_version Gets the Kernel version number.

Locking and Unlocking the Kernel

Function Description
fl_lock Locks the Real-Time Database on behalf of the calling process.
fl_unlock Unlocks the Real-Time Database for the calling process.

Often times, a task needs to transact several operations with the Kernel without being
interrupted by another task.

For example, a task may want to both write a value to a tag and clear its change bit for that tag
without the possibility of another task writing a value to that tag between the two operations,
which would result in the task missing the change since it subsequently clears the change flag.

By placing an fl_lock( ) and fl_unlock( ) combination around small portions of the code, the
task assures that intermediate values will be unavailable until the transaction is over. However,
care must be taken with these functions for no other tasks can access the Kernel while a lock is
held. Lengthy locks seriously degrade performance and an unreleased lock prevents the entire
application from performing any work.

124 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

Signals
6
Signals are notifications of events, particularly change of status, sent by one process to another,
referred to as the target process. Signals are a form of inter-process communication (IPC). In

PAK Library Services


some cases, the Kernel itself may send a signal to a target process, but this is still a form of IPC
since the Kernel always executes in the context of the calling process and acts on its behalf.
The target process, rather than the caller, is notified of the event or what status has changed.

Mailbox services also provide an IPC mechanism to FactoryLink processes. Compared with
signals, mailboxes allow data passing and are more flexible; however, they are slower. Also,
messages sent to a given mailbox are placed in a queue, so they are read in the same order as
they are sent. Signals are prioritized but not queued.

Signals provide a primitive, but very fast, form of IPC; therefore, they are ideally suited for
process synchronization. Each signal is assigned a numerical value in the range 0-31 so only
32 different events can be described by signals. The following events are predefined by the
Kernel and have special meaning.

Signal Symbolic Name Meaning


0 FLC_SIG_TERMINATED Process has been terminated.
1 FLC_SIG_TERM_FLAG_SET Termination flag is set.
2 FLC_SIG_TAG_LIST_CHANGED Tag list has been changed.
3 FLC_SIG_MESSAGE_RECEIVED Message has been received.

The signal services consist of the following functions.

Function Description
fl_send_sig Sends a signal to a target process.
fl_recv_sig Receives a signal for the calling process.
fl_hold_sig Prevents or allows signal delivery for the calling process.

Miscellaneous Session Services

The Kernel provides service functions to do miscellaneous odd jobs that fall into none of the
other categories. These include database lock/unlock functions (semaphores), sleep/wake
functions, initialization functions, and system data item retrieval functions.

FactoryLink Programmer’s Access Kit / 125


• PAK LIBRARY SERVICES
• Kernel Interface Services


The miscellaneous services consist of the following functions.

Function Description
fl_get_tick Gets the current clock tick and/or current date and time
maintained and reported by the operating system.
fl_global_tag Retrieves the tag number for one or more global tags.
fl_name_to_id Translates a process name to a FactoryLink ID.
fl_id_to_name Translates a FactoryLink ID to a process name.
fl_sleep Forces program to release the CPU for a given period of
time.
spool Sends a file to the FactoryLink spool task.

Database Access Services


The Real-Time Database Access section discusses transferring data values to and from the
Real-Time Database. Topics covered are
• Reading and Writing Tag Database Values
• Change Bits
• Reading and Writing Mailbox Messages

Any task may read a given tag; however, only one task, the “defining task,” should write it.
This restriction is not enforced, but it is a good design technique to use to avoid possible
ambiguity in the Real-Time Database.

Using Database Access Functions

The database access functions are functions callable by C-language application and system
programs. The Library functions make calls to the Kernel. The Kernel maintains the
Real-Time Database shared among all client processes and permits client processes to access it
only through these functions.

The database access services consist of the following functions.

Function Description
fl_read Reads specified tags from the Real-Time Database.
fl_write Writes specified tags to the Real-Time Database.
fl_forced_write Force-writes a specified tag to the Real-Time Database.

126 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

Function Description
6
fl_wait Waits to read, write, or access the Real-Time Database or certain
tags in the database.

PAK Library Services


fl_change_wait Reads the first tag that has changed since it was last read; if no
change, goes to sleep until a change occurs.
fl_change_read Reads the first tag that has changed since it was last read.
fl_set_chng Sets the calling task change-status flags for specified tags.
fl_clear_chng Clears the calling task change-status flags for specified tags.
fl_get_tag_info Gets the information associated with a specified list of tags.
fl_set_wait Sets the calling task wait flags for specified tags.
fl_clear_wait Clears the calling task wait flags for specified tags.

Real-Time Database

The corresponding typedefs for each data type are found in FLIB.H.

Database Tags

A tag consists of the following items:


• One or more bits containing the tag value
• Set of change-status bits
• Set of wait bits

Each set of bits consists of a single bit for each client process or, more properly, for each
potential client process. A process does not officially become a client process until it registers
with the Kernel by initializing the calling process through a call to fl_proc_init( ), but the bits
still exist.

Change-status bits. For each database tag, each possible client process has one change-status
bit. If the value of a bit is 0, the value has not changed since client (or task) number N last read
the tag where N = 0 through 30. The value of the bit is set to 1 when a new value is written to
the tag.

Wait bits. Each possible client process has one wait bit. When the client is currently waiting to
read or to write the specified tag, the value of the bit is 1; otherwise, the value is 0. A client can
set the value of a wait bit to 1 by performing one of the following actions:
• Call fl_change_wait( ). This sets the value to 1 only if none of the specified tags has
changed (it sleeps until someone writes a new value into one or more of the tags).
• Call fl_set_wait( ).

FactoryLink Programmer’s Access Kit / 127


• PAK LIBRARY SERVICES
• Kernel Interface Services


Tag Number. In the Kernel, a tag number completely specifies a database tag because it
includes the data type as well as the array index. All database access service operates on mixed
types; that is, on tags of various data types defined and allocated at run time.

Locking/Unlocking Database

The Kernel automatically locks the database during execution of any of these database access
functions and unlocks it upon completion. This ensures service calls are atomic operations in
the sense that, once begun, they cannot be interrupted by service calls from other clients. The
only exception is when the calling process may block another process waiting to write
synchronous tags.

VAL Union Structure

All database types besides message and mailbox are read and written the same way, accessing
the correct member of the union.

Database Type Union


DIGITAL val.dig
ANALOG val.ana
LONGANA val.lana
FLOAT val.flp
MESSAGE val.msg
MAILBOX val.mbxmsg

Sample Database Access Functions

The following examples illustrate the use of the database access functions in the FactoryLink
Library. These examples are not complete C programs. None of the examples illustrates the
interaction of the task with the Run-Time Manager.

Example A

Example A demonstrates how to use fl_read( ) to read messages from the database.
.
.
int task_id
TAG t;
VAL v;
char buffer[100];

v.msg.m_ptr = buffer;

128 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

v.msg.m_len = 0;
v.msg.m_max = sizeof(buffer);
fl_read(task_id, &t, 1, &v);
6
.

PAK Library Services


.

Example B

Example B demonstrates how to use fl_write( ) to write messages into the database.
.
.
int task_id;
TAG t;
VAL v;
char buffer[100];

strcpy( buffer, “The temperature is”);


v.msg.m_ptr = buffer;
v.msg.m_len = strlen(buffer);
v.msg.m_max = sizeof(buffer);
fl_write(task_id, &t, 1, &v);
.
.

Example C

Example C demonstrates how to use fl_read( ) to read analog values from the database.
.
.
int task_id;
TAG t;
VAL v;

fl_read(task_id, &t, 1, &v);


printf( “The ANALOG value is %d\n”, v.ana);
.
.

Example D

Example D demonstrates how to use fl_write( ) to write analog values to the database.
.
.
int task_id;
TAG t;
VAL v;

FactoryLink Programmer’s Access Kit / 129


• PAK LIBRARY SERVICES
• Kernel Interface Services

v.ana = 100;
fl_write(task_id, &t, 1, &v);
.
.

Mailbox

A mailbox is a tag that holds a queue of mailbox messages consisting of structures (typedef
MBXMSG) and some associated message data. Since mailboxes are tags, a process can read
and write values to them just as with other types of database tags; that is, the following
functions work when passed to a mailbox tag:
• fl_read( )
• fl_write( )
• fl_forced_write( )
• fl_change_read( )
• fl_change_wait( )
When messages are present in a mailbox, the change bit for the associated tag is set to 1. When
the mailbox is empty, the change bit for the associated tag is clear (value of 0).

Mailbox services provide an inter-process communication (IPC) mechanism to FactoryLink


processes. The services allow one process to send a mailbox message (typedef MBXMSG), a
structure that can hold arbitrary data of variable length, to another process.

Signal services also provide an IPC mechanism to FactoryLink processes. Compared with
signals, mailboxes allow data passing and are more flexible; however, they are slower. Also,
messages sent to a given mailbox are placed in a queue so they are read in the same order as
they are sent. Signals are prioritized but not queued.

fl_read_app_mbx( ) allows messages to be read in a different order than they were sent.

The message queue associated with a mailbox contains a head and a tail. The head of the queue
is the oldest message in the mailbox; the tail is the newest. Mailbox message reads occur at the
head or relative to the head of the queue; writes always occur at the tail.

The mailbox services consist of the following functions.

Function Description
fl_count_mbx Determines the number of messages in a mailbox, validates a
mailbox, or monitors a mailbox.
fl_query_mbx Queries a mailbox for a range of queued messages.

130 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

Function Description
6
fl_read_app_mbx Reads and dequeues a message from a mailbox.

PAK Library Services


fl_write_app_mbx Writes and queues a message into a mailbox.
fl_set_owner_mbx Sets the owner of a mailbox.

Some tasks communicate with each other via FactoryLink mailbox messages. It is possible to
configure an application so that these tasks are on different nodes, and the mailbox messages
and replies are sent across the network by FL/LAN. This is transparent to the tasks, but the
following conventions must be observed; otherwise, FL/LAN will not handle replies correctly.

If the task sending the mailbox message is expecting a reply, it should put the mailbox tag of
where it wants the reply sent into the mm_mbx field of the mailbox message. If it does not
want a reply, it should set mm_mbx.t_type and mm_mbx.t_data to 1 (0xFFFF). Otherwise,
FL/LAN thinks it wants a reply and since it will never get one, FL/LAN’s internal table where
it stores pending replies will fill up.

Also, if a reply is expected, the mm_sendid of the mailbox message must contain the sending
task’s FactoryLink task id; otherwise, FL/LAN will not be able to write the reply to the correct
instance of a user domain mailbox tag (since FL/LAN runs in the shared domain).

Calling and Return Conventions


The Calling Conventions and Exception Reporting section discusses how the Kernel reports
errors.

Function Description
fl_errno Returns the last error number generated by the calling process.

The following calling and return conventions apply to application programs that call any of the
FactoryLink Library functions:
• Most functions in the library return an item of C data type int.
• A return value of -1 invariably indicates the function failed. The reason for such a failure
depends on the function and the circumstances it is called under.

The calling task must call fl_errno( ) with its task id to access the specific failure code error.

In the source code, the error numbers may be referred to by the integer value or the symbolic
representation of the number. We recommend using the symbolic representation. For example,
the symbolic representation of 0 is GOOD. A line of code might read as follows:
if (fl_proc_init(“SKEL”,”Skeleton Task”) != GOOD)

FactoryLink Programmer’s Access Kit / 131


• PAK LIBRARY SERVICES
• Kernel Interface Services


This code checks whether the return value from a request to connect to the Kernel indicates an
error occurred. When the symbolic representation of GOOD is used, this code does not require
any changes if, for some reason, the integer value of GOOD is later changed to a value other
than 0. If the integer value is used in the code and it changes, the code must be changed and
recompiled.

The symbolic representations of these error numbers are found in the header file FLIB.H.

Return Reference List

Use the following lists (excerpts from FLDEFS.H) as references for error numbers.

Error
FactoryLink Error Codes Description
Number
FLE_INTERNAL 1 General error code.
FLE_OUT_OF_MEMORY 2 Memory allocation error because of
system exhaustion or FactoryLink
allocation.
FLE_OPERATING_SYSTEM 3 Unable to map Kernel semaphores.
FLE_NO_FLINK_INIT 4 Cannot locate Real-Time Database for
given {FLNAME}.
FLE_NO_PROC_INIT 5 Cannot locate Real-Time Database
area for {FLDOMAIN}+{FLUSER}.
FLE_BAD_FUNCTION 6 Reserved.
FLE_BAD_ARGUMENT 7 Bad input parameter passed into
function.
FLE_BAD_DATA 8 TAG structure received with an
invalid offset member.
FLE_BAD_TAG 9 TAG structure received with an
invalid type or offset member.
FLE_NULL_POINTER 10 Reserved.
FLE_NO_CHANGE 11 Change read/wait function call failed
because no changes for given tag
array.
FLE_PROC_TABLE_FULL 12 Maximum number of tasks has
registered for the given
{FLNAME}/{FLDOMAIN}/
{FLUSER}.
FLE_BAD_PROC_NAME 13 Invalid task name received.

132 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Kernel Interface Services

Error
FactoryLink Error Codes
Number
Description 6
FLE_BAD_USER_NAME 14 Invalid user name received.

PAK Library Services


FLE_BAD_OPTION 15 Reserved.
FLE_BAD_CHECKSUM 16 Reserved.
FLE_NO_OPTIONS 17 Reserved.
FLE_NO_KEY 18 Reserved.
FLE_BAD_KEY 19 Reserved.
FLE_NO_PORT 20 Reserved.
FLE_PORT_BUSY 21 Reserved.
FLE_ALREADY_ACTIVE 22 Initializing task with same name as
one currently running.
FLE_NOT_LOCKED 23 Attempted to unlock Kernel without
holding a lock.
FLE_LOCK_FAILED 24 Unable to attain lock to the Kernel.
FLE_LOCK_EXPIRED 25 Attempted to release a lock that has
expired on the Kernel.
FLE_WAIT_FAILED 26 Invalid task ID passed into fl_wait( ).
FLE_TERM_FLAG_SET 27 Termination flag for given task ID set
to ON.
FLE_QSIZE_TOOBIG 28 Internal error - failed to allocate
mailbox queue.
FLE_QSIZE_CHANGED 29 Internal error - inconsistent queue
size.
FLE_NO_TAG_LIST 30 Reserved.
FLE_TAG_LIST_CHANGED 31 Reserved.
FLE_WAKEUP_FAILED 32 Failure occurred awakening task
sleeping on the Kernel.
FLE_NO_SIGNALS 33 No signals pending for caller.
FLE_SIGNALLED 34 Task awakened by signal from another
task.
FLE_NOT_MAILBOX 35 Called mailbox function with a tag not
of type MAILBOX.
FLE_NO_MESSAGES 36 No mailbox messages pending for
mailbox tag.

FactoryLink Programmer’s Access Kit / 133


• PAK LIBRARY SERVICES
• Kernel Interface Services


Error
FactoryLink Error Codes Description
Number
FLE_ACCESS_DENIED 37 Cannot read a mailbox message
targeted for another task.
FLE_ATTR_FULL 38 Attribute name table full.
FLE_INVALID_ATTR 39 Invalid attribute name.
FLE_ATTR_NOT_DEF 40 Cannot find requested attribute.
FLE_APP_EXISTS 41 Attempted to start application with
same {FLNAME} as one running.
FLE_NO_FLINK_RTDB 42 Unable to map to kernel memory area
for {FLNAME}.
FLE_NO_TASK_BIT 43 Task protection bit not set for
initializing task.
FLE_NOT_LITE_TASK 44 Attempted to start restricted task from
running in a Lite system.
FLE_SEM_OP 45 Unable to get or release semaphose.
FLE_MBXLIM_EXCEED 46 Mailbox message space exhausted.
FLE_FLOAT_NAN 50 Float (FLP) is not-a-number.
FLE_FLOAT_POS_INF 51 Float (FLP) is positive infinity.
FLE_FLOAT_NEG_INF 52 Float (FLP) is negative infinity.

134 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
CT Access Services

CT A CCESS S ERVICES
6
CT access functions allow client processes to access the CT archives. The term archive refers

PAK Library Services


to the binary CT file containing data for more than one database table. For example, the
TIMER.CT file contains information for the event timer and interval timer database tables. A
typical application has a function that opens the task CTs and reads them into memory. The
write CT access functions are the complement of the CT read functions. Use them to create
and/or modify the CT archives.

The CT access services consist of the following functions.

Function Description
ct_open Opens a CT archive file.
ct_read_index Reads an index from a CT archive.
ct_read_hdr Reads the header for ctp into buffer.
ct_read_rec Reads a record from the current CT into memory.
ct_read_recs Reads records from the current CT into memory.
ct_close Closes a CT archive.
ct_create Creates/truncates/opens a CT for update.
ct_find_index Finds an index.
ct_get_hdrlen Gets the length of the current CT table header.
ct_get_name Gets the name of the current CT table.
ct_get_ncts Determines the number of CT tables in the archive.
ct_get_nrecs Determines the number of records in the last selected CT table.
ct_get_reclen Determines the record length of records in the current CT table.
ct_get_type Gets the type field from the current CT table.

FactoryLink Programmer’s Access Kit / 135


• PAK LIBRARY SERVICES
• CT Access Services

Error Codes Number Description


CT_CANNOT_OPEN_FILE 1 File is missing.
CT_CANNOT_CLOSE_FILE 2 Program bug.
CT_FILE_NOT_OPEN 3 Program bug.
CT_SEEK_ERROR 4 Wrong file size.
CT_READ_ERROR 5 Wrong file size.
CT_WRITE_ERROR 6 Drive not ready or disk full.
CT_BAD_MAGIC 7 File corrupted.
CT_BAD_DATA 8 File corrupted.
CT_NULL_POINTER 9 Program bug.
CT_BAD_INDEX 10 CT does not exist.
CT_BAD_RECORD 11 CT record does not exist.

136 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Object CT Access

O BJECT CT A CCESS
6
The object CT is a binary representation of a configuration database file similar to any other

PAK Library Services


task-specific CT. The main difference is the CT contains the contents of the application object
database, which is not tied to any one particular task. Another difference is a large application
with many objects requires special handling in order to fit within a standard CT.

The object CT API written using the PAK ct_...( ) primitives hides the details of how the object
database contents are coerced into a CT.

Overview of Object CT Services


The Object CT API mirrors the existing ct_...( ) API and provides the following services:
• Opening and closing of the object CT
• Object definition retrieval based on an object name
• Random access, block retrieval for object definitions

Overview of the Object CT API


Ignoring some organizational overhead, FactoryLink CTs equate to on-disk arrays of
C-structures. The object CT is no different, and consists of many arrays of the following
structure:
typedef struct _flobjrec
{
char tagname[MAX_TAG_NAME+1];
char tagdomain[MAX_USR_NAME+1];
char tagtype[MAX_TYPE_NAME+1];
char tagdescr[MAX_PROC_DESC+1];
char tagdimen[MAX_DIM_LENGTH+1];
u16 tagperwhen;
u16 tagchgbits;
TAG tagno;
} FLOBJREC;

FactoryLink Programmer’s Access Kit / 137


• PAK LIBRARY SERVICES
• Object CT Access


This structure reflects the current attributes that define a FactoryLink object. Applications
should treat this structure as opaque and not access its members directly. A function-based
interface, included with the Object CT API, should be used to query FLOBJREC’s values.
Using the API shields the PAK task from future changes that alter the object structure and its
members yet ignores the interface.

The Object CT API is a data abstracted set of functions. Its usage generally follows some
variant of the following sequence:
• Open the application object table
• Search for definitions for one or more objects
• Close the object table

Code Sample: Printing All Objects in a Particular Domain


#include <objct.h>

/*
* Function print_objs4dom writes to standard output all objects
* configured for a particular domain.
*/
int print_objs4dom(char *flapp, char *tgt_dom)
{
FLOBJREC rec;
u32 nrecs;
u32 k;
CT objct;

if (ct_open_obj(&objct, flapp) != GOOD)


return ERROR

nrecs = ct_nrecs_obj(objct);
for (k = 0; k < nrecs; k++)
{
ct_read_objs(objct, &rec, k, 1);

if (strcmp(tgt_dom, flobjrec_get_domain(rec)) == 0)

138 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Object CT Access

{
printf(“Object %s in domain %s\n”, 6
flobjrec_get_name(rec), tgt_dom);

PAK Library Services


}
}
ct_close_obj(&objct);
return nrecs;
}

An object is a user-defined name associated with a set of attributes, such as type, dimension,
and domain. This set of attributes equates to the object definition.

An application consists of many objects. Open the Configuration Explorer and right click on
“MyStarterApp” and select View > View Object Table to view the objects defined within an
application. The resulting list shows all objects with their definitions.

Object CT API Reference

Function Description
ct_find_obj Finds object definition for given object name.
ct_nrecs_obj Returns the number of object definitions held in CT.
ct_open_obj Opens object CT.
ct_read_obj Reads object definition(s) from object CT.
flobjrec_get_chgbits Extracts change bits attribute from object definition.
flobjrec_get_descr Extracts description attribute from object definition.
flobjrec_get_dimen Extracts dimension attribute from object definition.
flobjrec_get_domain Extracts domain attribute from object definition.
flobjrec_get_name Extracts the name from object definition.
flobjrec_get_perwhen Extracts persistence attribute from object definition.
flobjrec_get_tag Extracts tag attribute from object definition.
flobjrec_get_type Extracts type attribute from object definition.

FactoryLink Programmer’s Access Kit / 139


• PAK LIBRARY SERVICES
• Direct Tag Processing


D IRECT TAG P ROCESSING
FactoryLink tasks are exception driven. The value of a tag changes, causing the task to perform
an action in response. In fact, the main processing loop of these tasks usually resembles the
following pseudo code:
while (no task termination flag)
{
Wait for tag value change;
Find what action(s) are associated with the change;
Invoke the actions(s) for the tag value change;
}

The FactoryLink Kernel library services provide the low-level functionality required to
awaken upon Real-Time Database value changes as well as to identify which value changed.
However, determining the actions the task is to take for that change is left to the developer.

This is where the Direct Tag Processing (DTP) API enters the picture. The FLDTP API wraps
itself around the Kernel services and presents a higher level interface to the developer. With
DTP, the developer associates an action directly with the tag. In other words, whenever the
value of a tag changes, its associated action is invoked. Therefore, the value-add for DTP is the
developer spends more time on writing the processing than on routing value changes to the
processing.

The FLDTP API features are:


• Associating one or more actions directly with a tag change.
• Dynamic addition/removal of actions through the task run-time.
• Blocking/non-blocking processing of tag value changes.
• Priority-based processing of tag value changes.

Direct Tag Library Services


The DTP has a fairly standard life-cycle. It is created. It is loaded with tags and actions. These
tags and actions are then processed. As the program continues, existing tags/actions are
removed and/or new ones are added. Finally, the task terminates, destroying the DTP during its
exit.

This section categorizes the interfaces exposed by the FLDTP API. It should also help you
envision how to make it work for your task. All of the code samples have been taken from the
PAK Skeleton task.

140 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Direct Tag Processing

Instantiating the DTP


6
In general terms, the DTP is a container of actions bound to tags with the normal overhead of
construction, attribution, and destruction functionality.

PAK Library Services


DTP Data Structures

External C-Structures Description


fldtp Trigger manager.
fldtp_action Action/tag binding record.
fldtp_tag Tag inserted into DTP.

The main structure is fldtp. This structure is the tag manager and most work with the FLDTP
API requires a handle to one of its instances.

The next most visible structure is the fldtp_action( ) or action record. The action record
represents one process to invoke on behalf of a tag.

Finally, the fldtp_tag( ) structure represents a tag inserted into the DTP. Several actions can be
chained off the same tag. Users normally do not directly operate upon this structure.

DPT Instance

Function Description
fldtp_create Creates a DTP instance.
fldtp_destroy Destroys a DTP instance.
fldtp_get_comparef Get DTP comparison function pointer.
fldtp_get_msglen Get DTP message tag read buffer size.
fldtp_get_tagcnt Get DTP tag count.
fldtp_set_comparef Set DTP ID comparison function pointer.
fldtp_set_msglen Set DTP message tag read buffer size.
fldtp_set_proc_by Set DTP message tag read buffer size.

To use DTP, an instance of it must be created. Depending on the complexity of the program,
there may be several DTP instances.

An fldtp instance equates to a tag process manager. Through it, tag processing actions are
added, invoked, and removed. It serves as a container for all the events that the task needs to
respond.

FactoryLink Programmer’s Access Kit / 141


• PAK LIBRARY SERVICES
• Direct Tag Processing


Code Sample: Creating and Destroying a DTP Instance
#include <flib.h>
#include <fldtp.h>

id_t Task_id = -1;


FLDTP *TrigMgr = NULL;

int main(int argc, char *argv[])


{
....
. Attach to the Kernel
....
/* Create the trigger manager */
if (fldtp_create(&TrigMgr) != FLDTP_E_GOOD)shutdown(1);
....
. Continue task initialization…
....
}

void shutdown(int error)


{
fldtp_destroy(TrigMgr); /* release all trigger info */
fl_proc_exit(Task_id); /* terminate FactoryLink access */
exit(error); /* exit to OS */
}

DTP Action Record

Function Description
fldtp_action_get_args Get associated user-defined arguments.
fldtp_action_get_destroyf Get associated destruction notification function pointer.

142 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Direct Tag Processing

Function Description
6
fldtp_action_get_id Get associated ID.

PAK Library Services


fldtp_action_get_priority Get associated priority.
fldtp_action_set_args Set associated user-defined arguments.
fldtp_action_set_destroyf Set associated destruction notification function pointer.
fldtp_action_set_id Set associated ID.
fldtp_action_set_priority Set associated priority.

An action record (the fldtp_action( ) structure) contains all the information required to process
its associated tag. The user does not directly create these records. Instead, an action record is
created on behalf of the user whenever a tag action is inserted into the DTP.

Many attributes can be attached to the action record once its handle has been returned to the
user.

Loading Actions into the DTP

Function Description
fldtp_insert Insert tag/action into DTP.

Once the DTP is created, tags, along with their actions, need to be loaded into it. In terms of
code, this means calling the function dtp_insert( ) with the appropriate parameters: the handle
to the DTP instance to insert the action into, the tag the action is to be bound to, and the action
to be invoked. The term action means the pointer to the process function to invoke with the tag
value.

A successful insert into the DTP returns the handle to the action record that embodies the
inserted information. With this handle, additional attributes can be attached. Of these
attributes, the user data arguments are the most important. User data arguments are an array of
pointers to information related to the tag action. When processing tag actions, these pointers
are passed to the process function along with the tag value.

To illustrate, consider the following code sample. Here, a trigger is being inserted into the DTP.
Once inserted, the related CT information is attached to the action record representing this
trigger event. Later, when DTP invokes action, function proc_trig( ) is called and the CT
information will be passed to it. Also, a destruction notification function free_triginfo( ) is
being attached to the action record. This allows the task to release the memory held by CT
information when the action record is later destroyed. This attachment would not be necessary
if the memory allocated for the CT information was managed elsewhere.

FactoryLink Programmer’s Access Kit / 143


• PAK LIBRARY SERVICES
• Direct Tag Processing


Code Sample: Inserting into the DTP.
{
FLDTP_ACTION *ap;
TRIGINFO *tip;
....
. Read a CT header and all its records. Allocate and store at ‘tip’.
....
r1 = fldtp_insert(TrigMgr, &hdr_buf.trigger, proc_trig, &ap);
r2 = fldtp_action_set_args(ap, 1, (void**) &tip);
r3 = fldtp_action_set_destroyf(ap, free_triginfo);
if (r1 != FLDTP_E_GOOD || r2 != FLDTP_E_GOOD || r3 != FLDTP_E_GOOD)
{
status("TRIGMGR", FLS_INACTIVE);
shutdown(1);
}
....
. Read the next header from the CT…
....
}

144 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Direct Tag Processing

Processing Actions with DTP


6
Function Description

PAK Library Services


fldtp_proc Process all actions loaded into DTP.
fldtp_proc_action Process an individual action immediately.
fldtp_proc_change Process all actions tied to changed tags.
fldtp_proc_tag Process all actions tied to an individual tag.
fldtp_proc_wait Process all actions tied to changed tags. If none, wait.
fldtp_wait Wait for any tag in DTP to change.

Once the DTP is loaded with the tags and their actions, the next step is to process them. Each
of the process functions in the preceding table offer a unique scope of processing. The most
commonly used is fldtp_proc_wait( ) where the task sleeps until one or tags within the DTP
change. At that time, the actions tied to the changed tags are invoked and control is returned to
the caller. The other process functions either restrict processing to a particular subset of DTP
entries or tune its blocking/non-blocking behavior. The following scrap depicts the normal
process of a FactoryLink task using DTP:

Code Sample: Processing with DTP


while ( fl_test_term_flag(Task_id) == OFF )
fldtp_proc_wait(TrigMgr, Task_id);

Since the DTP invokes the action functions directly, the only work to perform outside of the
process function is to check the task termination flag.

As for the work to perform from within the process function, note the following code sample
that depicts a simple process function. Whenever a tag associated with process function
proc_trig( ) changes, function fldtp_proc_wait( ) invokes that function with the following
arguments: the tag, its value, and the associated user-defined arguments.

FactoryLink Programmer’s Access Kit / 145


• PAK LIBRARY SERVICES
• Direct Tag Processing


Code Sample: A DTP Process Function
void proc_trig(TAG *tag, VAL *val, short f_argc, void *f_argv[])
{
TRIGINFO *tip;
char msgbuf[80];
if (val->dig == 0) /* Ignore 'zero' triggers */return;
tip = (TRIGINFO*) f_argv[0];
....
. Process the trigger...
....
}

The above code sample takes the tag value from the digital member of the VAL union. This is
because the Skeleton task restricts its triggers to type DIGITAL. For more information on VAL
union, see “fl_read” in Chapter 7 in the API Library.

Removing Actions From DTP

Function Description
fldtp_remove Remove tag/action into DTP.
fldtp_remove_group Remove actions from DTP based on a criteria.

Most tasks initialize the DTP with a set of tags and their actions and never adjust them again
for the life of the task. These tasks do not need to use DTP’s removal function. More
sophisticated tasks, however, may very well need to dynamically alter their processing lists
over the task lifetime.

When a particular action is no longer required, it should be removed from the DTP so the task
need not wake-up unnecessarily. There are two ways to accomplish this. First, function
fldtp_remove( ) accepts the handle the particular action record to remove. While very surgical
and quick, the downside to this is the developer must keep track of all action records held
within the DTP.

The second way is to use function fldtp_remove_group( ). Here, the caller specifies a criteria
used to remove records from the DTP. This criteria is any combination of action function
pointer, user-defined ID, or tag binding. This allows the caller to remove particular records
without necessarily recording the individual handles to each and every DTP insertion the task
has ever made.

146 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Direct Tag Processing

FLDTP API Exit Codes


6
Functions of the FLDTP API always return one of the following exit codes.

PAK Library Services


Error Code Value Description
FLDTP_E_ GOOD 0 No error occurred.
FLDTP_E_INTERNAL -1 General failure indicator.
FLDTP_E_ INVARG -2 Invalid argument passed to function.
FLDTP_E_INVTAG -3 Invalid tag passed into function.
FLDTP_E_NOMEM -4 Memory allocation failure.
FLDTP_E_NOTFND -5 Cannot find requested object.
FLDTP_E_ILLPROC -6 Illegal call to procedure at given time. Some
DTP functions are not re-entrant.
FLDTP_E_ KERFAIL -7 Kernel function call failed. Call fl_errno( ) for
details.
FLDTP_E_INKTYPE -8 Tag of unknown type passed into function.
FLDTP_E_NOCHANGE -9 No tag changes are pending.

FactoryLink Programmer’s Access Kit / 147


• PAK LIBRARY SERVICES
• Normalized Tag Reference Services


N ORMALIZED TAG R EFERENCE S ERVICES
A FactoryLink object is a named instantiation of a data type of digital, analog, float, long
analog, message, or mailbox. The object may be a single instance of its data type or it may be
an array containing multiple instances of the same data type. The name of a FactoryLink object
is referred to as the object name.

A FactoryLink object may be a member of another object to connote a structured view. A


member FactoryLink object has equal standing with its parent object, save that it cannot have
members of its own. A member tag can be arrayed, but these usually parallel the dimensions of
its parent object.

Finally, FactoryLink object may have a local or remote value source. This source is known as
its node. This node is sometimes referred to as an external domain.

A tag refers to a single location within the FactoryLink Real-Time Database. A FactoryLink
object equates to one or more tags, depending on whether it is an arrayed object and/or whether
it has member objects associated with it.

Given these parameters, a reference to a FactoryLink object conforms to the following syntax:
[{node}:]{name}[[dimensions]][.member]

where:
node (optional) The source node for the given tag
name The base name for the tag
dimension (optional) The particular number for an arrayed tag
member (optional) The sub-component identifier for the base tag

For example, the object reference plc1:tagx[4][5].raw has a node of plc1, a name of tagx, the
dimensions of [4][5], and a member of raw.

This syntax provides the precision required to resolve an object reference to a single,
Real-Time Database location (or tag).

Also given this syntax, the combination of a reference node, name, and member equates to the
name of the object, as seen through Configuration Explorer object list table. Please keep in
mind the object name component may not be sufficient to uniquely identify a tag. It must be
accompanied by its associated source, dimension, or member attributes.

148 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Normalized Tag Reference Services

FLNTAG Services Overview


6
The syntax for a tag reference becomes complex when associated attributes are prefixed and/or
appended onto it. Even a simple reference, such as x[5], requires a significant amount of

PAK Library Services


parsing and interpretation.

The FLNTAG API consolidates this processing into a single interface. References can be
decomposed into their base components, have these components modified individually, and
ultimately recombined into a reference string. The API also provides hooks for obtaining
object definitions and RTDB locations.

The services provided by the FLNTAG API are


• Creation and destruction of an FLNTAG instance
• Decomposition of a tag reference string into a FLNTAG
• Object definition and RTDB location retrieval based on the FLNTAG
• Component level manipulation of a FLNTAG
• Generation of a string (reference, object name, …) from a FLNTAG

FLNTAG API Overview


The FLNTAG API is a data-abstracted set of functions. Its operation generally follows some
variant of the following sequence:

1. Open the application object table (table containing all known objects)

2. Create an FLNTAG instance

3. Load a tag reference string into the FLNTAG

4. Obtain the RTDB location for the reference, using the FLNTAG API

5. Destroy the FLNTAG instance

6. Close the object table

Therefore, the reference location within the RTDB can be determined in a hands-off manner.
Additionally, should the syntax for a reference change, code based on the API need not change
to support it.

FactoryLink Programmer’s Access Kit / 149


• PAK LIBRARY SERVICES
• Normalized Tag Reference Services


Code Sample: Converting a Tag Reference to a TAG
#include <flntag.h>

/*
* Function convert_ref2tag() returns the RTDB location for the
* given reference.
*/
int convert_ref2tag(char *flapp, char *tagref, TAG *tag)
{
FLNTAG *ntag;
CT objct;
int rv;

if (ct_open_obj(&objct, flapp) != GOOD)


return ERROR

if ((ntag = flntag_create()) != NULL)


{
if ((rv = flntag_parse_ref(ntag, tagref)) == FLNTAG_E_GOOD)
rv = flntag_find_tag(ntag, &objct, tag);

rv = (rv == FLNTAG_E_GOOD) ? GOOD : ERROR;


flntag_destroy(ntag);
}
else
{
rv = ERROR;
}

ct_close_obj(&objct);
return rv;
}

150 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Normalized Tag Reference Services

FLNTAG Return Codes


6
The following table lists the return codes defined in FLNTAG.H with their meanings.

PAK Library Services


Return Code Number Description
FLNTAG_E_GOOD 0 Function successful.
FLNTAG_E_GENERAL -1 Internal error.
FLNTAG_E_HANDLE -2 Invalid FLNTAG structure handle.
FLNTAG_E_INVARG -3 Invalid argument passed to function.
FLNTAG_E_NOMEM -4 Memory allocation failure.
FLNTAG_E_REFSYN -5 Illegal syntax for tag reference.
FLNTAG_E_INVCHR -6 Invalid character found in given tag
reference.
FLNTAG_E_LENGTH -7 Invalid string length.
FLNTAG_E_DIMSYN -8 Invalid dimension syntax.
FLNTAG_E_DIMLEN -9 Invalid dimension string length.
FLNTAG_E_DIMNUM -10 Invalid number of dimensions.
FLNTAG_E_DIMRNG -11 Number of tags for single dimension too
large.
FLNTAG_E_MBRREF -12 Member tag reference passed when
expecting only a structured tag reference.

FLNTAG Function Listing

Function Description
flntag_calc_base Calculates base tag address from arrayed tag.
flntag_calc_tag Calculates arrayed tag address from base tag.
flntag_create Creates FLNTAG instance.
flntag_destroy Destroys FLNTAG instance.
flntag_find_def Returns tag definition for given FLNTAG structure.
flntag_find_tag Returns tag definition for given TAG structure.
flntag_gen_objname Generates object name string.
flntag_gen_ref Generates tag reference string.

FactoryLink Programmer’s Access Kit / 151


• PAK LIBRARY SERVICES
• Normalized Tag Reference Services


Function Description
flntag_gen_str Generates string from selected portions of given FLNTAG.
flntag_get_dimen Returns dimension component of given FLNTAG.
flntag_get_member Returns member component of given FLNTAG.
flntag_get_name Returns name component of given FLNTAG.
flntag_get_node Returns node component of given FLNTAG.
flntag_parse_brkt4dims Parses dimensions from bracketed string representation.
flntag_parse_comma4dims Parses dimensions from comma string representations.
flntag_parse_ref Loads a given tag reference string into an FLNTAG.
flntag_set_dimen Sets dimension component of given FLNTAG.
flntag_set_member Sets member component of given FLNTAG.
flntag_set_name Sets name component of given FLNTAG.
flntag_set_node Sets node component of given FLNTAG.

152 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Path Manipulation

P ATH M ANIPULATION
6
The functions beginning with the name fl_path( ) are all concerned with allowing developers

PAK Library Services


to write portable code with generic path name structures that can be automatically converted to
be system-specific.

The normalized path functions eliminate system-specific path name dependencies and allow
porting of code to different platforms without changes. FactoryLink multi-platform code
should use only these functions to generate path names, open file information, and search
directories.

It is essential you call the fl_path( ) functions instead of attempting to hard-code or build path
names using string functions into the programs if you plan on porting the applications to other
systems and on retaining compatibility with future releases of FactoryLink.

Path Name Building and Representation


Paths are represented as either a system-dependent character string or as a data structure
containing the parts of the path as individual strings. The data structure form is called a
normalized path name.

A normalized path contains the following components:


• Node name
• Device
• Directory
• File name
• Wild card pattern
• File date and time
• File size
• File type
• System-dependent information

This information is stored in the NPATH C-structure. The NPATH structure should be
considered opaque and its members should not be accessed directly. The fl_path( ) API
provides functions to extract member values.

FactoryLink Programmer’s Access Kit / 153


• PAK LIBRARY SERVICES
• Path Manipulation


Path Name Format
The complete path name for a file follows the format:
DISK:/DIRECTORY/SUBDIRECTORY/FILENAME

Partial path name for a file follows the format:


/DIRECTORY/SUBDIRECTORY/FILENAME

Path Name Format for Windows NT and Windows 95

The platform-independent path name format of


DISK:/DIRECTORY/SUBDIRECTORY/FILENAME

translates to
DRIVE:\DIRECTORY\SUBDIRECTORY\FILENAME

If a file named TIMER.CT is located in a subdirectory named CT in the {FLAPP} directory,


the file name in this guide is specified as {FLAPP}/CT/TIMER.CT. The file name has the
format {FLAPP}\CT\TIMER.CT. The boldfaced type on {FLAPP} indicates this refers to the
default or operator-specified name of the application-related directory specified during
installation.

fl_path( ) functions under Microsoft Windows NT, Windows 95 normalize paths as follows:
• If a DOS-style path string is supplied to fl_path_norm( ), FactoryLink assumes any name
following the last slash character is a file name.
• If a path refers to a directory, add a trailing slash to the path name in order for
fl_path_norm( ) to normalize the path as a directory.
• If the path refers to a directory and adding a trailing slash is a problem, use the
fl_path_set_dir( ) function to normalize the path.

Use of Environment Variables in Path Names


The fl_path( ) API functions allow specification of environment variables in a multi-platform
path. An environment variable is indicated by placing the environment variable name inside
braces {}. For example, assuming that {FLAPP} is set to /users/myflapp and {FLDOMAIN}
is set to SHARED, the multi-platform path myflapp/ct is expanded to
/users/{FLINK}/{FLAPP}/shared/ct. This macro expansion takes place automatically
whenever braces are used around the name of a valid environment variable within a path name.
The following API functions recognize and expand environment variables:
• fl_path_norm

154 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Path Manipulation

• fl_path_add_dir
• fl_path_set_dir 6
• fl_path_set_file

PAK Library Services


• fl_path_set_pattern
• fl_path_set_node
• fl_path_set_device

Allocating/Destroying a Normalized Path


NPATH *fl_path_alloc(void)
void fl_path_free(NPATH *p)

The function fl_path_alloc( ) allocates and returns a pointer to a normalized path buffer. This
function should be called rather than allocating the NPATH structure directly so you can add a
buffer for system-dependent information to the path buffer.

The function fl_path_free( ) releases the space allocated by a call to fl_path_alloc( ). The
NPATH structure should not be accessed after fl_path_free( ) is called. This leads to
unpredictable behavior of the system.

Converting To/From a Normalized Path


char *fl_path_sys(NPATH *p, char *path, size_t length)
NPATH *fl_path_norm(NPATH *p, char *path)
NPATH *fl_path_set_dir(NPATH *p, char *dir)
NPATH *fl_path_cwd(NPATH *p)

The function fl_path_sys( ) converts a normalized path into a system specific path string. If the
path argument is null, fl_path_sys( ) calls malloc( ) to allocate memory for the resulting path.
Release the memory when it is no longer in use.

fl_path_norm( ) converts a system-specific path string into a normalized path. Alternatively,


the fl_path_set_dir( ) function is used if the path refers to a directory.

fl_path_set_dir( ) replaces the directory portion of the path and the directory argument is
converted to normalized form. If the NPATH argument is NULL, fl_path_set_dir( ) first calls
fl_path_alloc( ) to allocate a NPATH buffer. The file name, extension and version are not
modified by the fl_path_ser_dir( ) function.

fl_path_cwd( ) builds a normalized path for the current working directory. If the NPATH
argument is NULL, fl_path_cwd( ) first calls fl_path_alloc( ) to allocate a NPATH buffer.

FactoryLink Programmer’s Access Kit / 155


• PAK LIBRARY SERVICES
• Path Manipulation


Modifying an Existing Path
void fl_path_add(NPATH *p1, NPATH *p2)
void fl_path_add_dir(NPATH *p, char *dir)
void fl_path_set_file(NPATH *p, char *file)
void fl_path_set_pattern(NPATH *p, char *pattern)
void fl_path_set_node(NPATH *p, char *node)
void fl_path_set_device(NPATH *p, char *drive)
void fl_path_set_extension(NPATH *p, char *extension)
void fl_path_set_version(NPATH *p, char *version)

fl_path_add( ) catenates two paths. Any missing component of the second path, p2, is taken
from the first path, p1, or from the current directory if the first path is null.

fl_path_add_dir( ) adds a subdirectory specification to the end of the directory portion of a


path. Only one subdirectory can be added to a path during each call to fl_path_add_dir( ). The
subdirectory name should not contain any path-separator characters.

fl_path_set_file( ) replaces the file name portion of the path.

fl_path_set_pattern( ) sets the wild card pattern for subsequent directory search.

fl_path_set_node( ) replaces the node name portion of the path.

fl_path_set_device( ) replaces the drive portion of the path.

fl_path_set_extension( ) replaces the extension of the current file name portion of the path.

Creating/Deleting Directories and Files


int fl_path_mkdir(NPATH *p)
int fl_path_rmdir(NPATH *p)
int fl_path_create(NPATH *p)
int fl_path_remove(NPATH *p)

fl_path_mkdir( ) creates the directory given by the directory portion of the path.

fl_path_rmdir( ) deletes the directory given by the directory portion of the path.

fl_path_create( ) creates an empty file using the complete path.

fl_path_remove( ) removes the file specified by the complete path.

156 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Path Manipulation

Searching for Matching Files


int fl_path_opendir(NPATH *p)
6
int fl_path_readdir(NPATH *p)

PAK Library Services


void fl_path_closedir(NPATH *p)

fl_path_opendir( ) begins a directory search operation. The current directory information in


NPATH is used as the directory to search and the current wildcard pattern is used to choose
files. fl_path_opendir( ) returns GOOD if the directory opens for search or ERROR if it does
not. fl_path_opendir( ) reads the first entry in the directory.

fl_path_readdir( ) reads the next matching file in the directory and places the name of the file
into the file name component of the path. The file type, date, time, and size are also stored in
the NPATH structure. fl_path_readdir( ) returns GOOD if a matching file is found or ERROR
if not.

fl_path_closedir( ) ends a directory search. The following code fragment in C demonstrates


how to use directory search functions to print a directory listing.
NPATH *p;
char date[80];
char time[80];
char fullpath[MAX_PATH_NAME];
p = fl_path_norm(NULL, “*.*”);
if (fl_path_opendir(p) == ERROR)
{
printf(“Directory Not found\n”);
return;
}
do
{
fl_path_date(p, date,80);
fl_path_time(p, time,80);
fl_path_sys(p, fullpath,MAX_PATH_NAME);
printf(“%s %s %s\n”, date, time, fullpath);
} while ( fl_path_readdir(p) != ERROR );
fl_path_closedir(p);
fl_path_free(p);

FactoryLink Programmer’s Access Kit / 157


• PAK LIBRARY SERVICES
• Path Manipulation


Getting File Information
int fl_path_info(NPATH *p)
long fl_path_date(NPATH *p, char *buf,size_t length)
long fl_path_time(NPATH *p, char *buf,size_t length)
int fl_path_access(NPATH *p)
char *fl_path_get_device(NPATH *p)
char *fl_path_get_node(NPATH *p)
char *fl_path_get_dir(NPATH *p)
char *fl_path_get_file(NPATH *p)
long fl_path_get_dt(NPATH *p)
long fl_path_get_size(NPATH *p)
int fl_path_get_type(NPATH *p)

fl_path_info( ) initializes the date, time, size, and type for the path. If the file does not exist,
fl_path_date( ) formats the date of a file into the caller's buffer and returns the date and time
(concatenated) as a long integer.

fl_path_time( ) formats the time of the file into the caller's buffer. This function is operating
system-dependent.

Under Windows NT and Windows 95, the format is controlled by the country code returned by
the MS-DOS function 38h.

158 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Message Translation Services

M ESSAGE TRANSLATION S ERVICES


6
The message translation functions provide services so run-time tasks can translate keywords

PAK Library Services


into localized messages stored in external disk files (message files).

The message translation services consist of the following functions.

Functions Descriptions
fl_xlate Translates keyword to its associated message.
fl_xlate_init Loads the first message file. The message
translation data structure is a tree.
fl_xlate_load Loads the specified file into the current translation
tree, replacing any duplicate keywords. The
function returns the number of entries loaded from
this file or returns ERROR.
fl_xlate_get_tree Returns the address of the current translation tree or
NULL if no translation files have been loaded.
fl_xlate_set_tree Sets the current translation tree to the tree at the
specified address.

Message Translation Functions Overview


Keyword/translation pairs are kept in a tree data structure. The translation for a keyword is
retrieved using the fl_xlate( ) function. This tree is automatically loaded with a set of default
translations for tasks. The translations may be overridden or supplemented by loading another
translation file into the current tree. Each task may maintain several translation trees.

Use the fl_xlate( ) functions for output from all messages to create a language-independent
task. If file names or other data need to be imbedded in a message, use fl_xlate( ) to retrieve the
format string and then sprintf ( ) using that format, as in the following example:

Example 1

The file test.txt contains:


BADFILE“Could not open the file: %s”

The file test.c contains:


char buff[MAX_MSG_SIZE] ;
sprintf(buff, fl_xlate(BADFILE), filename);

FactoryLink Programmer’s Access Kit / 159


• PAK LIBRARY SERVICES
• Message Translation Services


Loading Translation Files
int fl_xlate_init(char FAR *file, char FAR *buff, uint len)
int fl_xlate_load(char FAR *file)

When loading translation files, the file fllang.lst in \flink\install is examined to determine the
current language. It is appended to the {FLINK}/MSG path used to load the master file as well
as user-defined files.

If the user-specified file contains path information, it is folded into the {FLINK}/MSG/<lang>
path when loading the file.

The function fl_xlate_init( ) starts a fresh translation tree and loads the default translation file
master.txt. The user-specified translation file is then loaded on top of the existing definitions.
Duplicate definitions are superseded by the last file loaded. The function returns the total
number of translations loaded from both the master.txt file as well as the user-specified file or
returns ERROR.

The function does not use the buff and len parameters of fl_xlate_init( ) but are retained to stay
compatible with existing code.

The function fl_xlate_load( ) loads the specified file into the current translation tree, replacing
any duplicate keys. The function returns the number of entries loaded from this file or returns
ERROR.

Example 2

If the current language variable is defined to be DE for German, the following call:
fl_xlate_init(“iml”, NULL, 0)

loads {FLINK}/MSG/DE/master.txt into the tree and then loads {flink}/msg/de/iml.txt into the
tree. The return value is the total number of translations loaded from both files (duplicates are
counted only once).

The call
fl_xlate_load(“iml”)

loads {FLINK}/MSG/DE/iml.txt into the tree and returns the number of translations.

The call
fl_xlate_load(/temp/test)

still loads /temp/test.txt into the tree and returns the number of translations.

160 / FactoryLink Programmer’s Access Kit


PAK LIBRARY SERVICES
Message Translation Services

Translating
char FAR *fl_xlate(char FAR *key)
6

PAK Library Services


The function fl_xlate( ) returns a pointer to the translation text for the requested key if the key
is found in the tree. The pointer to the original key is returned if no translation is found.

Managing Multiple Translation Trees


void FAR *fl_xlate_get_tree( void )
void FAR *fl_xlate_set_tree( void *p )

The function fl_xlate_get_tree( ) returns the address of the current translation tree or NULL if
no translation files are loaded.

The function fl_xlate_set_tree( ) sets the current translation tree to the specified address.
Future file loads and translations are facilitated using this tree.

Example 3
void *tree1, *tree2 ; /* pointers to 2 trees */
fl_xlate_load(“file1") ;
tree1 = fl_xlate_get_tree() ;
fl_xlate_load(“file2") ;
tree2 = fl_xlate_get_tree() ;
fl_xlate_set_tree(tree1) ;
printf(“%s\n”, fl_xlate(“token”)) ;
fl_xlate_set_tree(tree2) ;
printf(“%s\n”, fl_xlate(“token”)) ;

fl_xlate_set_tree( ) may also be used to start a fresh tree, as in the following example:

Example 4
fl_xlate_set_tree(NULL) ; /* start new tree */

Extended Characters
Because FactoryLink is translated into several languages, it is important to know that extended
characters present in foreign languages are interpreted by the various programs you use to edit
files.

All translated text returns with the characters in the Windows codepage 1252. It is important
that the translated files in the FactoryLink ECS baseline, like multilanguage TXT files (*.mlt),

FactoryLink Programmer’s Access Kit / 161


• PAK LIBRARY SERVICES
• Message Translation Services


remain in this representation so you can convert from 1252 to other codepages for other
platforms. For this reason, any edits to these files must be performed on a Windows or VMS
platform.

When it is necessary to edit a file that contains text in a foreign language, make sure to
preserve the 1252 representation. Most Windows-based products should be able to handle the
1252 codepage correctly, for example, Microsoft Word, Microsoft Write, Notepad, and
Codewright. You may want to choose one of these editors as your best choice for editing text
files with foreign language data. If you cannot see all the characters clearly, it may be
necessary to select another font.

162 / FactoryLink Programmer’s Access Kit


Chapter 7





PAK API Reference Library
7

PAK API Reference


The FactoryLink Library offers a set of services that supports the creation of FactoryLink

Library
tasks, such as functions to read and write data contained in the real-time database. Where
possible, the API is consistent across operating systems and platforms. This permits programs
written in ANSI C to be compiled without source modification on any of the FactoryLink
platforms. You can upgrade the hardware platform by physically porting the application over
to a different platform and recompiling it.

This chapter provides the following information about each API function:
• Syntax: Valid format for this function
• Arguments: List containing the following information about each argument:
• Type
• Name
• Direction (input = in; output = out; or both = in/out)
• Description
• Returns: Description of the returned data from the function, usually a symbolic
representation representing the integer value returned by the function, such as ERROR or
GOOD.
• Remarks: Additional information about the function, such as code fragments in the C
language.
• See also: Lists related function(s).

FactoryLink Programmer’s Access Kit / 163


• PAK API REFERENCE LIBRARY



CT _ CLOSE
Close a CT archive.
Syntax #include <flib.h>
int ct_close(CT* ctp);

Arguments CT* ctp in CT file buffer.

Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_CANNOT_CLOSE_FILE
See also “ct_open”

CT _ CLOSE _ OBJ
Object CT API.
Syntax #include <objct.h>
int ct_close_obj(CT* objct);

Arguments CT* ctp in Object CT handle.

Returns CT_NULL_PTR
CT_FILE_NOT_OPEN
CT_CANNOT_CLOSE_FILE
Remarks Function ct_close_obj( ) closes the object CT. The CT handle should not be
referenced after being closed.
See also “ct_open_obj”

164 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

CT _ FIND _ INDEX
7
Find an index.
Syntax #include <flib.h>

PAK API Reference


int ct_find_index(CT* ctp, char* ndx);

Library
Arguments CT* ctp in CT file buffer.

char* ndx in Name field.

Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_SEEK_ERROR
CT_READ_ERROR
CT_BAD_DATA
CT_BAD_INDEX
Remarks Find an index by matching the name field.

CT _ FIND _ OBJ
Object CT API.
Syntax #include <objct.h>
int ct_find_obj(CT* objct, char* objname, FLOBJREC* rec;

Arguments CT* objct in Object CT handle.

char* objname in Name of object to find.

FLOBJREC* rec out Buffer for object definition.

FactoryLink Programmer’s Access Kit / 165


• PAK API REFERENCE LIBRARY



Returns GOOD
ERROR
Remarks Function ct_find_obj( ) searches the given object CT for the given objname and
returns its definition.
Function ct_find_obj( ) employs a binary search.
See also “ct_open_obj”

CT _ GET _ HDRLEN
Get the length of the current CT table header.
Syntax include <flib.h>
int ct_get_hdrlen(CT* ctp);

Arguments CT* ctp in Ct file buffer.

Returns Length of the header. The return value is undefined if the CT archive is not opened.
Remarks Determine the length of the table header of the currently selected CT table.
See also “ct_read_hdr”

CT _ GET _ NAME
Get the name of the current CT table.
Syntax #include <flib.h>
char *ct_get_name(CT* ctp);

Arguments CT* ctp in CT file buffer.

Returns Table name. The return value is undefined if the CT archive is not opened.
Remarks Returns a pointer to the name field of the currently selected CT table. Do not modify
the memory pointed to by the return value.

166 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

CT _ GET _ NCTS
7
Determine the number of CT tables in the archive.
Syntax #include <flib.h>

PAK API Reference


int ct_get_ncts(CT* ctp);

Library
Arguments CT* ctp in CT file buffer.

Returns Number of CT tables. The return value is undefined if the CT archive is not opened.

CT _ GET _ NRECS
Determine the number of records in the last selected CT table.
Syntax #include <flib.h>
int ct_get_nrecs(CT* ctp);

Arguments CT* ctp in CT file buffer.

Returns Number of records. The return value is undefined if the CT archive is not opened.

CT _ GET _ RECLEN
Determine the record length of records in current CT table.
Syntax #include <flib.h>
int ct_get_reclen(CT* ctp);

Arguments CT* ctp in CT file buffer.

Returns Length of individual records. The return value is undefined if the CT archive is not
opened.
Remarks All tables have fixed-length records.

FactoryLink Programmer’s Access Kit / 167


• PAK API REFERENCE LIBRARY



CT _ GET _ TYPE
Get the type field from the current CT table.
Syntax #include <flib.h>
int ct_get_type(CT* ctp);

Arguments CT* ctp in CT file buffer.

Returns Table type number. The return value is undefined if the CT archive is not opened.

CT _ NRECS _ OBJ
Object CT API.
Syntax #include <objct.h>
int ct_nrecs_obj(CT* objct, u32* nrecs);

Arguments CT* objct in Object CT handle.


u32* nrecs out Number of objects in given CT.

Returns GOOD
ERROR
Remarks Function ct_nrecs_obj( ) returns the total number of objects contained within the
given object CT.
See also “ct_open_obj”
“ct_read_objs”

CT _ OPEN
Open a CT archive file.
Syntax #include <flib.h>
int ct_open (CT* ctp, char* dirp, char* namep);

Arguments CT* ctp in/out CT file buffer.


char* dirp in Base path name.
char* namep in CT file name.

168 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

Returns GOOD
CT_NULL_POINTER 7
CT_CANNOT_OPEN_FILE

PAK API Reference


CT_READ_ERROR
CT_BAD_MAGIC

Library
Remarks ct_open( ) places information about the CT archive into the buffer ctp points to. The
archive is positioned at the first table in the archive.

CT _ OPEN _ OBJ
Object CT API.
Syntax #include <objct.h>
int ct_open_obj(CT* objct, char* flapp);

Arguments CT* objct in/out Object CT handle.


char* flapp in Application directory.

Returns GOOD
CT_NULL_PTR
CT_CANNOT_OPEN_FILE
CT_READ_ERROR
CT_BAD_MAGIC
Description Function ct_open_obj( ) opens the object CT. This CT handle is passed to all
subsequent object CT API calls.
See also “ct_close_obj”

CT _ READ _ HDR
Read the header for ctp into buffer.
Syntax #include <flib.h>
int ct_read_hdr(CT* ctp, void* hdrp);

Arguments CT* ctp in CT file buffer.


void* hdrp in CT header buffer.

FactoryLink Programmer’s Access Kit / 169


• PAK API REFERENCE LIBRARY



Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_BAD_INDEX
CT_SEEK_ERROR
CT_READ_ERROR
Remarks Call ct_read_index( ) before calling ct_read_hdr( ).

CT _ READ _ INDEX
Read and index from a CT archive.
Syntax #include <flib.h>
int ct_read_index (CT* ctp, uint ndx);

Arguments CT* ctp in CT file buffer.

uint ndx in Index to read.

Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_BAD_INDEX
CT_SEEK_ERROR
CT_READ_ERROR
Remarks Each table in the archive has an associated index containing information about the
table. The index is read into the CT file buffer ctp points to. Reading an index selects
a specific CT for reading.

170 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

CT _ READ _ OBJS
7
Object CT API.
Syntax #include <objct.h>

PAK API Reference


int ct_read_objs(CT *objct, FLOBJREC* recs, u32 srec, u32 nrecs);

Library
Arguments CT* objct in Object CT handle.

FLOBJREC* recs out Buffer for object definitions.

u32 srecs in Starting record number.

u32* nrecs out Number of records to read.

Returns GOOD
ERROR
Remarks Function ct_read_obsj( ) reads the given number of definitions (nrecs) into target
buffer recs, beginning at record srec.
See also “ct_open_obj”
“ct_nrecs_obj”

CT _ READ _ REC
Read a record from the current CT into memory.
Syntax #include <flib.h>
int ct_read_rec(CT* ctp, void recp, uint rec);

Arguments CT* ctp in CT file buffer.

void recp out Record buffer.

uint rec in Record number.

Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_BAD_INDEX
CT_BAD_RECORD

FactoryLink Programmer’s Access Kit / 171


• PAK API REFERENCE LIBRARY



CT_SEEK_ERROR
CT_READ_ERROR
Remarks Read the indicated record from the currently selected CT into the memory pointed to
by the buffer.

CT _ READ _ RECS
Read records from the current CT into memory.
Syntax #include <flib.h>
int ct_read_recs(CT* ctp, void* recp, uint rec, uint recs);

Arguments CT* ctp in CT file buffer.

void* recp out Record buffer.

uint rec in Starting record number.

uint recs in Number of record to read.

Returns GOOD
CT_NULL_POINTER
CT_FILE_NOT_OPEN
CT_BAD_INDEX
CT_BAD_RECORD
CT_SEEK_ERROR
CT_READ_ERROR
Remarks Read the indicated records from the currently selected CT into the memory pointed to
by the buffer. Reading begins at record number rec.

FL _ CHANGE _ READ
Read the first tag that has changed since it was last read.
Syntax #include <flib.h>
int fl_change_read(id_t id, TAG* tp, uint n, uint* ip, void* vp);

Arguments id_t id in Caller’s FactoryLink ID.

172 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

TAG* tp in Pointer to tag array specifying which


tags to examine. 7
uint n in Number of tags involved.

PAK API Reference


uint* ip out Pointer to index into tag array to be
used and updated, if necessary, by the

Library
kernel.

void* vp out Pointer to area to receive value of the


first changed tag, if r==GOOD.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_ARGUMENT
FLE_NO_CHANGE
FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Test for a change in value of one or more tags in the real-time database. The calling
process is immediately informed (it is never blocked) as to whether any of the
specified tags changed since last read. ip specifies the first tag to examine; however,
in contrast to fl_change_wait( ), ip does not wrap around the tag array.
In the case of a message tag, be sure the m_ptr and m_mbx members of value area vp
are initialized.
In the case of a mailbox tag, the value passed back is the MBXMSG for the head
message without the associated message data.

FactoryLink Programmer’s Access Kit / 173


• PAK API REFERENCE LIBRARY



FL _ CHANGE _ WAIT
Read the first tag that has changed since it was last read; if no change, go to sleep
until a change occurs.
Syntax #include <flib.h>
int fl_change_wait (id_t id, TAG* tp, uint n, uint* ip, void* vp);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array specifying which tags to examine.

uint n in Number of tags involved.

uint* ip out Pointer to index into tag array to be used and updated,
if necessary, by the kernel.

void vp out Pointer to area to receive the value of the first changed
tag, if r==GOOD.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_ARGUMENT
FLE_NO_CHANGE
Remarks Wait on a change in value of one or more tags in the real-time database. If any of these
tags has changed, control is returned immediately to the caller as in
fl_change_read( ). Otherwise, the calling process is put to sleep (blocked) until one
or more of the specified tags changes. At this point, it is awakened. While sleeping,
the calling task is also awakened if another process wakes it up. This can be done
either directly via fl_send_sig( ) or indirectly via fl_set_term_flag( ). Although all n
tags are waited upon, only one value is read and returned in vp. This is the one
detected as the first one to change. In deciding which tag is first, ip is used in
wraparound fashion within the tag array.
In the case of a message tag, be sure the m_ptr and m_mbx members of value area vp
are initialized.
In the case of a mailbox tag, the value passed back is the MBXMSG for the head
message without the associated message data.

174 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ CLEAR _ CHNG
7
Clear the calling task change-status flags for specified tags.
Syntax #include <flib.h>

PAK API Reference


int fl_clear_chng(id_t id, TAG* tp, uint n);

Library
Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array.

uint n in Number of tags involved.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Clear (to 0) the change state of the specified tags for the calling process only. This
function undoes action of fl_set_chng( ). It is also useful for establishing initial
conditions for a programming loop.

FL _ CLEAR _ WAIT
Clear the calling task wait flags for specified tags.
Syntax #include <flib.h>
int fl_clear_wait(id_t id, TAG* tp, uint n);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array.

uint n in Number of tags involved.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller’s FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER

FactoryLink Programmer’s Access Kit / 175


• PAK API REFERENCE LIBRARY



FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Clear (to 0) the wait flag of the specified tags for the calling process only. Also, use
this function to establish initial conditions.

FL _ COUNT _ MBX
Determine the number of messages in a mailbox, validate a mailbox, or monitor a
mailbox.
Syntax #include <flib.h>
int fl_count_mbx(id_t id, TAG mbx, uint* np);

Arguments id_t id in Caller’s FactoryLink ID.

TAG mbx in Mailbox to be accessed.

uint np out Message count to be filled in by the kernel.

Returns GOOD: if good, also returns np.


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID, and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks Use fl_count_mbx( ) to determine how many messages are present in a mailbox.
Generally, call fl_count_mbx( ) prior to allocating space for an array of MBXMSGs
and calling fl_query_mbx( ). Also, use this function to validate a mailbox TAG and to
monitor a mailbox.

176 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ DBFMTT
7
Prepare a formatted string from a set of tag values.
Syntax #include <flib.h>

PAK API Reference


int fl_dbfmtt(id_t id, int maxlen, char bp0, char fp, TAG* args);

Library
Arguments id_t id in Task ID used to access real-time database.

int maxlen in Maximum number of characters that can be stored


in the output buffer.

char bp0 out Pointer to memory buffer that stores formatted


output.

char fp in Format string.

TAG* args in Tag array to be read from real-time database.

Returns Length of string


Remarks This function is similar to the C-language function sprintf( ). The format string can
contain a format specifier of the following form:
%m.nc
where
m Represents the width of the output (optional). If m is preceded by a hyphen, the output
is left justified. By default, the output is right justified.
n Represents the precision of the output (optional)
c Is one of the following:
Char Output
B String representing a DIGITAL value as ON or OFF
b Number representing a DIGITAL value as 0 or 1
d Integer value in base 10
u Unsigned integer value in base 10
x Integer value in base 16 (hexadecimal)
o Integer value in base 8 (octal)
c Single character
s Character string

FactoryLink Programmer’s Access Kit / 177


• PAK API REFERENCE LIBRARY



f Floating-point number
g Floating-point number
% A percent sign
The next tag in the args array for each format specifier is used to read a value from the
real-time database. The tag value is converted to the appropriate type for the format
specifier and then formatted into the output buffer.

FL _ ERRNO
Return the last FactoryLink error number generated by the calling process.
Syntax #include <flib.h>
int fl_errno(id_t id);

Arguments id_t id in Caller’s FactoryLink ID.

Returns GOOD
Last Error Number
Remarks Returns the last FactoryLink error number generated by the calling process during the
last call to the kernel that resulted in an error.

FL _ FIND _ GLOBAL _ TAG


Retrieve tag number for one or more global tag IDs for any accessible domain.
Syntax int fl_find_global_tag(TAG* tagp, uint n, uint* ids,
char* app, char* domain);

Arguments TAG* tagp out Array where tag numbers are returned.

uint n in Number of tags to find.

uint* ids in Array of identification numbers.

char* app in Application directory ({FLAPP}).

char* domain in Current domain name.

Returns Number of tags read from global CT file

178 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

Remarks Function fl_find_global_tag( ) performs searches for global tags based on the
application domain hierarchy. 7
If fl_global_tag is called from the SHARED domain, it looks in the GLOBAL.CT
configuration table for tags matching tags defined in the SHARED domain.

PAK API Reference


If it is called from the USER domain, it searches first for global tags defined in the
USER domain, then in the SHARED domain.

Library
GLOBAL.CT contains global tags available to all tasks. The GLOBAL.CT is
searched for a matching value for each member of the ids array. The associated tag is
then copied into the corresponding member of the tagp array.
The id values are defined in FLIB.H.
The following code illustrates an example of the use of this function:
#include <flib.h>

uint ids[3] = {GT_SECONDS, GT_MINUTES, GT_HOURS};
TAG gtags[3];
ANA vals[3];

/* Find the tag numbers for the tags where the


timer task is updating the seconds, minutes, and hours */
fl_find_global_tag(&gtags[0], 3, &ids[0],getenv(“FLAPP”), setenv(“FLDOMAIN));;
/* Read the time tags */
fl_read(taskid, &gtags[0], 3, &vals[0]);
seconds = vals[0];
minutes = vals[1];
hours = vals[2];

FL _ FORCED _ WRITE
Force-write a specified tag into the real-time database.
Syntax #include <flib.h>
int fl_forced_write(id_t id, TAG* tp, uint n, void* vp);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array specifying which tags to


force-write.

uint n in Number of tags to be force-written.

FactoryLink Programmer’s Access Kit / 179


• PAK API REFERENCE LIBRARY



void* vp in Pointer to area holding values.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
FLE_OUT_OF_MEMORY
FLE_FLOAT_NAN
FLE_FLOAT_POS_INF
FLE_FLOAT_NEG_INF
Remarks This function operates similarly to fl_write( ) except all change states are set on
regardless of whether the new values written into the database are the same as the
previous values stored there. Upon completion of writing, those client processes
waiting on any of the tags involved are awakened.

FL _ GET _ APP _ DIR


Return the application directory for the specified process.
Syntax #include <flib.h>
int fl_get_app_dir(id_t id, char* dir);

Arguments id_t id in Caller’s FactoryLink ID.

char* dir out Pointer to directory string to be returned.

Returns GOOD: if good, dir is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_get_app_dir( ) returns the application directory for the process specified by the
FactoryLink ID (usually, but not necessarily, the caller’s ID). It returns the application
directory as a full path name, including a drive letter, if applicable.
This directory is the root directory for all dynamic files of a particular FactoryLink
application.

180 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ GET _ CMD _ LINE


7
Return the command line for the specified process.
Syntax #include <flib.h>

PAK API Reference


int fl_get_cmd_line(id_t id, char* line);

Library
Arguments id_t id in Caller’s FactoryLink ID.

char* line out Pointer to command line to be filled in by the


kernel.

Returns GOOD: if good, dir is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_get_cmd_line( ) returns the command line for the process specified by the
FactoryLink ID (usually, but not necessarily, the caller’s ID). The command line for a
process is an ASCII string that generally contains instructions to the process to alter
its normal behavior and additional environmental information.

FL _ GET _ COPYRT
Return a pointer to a copyright message for FactoryLink.
Syntax #include <flib.h>
char* fl_get_copyrt(void);
Arguments None
Returns Pointer to copyright message.
Remarks Do not modify the pointer returned by this function.

FL _ GET _ CTRL _ TAG


Return the control tag that refers to a digital or analog tag for the specified process.
Syntax #include <flib.h>
int fl_get_ctrl_tag(id_t , TAG* tag);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tag out Pointer to control tag to be returned.

FactoryLink Programmer’s Access Kit / 181


• PAK API REFERENCE LIBRARY



Returns GOOD: if good, tag is filled in.
ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_get_ctrl_tag( ) returns the control tag, which refers to a digital or analog tag, for the
process specified by the FactoryLink ID (which is not necessarily, and usually is not,
the caller’s ID). The control tag for a process is used to control starting and stopping
of the process. Any process may write a value of 1 or any other nonzero value to the
control tag to tell the Run-Time Manager to start the process. Likewise, it may write a
value of 0 to tell the Run-Time Manager to stop the process by setting the termination
flag of the process.

FL _ GET _ ENV
Return the KENV structure of the client process.
Syntax #include <flib.h>
int fl_get_env(id_t id, KENV* uep);

Arguments id_t id in Client FactoryLink ID (0-30) used as an index into


array of KENVs kept by the kernel.

KENV* uep out Pointer to KENV structure to be returned.

Returns GOOD
ERROR
Remarks Return a KENV structure describing the environment of the given client process,
usually the calling process. The Run-Time Manager calls fl_set_env( ) to define this
structure before the client process is started. This function returns all fields of the
KENV structure.

FL _ GET _ MSG _ TAG


Return the value of the real-time database message tag for the specified process.
Syntax #include <flib.h>
int fl_get_msg_tag(id_t id, TAG* tag);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tag out Pointer to message tag to be returned.

182 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

Returns GOOD: if good, tag is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed. 7
Remarks fl_get_msg_tag( ) returns the value of a real-time database message tag for the

PAK API Reference


process specified by the FactoryLink ID (usually, but not necessarily, the caller’s ID).
The MSG database tag is written by the process and read by the Run-Time Manager.
Its ASCII value continually describes what the process is doing, what problems it is

Library
encountering, and other similar information (another self-reporting mechanism). It is
passed directly from the Run-Time Manager to the Real-Time Graphics process for
display on the Run-Time Manager screen.

FL _ GET _ PGM _ DIR


Return the program directory for the specified process.
Syntax #include <flib.h>
int fl_get_pgm_dir(id_t id, char* dir);

Arguments id_t id in Caller’s FactoryLink ID.


char* dir out Pointer to directory string to be returned.

Returns GOOD: if good, dir is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_get_pgm_dir( ) returns the program directory for the process specified by the
FactoryLink ID (usually, but not necessarily, the ID of the caller). The program
directory is returned as a full path name, including a drive letter, if applicable.
This directory is the root directory for all static files, that is, for all files of an installed
FactoryLink system but not part of any FactoryLink application.

FL _ GET _ SERIAL
Return a pointer to the serial number assigned to the FactoryLink system.
Syntax char* fl_get_serial(void);
Arguments None
Returns If successful, the function returns a pointer to serial number of the FactoryLink
system.
If unable to access the kernel (task not initialized with the kernel), the function returns
NULL.
Remarks Do not modify the pointer returned by this function.

FactoryLink Programmer’s Access Kit / 183


• PAK API REFERENCE LIBRARY



FL _ GET _ STAT _ TAG
Return the value of the real-time database analog status tag for the specified process.
Syntax #include <flib.h>
int fl_get_stat_tag(id_t id, TAG* tag);

Arguments id_t id in Caller’s FactoryLink ID.


TAG* tag out Pointer to status tag to be returned.

Returns GOOD: if good, tag is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_get_stat_tag( ) returns the value of the status tag for the process specified by the
FactoryLink ID (not necessarily the caller’s ID). The ANA status tag is written by the
process and read by the Run-Time Manager. Its numeric value continuously reflects
the self-reported status of the process, as follows.

Status Symbolic Name Meaning


0 FLS_INACTIVE Process is inactive (not running).
1 FLS_ACTIVE Process is active (running).
2 FLS_ERROR Error (non-fatal error occurred).
3 FLS_STARTING Starting (initialization in progress).
4 FLS_STOPPING Stopping (shutdown in progress).
Other Error (non-fatal error occurred).

The Run-Time Manager converts the status value to an ASCII string and passes it to
the Real-Time Graphics process for display on the Run-Time Manager screen.

Symbolic Name Status Meaning


FLS_INACTIVE 0 Inactive (not running).
FLS_ACTIVE 1 Active (running).
FLS_ERROR 2 Non-fatal error encountered.
FLS_STARTING 3 Starting/initialization.
FLS_STOPPING 4 Stopping/exiting.

184 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ GET _ TAG _ INFO


7
Get the information associated with a specified list of tags.
Syntax #include <flib.h>

PAK API Reference


int fl_get_tag_info (TAG* tp, uint n, i16* dp, u16* op);

Arguments TAG* tp in Pointer to tag array specifying which tags are

Library
involved.
uint n in Number of tags involved.
i16* dp out Pointer to description array to be returned.
u16* op out Pointer to offset array to be returned.

Returns GOOD
ERROR
Remarks The dp array is filled in with one of the following values that correspond to the tags
passed to it

Value Description
FL_BAD_DATA Tag is out-of-range (bad t_data field).
FL_BAD_TYPE Tag is a bad t_type field.
FL_UNDEFINED Tag is undefined.
FL_DIGITAL Tag is a digital (DIG).
FL_ANALOG Tag is an analog (ANA).
FL_MESSAGE Tag is a message (MSG).
FL_LANALOG Tag is a long analog (longana).
FL_FLOAT Tag is floating point (FLP).
FL_MAILBOX Tag is mailbox (holds MBXMSGs).

The kernel fills in the op array with the offset into the vp buffer where the value is
stored if fl_read( ), fl_write( ) or fl_forced_write( ) are called with the argument list
(id, tp, n, vp). The caller may set either or both of the pointers dp or op to NULL if he
does not wish to receive corresponding information, fl_get_tag_info( ) if all n tags in
the tp array are valid, and ERROR if one or more of them is bad.

FactoryLink Programmer’s Access Kit / 185


• PAK API REFERENCE LIBRARY



FL _ GET _ TICK
Get the current clock tick and/or current date and time maintained and reported by the
operating system.
Syntax #include <flib.h>
int fl_get_tick(u32* tickp, KDT* datetimep);

Arguments u32 tickp out Pointer to location for storing clock tick.

KDT* datetimep out Pointer to location for storing data and time.

Returns Always GOOD


Remarks The clock tick is graduated in millisecond units and is non-decreasing until
wraparound time (about once a month). The chief use is in measuring elapsed time.
The date and time are stored in a DATETIME structure familiar to the operating
system. Either tickp or datetimep may be NULL, which the kernel interprets as a lack
of interest in the corresponding value; therefore, the kernel does not store the value.

FL _ GET _ TITLE
Return a pointer to the name of the product.
Syntax #include <flib.h>
char* fl_get_title(void);
Arguments None
Returns Pointer to name of product.
Remarks Do not modify the pointer returned by this function.

FL _ GET _ VERSION
Get the kernel version number.
Syntax #include <flib.h>
uint fl_get_version();
Arguments None
Returns FactoryLink kernel version number. Numerically returns version x.y as
(x * 256) + y.

186 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ GLOBAL _ TAG
7
Retrieve the tag number for one or more global tags.
Syntax #include <flib.h>

PAK API Reference


Arguments TAG* tagp out Array where tag numbers are returned.

Library
uint n in Number of tags to read.

uint* ids in Array of identification numbers.

Returns Number of tags read from the global CT file.


Remarks GLOBAL.CT contains global tags available to all tasks. GLOBAL.CT is searched for
a matching value for each member of the ids array. The associated tag is then copied
into the corresponding member of the tagp array.
The id values are defined in FLIB.H.
The following code illustrates an example of the use of this function:
#include <flib.h>

uint ids[3] = {GT_SECONDS, GT_MINUTES, GT_HOURS};
TAG gtags[3];
ANA vals[3];
/* Find the tag numbers for the tags where the
timer task is updating the seconds, minutes, and hours */
fl_global_tag(&gtags[0], 3, &ids[0]);
/* Read the time tags */
fl_read(taskid, &gtags[0], 3, &vals[0]);
seconds = vals[0];
minutes = vals[1];
hours = vals[2];
A smart run-time task can initiate a shutdown of the FactoryLink system. To cause the
Run-Time Manager to begin an immediate system shutdown, the task writes a value
of 1 (ON) to the global, predefined analog tag, RTMCMD.

FactoryLink Programmer’s Access Kit / 187


• PAK API REFERENCE LIBRARY



FL _ HOLD _ SIG
Prevent or allow signal delivery for the calling process.
Syntax #include <flib.h>
int fl_hold_sig(id_t id, int sig, int hold);

Arguments id_t id in Caller’s FactoryLink ID.


int sig in Signal (0-31) to be affected.
int hold in Hold value:
1 = prevent signal delivery.
0 = allow signal delivery.

Returns Previous hold value (1 or 0) for the signal


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns FLE_BAD_ARGUMENT.
Remarks Initially, all signals except 0 and 1 are held; that is, by default, signals 0 and 1 are
deliverable to the calling process, but others are not. A FactoryLink process wishing
to be notified when its tag list of tags has changed must execute the following
function to allow delivery of this signal:
fl_hold_sig(id, FLC_SIG_TAG_LIST_CHANGED, 0);
It is legal to hold any signal with fl_hold_sig( ), including signals 0 and 1.

FL _ ID _ TO _ NAME
Translate a FactoryLink ID to a process name.
Syntax #include <flib.h>
int fl_id_to_name(id_t id, char* name);

Arguments id_t id in FactoryLink ID to be translated.


char* name out Pointer to process name to be returned.

Returns GOOD: if good, name is filled in.


ERROR: if error, an invalid FactoryLink ID is assumed.
Remarks fl_id_to_name( ) checks the FactoryLink ID and, if the ID is valid, returns the
associated process name.

188 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ LIMIT _ MBX
7
RTDB Access API.

PAK API Reference


Syntax #include <flib.h>
int fl_limit_mbx(id_t, u16 dir,
TAG* mbxp, u16 nmbx,

Library
u16* klimp;

Arguments id_t id in Task ID.

u16 dir in Direction of information. If dir is


FL_FUNC_SET: sets mbx limit(s)
FL_FUNC_GET: returns mbx limit(s)

TAG* mbxp in Mailbox tags to set/get limits for.

u16 nmbx in Number of mailbox tags.

u16* klimp in/out If setting values, the new limits are passed within
this array.
If getting values, the mailbox limits are returned
within this array.

Returns GOOD: operation successful.


ERROR: Operation failed.
Remarks Function fl_limit_mbx( ) sets or gets the number kf Kbytes held by the given
mailbox. If the limit is set to zero, the number if Kbytes a mailbox can reference is
determined by the application system default as set by the Run-Time Manager.
See also “fl_write_mbx”
“fl_errno”

FactoryLink Programmer’s Access Kit / 189


• PAK API REFERENCE LIBRARY



FL _ LOCK
Lock the real-time database on behalf of the calling process.
Syntax #include <flib.h>
int fl_lock(id_t id);

Arguments id_t id in Caller’s FactoryLink ID.

Returns GOOD
ERROR
Remarks Only one client process may have the real-time database locked at any given time. If
the calling process calls fl_lock( ) and the real-time database is already locked by that
same process, a counter is incremented and the lock remains in effect for the caller.
This counter allows calls to fl_lock( ) and fl_unlock( ) to be nested.
If another client process has already locked the real-time database, the caller is put to
sleep (blocked) until his lock request can be honored. Upon return from fl_lock( ),
only the calling process is granted access to the real-time database until it makes a
corresponding call to fl_unlock( ), provided it does not execute fl_wait( ), either
directly or indirectly. fl_wait( ) releases its lock and puts it to sleep. When it awakes,
the lock is reinstated.
If the caller wants to keep the real-time database locked and thereby retain exclusive
access to it, it must not call fl_change_wait( ) or write any synchronous tags via
fl_write( ) or fl_forced_write( ).

FL _ NAME _ TO _ ID
Translate a process name to a FactoryLink ID.
Syntax #include <flib.h>
id_t fl_name_to_id(id_t id, char* name);

Arguments id_t id in Pointer to process name to be translated.


char* name in Task ID of calling task.

Returns FactoryLink ID
ERROR: if error, an invalid process name is assumed
Remarks fl_name_to_id( ) searches the domain of the given task id for the specified process
name; and, if the process name is found, returns the associated FactoryLink ID.

190 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ ACCESS
7
Check file access mode for a given file.
Syntax #include <flpath.h>

PAK API Reference


int fl_path_access(NPATH path);

Library
Arguments NPATH* path in Pointer to a previously allocated NPATH
structure containing a normalized path name
buffer.

Returns The file access mode of the file as one of the following character strings:
NPATH_READ
NPATH_WRITE
NPATH_READ | NPATH_WRITE
If specified file does not exist, returns ERROR.
Remarks The function fl_path_access( ) returns a string informing the calling program of the
mode(s) (read-only, write-enable, or read/write) the calling program is authorized to
access the specified file in, if available.
See also fl_path and related calls

FL _ PATH _ ADD
Catenates two normalized paths.
Syntax #include <flpath.h>
void fl_path_add(NPATH* path1, NPATH* path2);

Arguments NPATH* path1 in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

NPATH* path2 in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns N/A
Remarks fl_path_add( ) catenates two paths. Any missing component of the second path p2 is
taken from the first path p1 or from the current directory if the first path is null.
See also fl_path and related calls

FactoryLink Programmer’s Access Kit / 191


• PAK API REFERENCE LIBRARY



FL _ PATH _ ADD _ DIR
Adds one subdirectory specification per call to the end of the directory portion of a
path.
Syntax #include <flpath.h>
void fl_path_add_dir(NPATH* path, char* dir);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

char* dir in Directory name in system-specific format.

Returns N/A
Remarks fl_path_add_dir( ) adds a subdirectory specification to the end of the directory
portion of a path. Only one subdirectory can be added to a path during each call to
fl_path_add_dir( ). The subdirectory name should not contain any path-separator
characters.
See also fl_path and related calls

FL _ PATH _ ALLOC
Allocate a normalized path name buffer.
Syntax #include <flpath.h>
NPATH* fl_path_alloc(void);
Arguments None
Returns If successful, returns a pointer to an allocated normalized path buffer.
If unsuccessful, returns NULL; an invalid process name is assumed.
Remarks The function fl_path_alloc( ) allocates and returns a pointer to a normalized path
buffer. Programmers should call this function, rather than allocate the NPATH
structure directly so a buffer for system-dependent information can be added to the
path buffer.
See also fl_path and related calls

192 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ CLOSEDIR
7
Ends a directory search for a file.
Syntax #include <flpath.h>

PAK API Reference


void fl_path_closedir(NPATH* path);

Library
Arguments NPATH* path in Pointer to a previously allocated NPATH structure
containing a normalized path name buffer.

Returns N/A
Remarks fl_path_closedir( ) ends a directory search.
See also “fl_path_opendir” and related calls

FL _ PATH _ CREATE
Create an empty file using the complete path specified.
Syntax #include <flpath.h>
int fl_path_create(NPATH* path);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR
Remarks fl_path_create( ) creates an empty file using the complete path specified by the given
NPATH. The file may then be opened, copied, referenced, or closed by any task with
the proper file access privileges.

FL _ PATH _ CWD
Build a normalized path for the current working directory.
Syntax #include <flpath.h>
NPATH *fl_path_cwd(NPATH* path);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

FactoryLink Programmer’s Access Kit / 193


• PAK API REFERENCE LIBRARY



Returns Pointer to a normalized path buffer. The pointer is returned in the variable named in
the call: PATH = fl_path_cwd( ).
NULL
Remarks fl_path_cwd( ) builds a normalized path for the current working directory. If the
NPATH argument is NULL, fl_path_cwd( ) first calls fl_path_alloc( ) to allocate a
NPATH buffer. Either way, the working directory may now be accessed using the path
name built.

FL _ PATH _ DATE
Places formatted system date and time stamp from a specified file's header into
specified buffer.
Syntax #include <flpath.h>
long fl_path_date(NPATH* path, char* buf, size_t length);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.
char* buf out Pointer to buffer for receiving data.
size_t length in Length of output buffer.

Returns File date-and-time stamp.


ERROR
Remarks fl_path_date( ) formats the date and time stamp on a file (the date/time the file was
last updated) into the caller's buffer and returns the date and time (concatenated) as a
long integer.

FL _ PATH _ GET _ SIZE


Returns the size in bytes of the specified file.
Syntax #include <flpath.h>
long fl_path_get_size(NPATH* path);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns Size of file in bytes


ERROR
Remarks fl_path_get_size( ) returns the size of a specific file in bytes.

194 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ GET _ TYPE


7
Returns the file type of the specified file.
Syntax #include <flpath.h>

PAK API Reference


long fl_path_get_size(NPATH* path);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure

Library
containing a normalized path name buffer.

Returns File type as one of the following constants:


NPATH_REGULAR
NPATH_DIRECTORY
ERROR
Remarks fl_path_get_type( ) returns the type of the file.
fl_path_get_type( ) returns the file type of the file specified. One of the following
constants is returned:
NPATH_REGULAR
NPATH_DIRECTORY
fl_path_get_type( ) returns the file type of the file specified. One of the following
constants is returned:
NPATH_REGULAR
NPATH_DIRECTORY

FL _ PATH _ INFO
Initialize date, time, size, and type of files allowed for the specified path.
Syntax #include <flpath.h>
int fl_path_info(NPATH* path);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR
Remarks fl_path_info( ) initializes the date, time, size, and type for the path. If the path does
not exist, fl_path_info( ) returns ERROR. Otherwise, it returns GOOD.
This function is called automatically by fl_path_opendir( ) and fl_path_readdir( ).

FactoryLink Programmer’s Access Kit / 195


• PAK API REFERENCE LIBRARY



FL _ PATH _ MKDIR
Creates the directory specified by the directory portion of the indicated path.
Syntax #include <flpath.h>
int fl_path_mkdir(NPATH* path);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR
Remarks fl_path_mkdir( ) creates the directory given by the directory portion of the path, if the
directory does not already exist. It creates all directories and subdirectories necessary
for the path, up to and including the last subdirectory specified in the NPATH
structure.
For example, if none of the following directories exist:
/test
/test/mystuff
/test/mystuff/log
the following code fragment in C creates them all, in hierarchical order:
NPATH* np;
np = fl_path_set_dir(NULL, /test/mystuff/log);
fl_path_mkdir(np);
This function returns GOOD if the directories already exist. It returns ERROR only if
at least one of the directories cannot be created because of a system error or
insufficient privilege levels on the part of the caller.
See also “fl_path_rmdir” and related calls

196 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ NORM
7
Convert part or all of a system-specific path string into a normalized path.
Syntax #include <flpath.h>

PAK API Reference


NPATH* fl_path_norm(NPATH* path, char* path_buf);

Library
Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure
containing a normalized path name buffer.

char* path_buf in Source string.

Returns Pointer to the NPATH structure; also, if the pointer argument p passed in was NULL,
an NPATH buffer has been allocated and the pointer value is now set.
NULL
Remarks fl_path_norm( ) converts a system-specific path string into a normalized path. Any or
all components of the path may be left out. If the NPATH argument is NULL,
fl_path_norm( ) first calls fl_path_alloc( ) to allocate a NPATH buffer.

FL _ PATH _ OPENDIR
Begins a directory search for a file.
Syntax #include <flpath.h>
int fl_path_opendir(NPATH* path);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR

Remarks fl_path_opendir( ) begins a directory search operation. The current directory


information contained in NPATH is used as the directory to search and the current
wild card pattern is used to select files. fl_path_opendir( ) returns GOOD if the
directory could be opened for search or ERROR if it could not.
fl_path-opendir( ) reads the first entry in the directory.
See also “fl_path_closedir” and related calls

FactoryLink Programmer’s Access Kit / 197


• PAK API REFERENCE LIBRARY



FL _ PATH _ READDIR
Reads next matching file from directory during a directory search for a file.
Syntax #include <flpath.h>
int fl_path_readdir(NPATH* path);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR
Remarks fl_path_readdir( ) reads the next matching file in the directory and places the name of
the file into the file name component of the path. The file type, date, time, and size are
also stored in the NPATH structure. fl_path_readdir( ) returns GOOD if a matching
file was found or ERROR, if not found.
The following code fragment in C demonstrates how to use directory search functions
to print a directory listing:
NPATH* p;
char date[80];
char time[80];
char fullpath[MAX_PATH_NAME];
= fl_path_norm(NULL, *.*);
if ( fl_path_opendir(p) == ERROR )
{
printf(Directory Not found\n);
return;
}
do
{
fl_path_date(p, date);
fl_path_time(p, time);
fl_path_sys(p, fullpath);
printf(%s %s %s\n, date, time, fullpath);
} while ( fl_path_readdir(p) != ERROR );
fl_path_closedir(p);
fl_path_free(p);
See also “fl_path_opendir”
“fl_path_closedir” and related calls

198 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ REMOVE
7
Delete the file specified by the complete path given.
Syntax #include <flpath.h>

PAK API Reference


int fl_path_remove(NPATH* path);

Library
Arguments NPATH* path in Pointer to a previously allocated NPATH structure
containing a normalized path name buffer.

structure containing a normalized path name buffer


Returns GOOD
ERROR
Remarks fl_path_remove( ) removes the file specified by the complete path given.
See also “fl_path_create” and related calls

FL _ PATH _ RMDIR
Delete the directory specified by the directory portion of the indicated path.
Syntax #include <flpath.h>
int fl_path_rmdir(NPATH* path);

Arguments NPATH* path in Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.

Returns GOOD
ERROR
Remarks fl_path_rmdir( ) deletes the directory given by the directory portion of the path.
See also “fl_path_mkdir” and related calls

FactoryLink Programmer’s Access Kit / 199


• PAK API REFERENCE LIBRARY



FL _ PATH _ SET _ DIR
Replaces the directory portion of the specified path with the directory argument
specified converted to normalized form.
Syntax #include <flpath.h>
NPATH* fl_path_set_dir(NPATH* path, char* dir);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH structure


containing a normalized path name buffer.
char* dir in Directory name in system-specific format.

Returns Pointer to NPATH structure


NULL
Remarks fl_path_set_dir( ) replaces the directory portion of the path with the specified
directory argument after converting the argument to normalized form. If the NPATH
argument is NULL, fl_path_set_dir( ) first calls fl_path_alloc( ) to allocate a NPATH
buffer. The file name, extension, and version are not modified by the
fl_path_set_dir( ) function.
The fl_path_set_dir( ) function can be used to convert a system-specific path string
into a normalized path if the path is known to refer to a directory.
See also fl_path( ) and related calls

FL _ PATH _ SET _ DEVICE


Replaces the drive (device) name portion of the specified path with the argument
specified after converting the argument to normalized form.
Syntax #include <flpath.h>
void fl_path_set_device(NPATH* path, char* drive);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH


structure containing a normalized path name
buffer.
char* drive in Device (drive) name in system-specific format.

Returns N/A
Remarks fl_path_set_device( ) replaces the drive (device) name portion of the path with the
specified argument after converting the argument to normalized form.
See also fl_path( ) and related calls

200 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ SET _ EXTENSION


7
Replaces the file extension portion of the specified path with the argument specified
after converting the argument to normalized form.

PAK API Reference


Syntax #include <flpath.h>
void fl_path_set_extension(NPATH* path, char* extension);

Library
Arguments NPATH* path in/out Pointer to a previously allocated NPATH
structure containing a normalized path name
buffer.

char* extensio in File name extension in system-specific format.


n

Returns N/A
Remarks fl_path_set_extension( ) replaces the file extension portion of the path with the
specified argument after converting the argument to normalized form.
See also fl_path( ) and related calls

FL _ PATH _ SET _ FILE


Replaces the file name portion of the specified path with the specified argument after
converting the argument to normalized form.
Syntax #include <flpath.h>
void fl_path_set_file(NPATH* path,char* file);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH


structure containing a normalized path name
buffer.

char* file in File name in system-specific format.

Returns N/A
Remarks fl_path_set_file( ) replaces the file name portion of the path with the specified
argument after converting the argument to normalized form.
See also fl_path( ) and related calls

FactoryLink Programmer’s Access Kit / 201


• PAK API REFERENCE LIBRARY



FL _ PATH _ SET _ NODE
Replaces the node name portion of the specified path with the specified argument
after converting the argument to normalized form.
Syntax #include <flpath.h>
void fl_path_set_node(NPATH* path, char* node);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH


structure containing a normalized path name
buffer.

char* node in Node name in system-specific format.

Returns N/A
Remarks fl_path_set_node( ) replaces the node name portion of the path with the specified
argument after converting the argument to normalized form.
See also fl_path( ) and related calls

FL _ PATH _ SET _ PATTERN


Sets a wild card pattern for subsequent directory searches.
Syntax #include <flpath.h>
void fl_path_set_pattern(NPATH*path, char* pattern);

Arguments NPATH* path in/out Pointer to a previously allocated NPATH


structure containing a normalized path name
buffer.

char* pattern in Wild card pattern in system-specific


format.

Returns N/A
Remarks fl_path_set_pattern( ) sets a wild card pattern in the specified portion of the path in
normalized form for subsequent directory searches.
See also fl_path( ) and related calls

202 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PATH _ SYS
7
Convert a normalized path into a system-specific path string.
Syntax #include <flpath.h>

PAK API Reference


char *fl_path_sys(NPATH* path, char* syspath, size_t length);

Library
Arguments NPATH* path in Pointer to a previously allocated NPATH
structure containing a normalized path name
buffer.

char* syspath out Destination string.

size_t length in String length.

Returns Pointer to a system-specific converted path string.


NULL
Remarks fl_path_sys( ) converts a normalized path into a system-specific path string. If the
path argument is null, fl_path_sys( ) calls the C function malloc to allocate memory
for the resulting path. The caller should call free to release the memory when it is no
longer needed.
Example:
The following example opens a specified AC file in the {FLINK}/ac directory:
NPATH *np = (NPATH *)Null;
FILE *ac_file;
char *flink; /* Buffer containing FLINK path*/ char *filename; /* Buffer containing AC file name */

np = fl_path_alloc();
if (np == NULL)
return ERROR;
fl_path_sys(path, flink, sizeof(flink));
np = fl_path_add_dir(np, ac);
fl_path_set_file(np, filename);
fl_path_set_extension(np, ac);
fl_path_set_version(np, "");
ac_file = fl_path_fopen(np, r);
fl_path_free(np);
if (ac_file == NULL)
return ERROR;

FactoryLink Programmer’s Access Kit / 203


• PAK API REFERENCE LIBRARY



FL _ PATH _ TIME
Places formatted system time stamp from a specified file's header into specified
buffer.
Syntax #include <flpath.h>
long fl_path_time(NPATH* path, char* buf, size_t length);

Arguments NPATH* path in Pointer to a previously allocated NPATH


structure containing a normalized path name
buffer.

char* buf out Buffer to contain returned time stamp.

size-t length in Length of output buffer.

Returns Path date and time-stamping.


ERROR
Remarks fl_path_time( ) formats the time stamp on a file (the time, not including day or date,
when the file was last updated) into the caller's buffer. The format of the result from
this function is operating-system dependent.

FL _ PROC _ EXIT
Detaches the task from the kernel.
Syntax #include <flib.h>
int fl_proc_exit(id_t id);

Arguments id_t id in Caller’s FactoryLink ID.

Returns GOOD
ERROR
Remarks This function renounces all further access to the real-time database.

204 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ PROC _ INIT
7
Initialize the FactoryLink calling process.
Syntax #include <flib.h>

PAK API Reference


int fl_proc_init(char* task, char* desc);

Arguments char* task in Pointer to process name, 32 characters

Library
maximum, null-terminated.
char* desc in Pointer to process description, 80 characters
maximum, null-terminated.
Returns If successful at registering the start-up process with the kernel, function returns the
calling routine FactoryLink task ID.
If unsuccessful, function returns one of the following negative (sign bit on) error
codes:
FLE_NO_FLINK_INIT
FLE_BAD_PROC_NAME
FLE_ALREADY_ACTIVE
FLE_NULL_POINTER
FLE_NO_PROC_INIT
FLE_PROC_TABLE_FULL
Remarks This API has been retained from previous releases of FactoryLink to maintain
compatibility for users to upgrade with no changes to existing startup code. However,
new tasks should be written to use fl_proc_init_app( ) to register with the kernel. Any
task, even one written for a previous release, may now override the environment
values (use command arguments), if desired, by calling fl_proc_init_app( ). This API
now calls the new version.
The current fl_proc_init( ) is now implemented as:
int fl_proc_init(char* task, char* desc)
{
char flname[MAX_USR_NAME] ;
char fluser[MAX_USR_NAME] ;
char fldomain[MAX_USR_NAME];
fl_getvar(FLNAME, flname, sizeof(flname)) ;
fl_getvar(FLDOMAIN, fldomain, sizeof(fldomain)) ;
fl_getvar(FLUSER, fluser, sizeof(fluser)) ;
return fl_proc_init_app(task,desc,flname,fldomain,fluser);
}
See also “fl_proc_init_app”

FactoryLink Programmer’s Access Kit / 205


• PAK API REFERENCE LIBRARY



FL _ PROC _ INIT _ APP
Initialize the calling process and register it with the FactoryLink kernel for a specific
application/domain (replaces fl_proc_init).
Syntax #include <flib.h>
fl_proc_init_app(char* task, char* desc,
char* flname, char* fldomain, char* fluser);

Arguments char* task in Pointer to process name, 32 characters


maximum, null-terminated.

char* desc in Pointer to process description, 80 characters


maximum, null-terminated.

char* flname in Pointer to application invocation name


({FLNAME}).

char* fldomain in Pointer to domain name ({FLDOMAIN}).

char* fluser in Pointer to user name ({FLUSER}).

The flname argument specifies the name of the invocation the task is registering with.
Normally, the value of the environment variable FLNAME is used.
The fldomain argument specifies the domain the task is registering for and is
associated with at run time. Normally, the value of the environment variable
FLDOMAIN is used.
The fluser argument specifies which instance of the specified domain the task is
registering for. Normally, the value of the environment variable FLUSER is used.
Returns Calling routine FactoryLink task ID
If unsuccessful at registering the start-up process with the kernel, returns one of the
following negative (sign bit on) error codes:
FLE_NO_FLINK_INIT
FLE_BAD_PROC_NAME
FLE_ALREADY_ACTIVE
FLE_NULL_POINTER
FLE_NO_PROC_INIT
FLE_PROC_TABLE_FULL

206 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

Remarks A calling process must pass a process name and description to fl_proc_init_app( ).
After validating the name, the kernel returns the FactoryLink ID for use in subsequent 7
kernel calls to identify the caller.
Multiple threads of a single process can execute separate fl_proc_init_app( )s. In

PAK API Reference


these cases, the kernel regards the threads as different client processes and assigns
distinct IDs and kernel areas. Be aware the process that obtains an ID is the only
process allowed to use that ID. Unpredictable behavior can result if a process or

Library
thread uses an ID not initially assigned to it.

FL _ QUERY _ MBX
Query a mailbox for a range of queued messages.
Syntax #include <flib.h>
int fl_query_mbx(id_t id, TAG mbx, MBXMSG* mmp, uint i, uint n, uint* np);

Arguments id_t id in Caller’s FactoryLink ID.

TAG mbx in Mailbox to be accessed.

MBXMSG* mmp out Pointer to array of mailbox messages to


filled in by the kernel.

uint i in Index relative to head of queue.

uint n in Requested number of mailbox messages.

uint* np out Actual number of mailbox messages to be


filled in by the kernel.

Returns GOOD: if good, also fills in mmp and np


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_NO_MESSAGES
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED

FactoryLink Programmer’s Access Kit / 207


• PAK API REFERENCE LIBRARY



Remarks Use this function to read one or more mailbox message headers without reading their
message data and without dequeueing them. The MBXMSG holds information about
the message, such as type, who sent it, and length of its data. Therefore, call
fl_query_mbx( ) prior to allocating space for the message data and calling
fl_read_mbx( ). The argument i specifies where, relative to the head of the message
queue, reading is to begin (i = 0 means start at the head itself, i = 1 means skip the
first message and start with the second, and so on). The message at the head of the
queue is the oldest message in the mailbox. The argument n specifies how many
maximum mailbox messages are requested to be read and the kernel fills in np with
the actual number read.

FL _ READ
Read specified tags from the real-time database.
Syntax #include <flib.h>
int fl_read(id_t id, TAG* tp, uint n, void* vp);

Arguments id_t id in Caller’s FactoryLink ID.


TAG* tp in Pointer to tag array specifying which tags
to read.
uint n in Number of tags to read.
void* vp out Pointer to area to receive values.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks The tags may have mixed data types, as with all database access calls. The values of
the tags are read from the real-time database and placed in the private data area of the
calling process pointed to by vp. After each tag is read, its change bit for the calling
process is cleared. The change state for other client processes are unaffected. When
reading blocks of mixed tag types, use fl_get_tag_info( ) to find out how much
memory to prepare before calling fl_read( ) when reading blocks of mixed tag types.
See also “fl_read_no_clear”

208 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ READ _ APP _ MBX


7
Read and dequeue a message from a mailbox in a specific application instance.
(Replaces fl_read_mbx).

PAK API Reference


Syntax #include <flib.h>
int fl_read_app_mbx(id_t id, id_t rid, MBX mbx, MBXMSG* msg, uint i);

Library
Arguments id_t id in Caller’s FactoryLink ID.
id_t rid in FactoryLink ID of process owning the
mailbox.
MBX mbx in Mailbox to be accessed.
MBXMSG* msg out Pointer to a single mailbox message to be
returned.
uint i in Index relative to head of queue.

Returns GOOD: if good, also fills msg and message data


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_NO_MESSAGES
FLE_ACCESS_DENIED
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks Use fl_read_app_mbx( ) to read a single mailbox message together with its message
data. After this is done, the message is deleted or dequeued from the mailbox. If the
buffer provided by the caller is not large enough, message data may be lost.
Just as in fl_query_mbx( ), the argument i specifies which mailbox message, relative
to the head of the message queue, is to be read. However, fl_read( ) is less flexible
because it always reads from the head message. The following call:
fl_read_app_mbx(id, id, &mbxtag, mmp, 0);
is equivalent to:
fl_read(id, &mbx, 1, mmp);

FactoryLink Programmer’s Access Kit / 209


• PAK API REFERENCE LIBRARY



FL _ READ _ MBX
Read and dequeue a message from a mailbox (Obsolete. See fl_read_ app_mbx).
Syntax #include <flib.h>
int fl_read_mbx(id_t id, TAG mbx, MBXMSG* mmp, uint i);

Arguments id_t id in Caller’s FactoryLink ID.

TAG mbx in Mailbox to be accessed.

MBXMSG* mmp out Pointer to a single mailbox message to be


returned.

uint i in Index relative to head of queue.

Returns GOOD: if good, also fills mmp and message data.


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:

LE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_NO_MESSAGES
FLE_ACCESS_DENIED
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks This API has been retained from previous releases of FactoryLink to maintain
compatibility for users to upgrade with no changes to existing startup code. However,
new tasks should be written to use fl_read_app_mbx( ) with additional capabilities
for multi-user systems. fl_read_mbx( ) can only be used to send messages to tasks in
the same domain instance.
The following function call:
fl_read_mbx(id, &mbxtag, mmp, 0) ;
is equivalent to:
fl_read_app_mbx (id, id, &mbxtag, mmp, O) ;

210 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ READ _ NO _ CLEAR
7
Syntax #include <flib.h>
int fl_read(id_t id, TAG* tp, uint n, void* vp);;

PAK API Reference


Arguments id_t id in Caller’s FactoryLink ID.

Library
TAG* tp in Pointer to tag array specifying which tags to
read.

uint n in Number of tags to read.

void* vp out Pointer to area to receive values.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Function fl_read_no_clear( ) behaves exactly the same as function fl_read( ), except
that the change bits for the reading tasks are not cleared. This enables the program to
obtain the latest value of a tag while preserving the current state of the tag change bit
such that a changed value can be processed at some later point.
See also “fl_change_read”
“fl_read”

FactoryLink Programmer’s Access Kit / 211


• PAK API REFERENCE LIBRARY



FL _ RECV _ SIG
Receive a signal for the calling process.
Syntax #include <flib.h>
int fl_recv_sig(id_t id);

Arguments id_t id in Caller’s FactoryLink ID.

Returns The signal (0-31) received.


ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NO_SIGNALS
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks If two or more signals are active and deliverable when fl_recv_sig( ) is called, the
lowest numbered active signal is delivered to the caller. With the exception of signals
0 and 1, once a signal has been delivered, it is deactivated. This means once signals 0
and 1 are activated, they can never be deactivated.

FL _ SEND _ SIG
Send a signal to a target process.
Syntax #include <flib.h>
int fl_send_sig(id_t id, char* name, int sig);

Arguments id_t id in Caller’s FactoryLink ID.


char* name in Name of FactoryLink process the signal is to
be sent to.
int sig in Signal (0-31) to be sent.

Remarks It is legal to send any signal to any active FactoryLink process. If the intended
recipient of the signal is asleep or waiting to lock or to access the database in the
kernel and the signal is not being held, the recipient is immediately awakened and
returned the error code FLE_SIGNALLED. The recipient should then call
fl_recv_sig( ) to see which signal was sent.
Note the following function:
fl_ set_term_flag(id, name) ;

212 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

duplicates precisely the following function:


fl_send_sig(id, name, FLC_SIG_TERM_FLAG_SET ; 7

PAK API Reference


FL _ SET _ CHNG
Set the calling task change-status flags for specified tags.

Library
Syntax #include <flib.h>
int fl_set_chng(id_t id, TAG* tp, uint n);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array specifying which tags are


involved.

uint n in Number of tags involved.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Set the change state of the specified tags for the calling process only to ON. This
establishes initial conditions prior to entering a programming loop, particularly those
that use fl_change_read( ) or fl_change_wait( ) to read real-time database values.

FactoryLink Programmer’s Access Kit / 213


• PAK API REFERENCE LIBRARY



FL _ SET _ OWNER _ MBX
Set the owner of a mailbox.
Syntax #include <flib.h>
int fl_set_owner_mbx(id_t id, TAG mbx, uint onoff);

Arguments id_t id in Task ID.

TAG mbx in Mailbox to modify.

uint onoff in Flag to indicate operation.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_ACCESS_DENIED
Remarks Use this function to set the owner of a mailbox.
If the value of onoff is TRUE, the owner of the mailbox is set to the calling task.
If the value of onoff is FALSE, the mailbox ownership is removed.
When a write is performed on the mailbox, the owner of a mailbox is signaled with
flc_sig_message_received( ).
See also “fl_send_sig”

214 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ SET _ TERM _ FLAG


7
Set the termination flag of a client process.
Syntax #include <flib.h>

PAK API Reference


int fl_set_term_flag(id_t id, char* name);

Library
Arguments id_t id in Task ID.

char* name in Pointer to name of process the


termination flag is to be set for.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_BAD_PROC_NAME
FLE_NO_PROC_INIT
Remarks Set the termination flag of a client process within the same domain as the caller,
which may be different from the calling process. Normally, only the Run-Time
Manager uses this service.

FL _ SET _ WAIT
Set the calling task wait flags for specified tags.
Syntax #include <flib.h>
int fl_set_wait(id_tid, TAG* tp, uint n);

Arguments id_t id in Caller’s FactoryLink ID.

TAG* tp in Pointer to tag array specifying which tags


are involved.

uint n in Number of tags involved.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER

FactoryLink Programmer’s Access Kit / 215


• PAK API REFERENCE LIBRARY



FLE_LOCK_FAILED
FLE_BAD_TAG
Remarks Set the wait flag of the specified tags for the calling process only to ON. This function
is used in conjunction with fl_wait( ) to wait on a set of tags.

FL _ SLEEP
Delay execution of the task for the indicated number of milliseconds.
Syntax #include <flib.h>
void fl_sleep(ulong msecs);

Arguments ulong msecs in Number of milliseconds to delay.

Returns None
Remarks The actual resolution of the delay is system-specific; however, at most, the delay is
one second.

FL _ TEST _ TERM _ FLAG


Ask the kernel the current status of current task termination flag.
Syntax #include <flib.h>
int fl_test_term_flag(id_t id);

Arguments id_t id in Caller’s FactoryLink ID.

Returns OFF
ON
ERROR
Remarks Test the termination flag of the calling process and return its state to OFF or ON.
If the flag is ON, another client process (usually the Run-Time Manager) has
requested that the caller exit via fl_proc_exit( ).

216 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ UNLOCK
7
Unlock the real-time database for the calling process.
Syntax #include <flib.h>

PAK API Reference


int fl_unlock(id_t id);

Arguments id_t id in Task ID.

Library
Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID for
details.
Remarks Calls to fl_lock( ) and fl_unlock( ) nest; one call to fl_unlock( ) undoes one previous
call to fl_lock( ).

FL _ WAIT
Wait to read, write, or access the real-time database or certain tags in the database.
Syntax #include <flib.h>
int fl_wait(id_t id, int req);

Arguments id_t id in Caller’s FactoryLink ID.


int req in Command; must have one of the
following symbolic values:
FLC_WAIT_READ.
FLC_WAIT_WRITE.
FLC_WAIT_ACCESS.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_BAD_ARGUMENT
FLE_WAIT_FAILED
FLE_TERM_FLAG_SET
Remarks Ensure the fl_wait( ) function call is embedded between calls to functions fl_lock( )
and fl_unlock( ); otherwise, the task keeps the run-time database locked. Normally, a
task only waits to read a value; therefore, the constant FLC_WAIT_READ is passed
into the function.

FactoryLink Programmer’s Access Kit / 217


• PAK API REFERENCE LIBRARY



FL _ WRITE
Write specified tags into the real-time database.
Syntax #include <flib.h>
int fl_write(id_t id, TAG* tp, uint n, void* vp);

Arguments id_t id in Caller’s FactoryLink ID.


TAG* tp in Pointer to tag array specifying which tags
are to be written.
uint n in Number of tags to be written.
void* vp in Pointer to area holding the values.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_LOCK_FAILED
FLE_BAD_TAG
FLE_OUT_OF_MEMORY
FLE_FLOAT_NAN
FLE_FLOAT_POS_INF
FLE_FLOAT_NEG_INF
Remarks The tags may have mixed data types. The values of the tags are read from the private
data area pointed to by vp and written into the kernel database. After each value
transfer, vp is incremented by the size of the tag. If the new value of the tag is
different from its previous value, the tag change state for all client processes is set to
ON after it is written. Those processes waiting on a change to this tag are then
awakened.
The amount of data that can be written to a message tag is established by the length of
data of the first write to that tag. The one exception is if an explicit message length is
set within the tag definition.
For cases in which the length has not been pre-defined and the task needs to initialize
the space allocated to the message for that value, then:
set m_ptr member of the MSG structure is set to NULL
set m_max field is set to a non-zero value

218 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

This allocates space for the message based on the value of m_max but will not set the
change flag for the tag. This works only if no prior writes to the message tag have 7
occurred.

PAK API Reference


FL _ WRITE _ APP _ MBX
Write and queue a message into a mailbox. (Replaces fl_write_mbx).

Library
Syntax #include <flib.h>
int fl_write_app_mbx(id_t id, id_t wid, TAG mbx, MBXMSG* msg);

Arguments id_t id in Caller’s FactoryLink ID.


id_t wid in FactoryLink ID of process owning the mailbox.
TAG mbx in Mailbox to be accessed.
MBXMSG* msg in Pointer to a single mailbox message to be
returned.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_NO_MESSAGES
FLE_ACCESS_DENIED
FLE_OUT_OF_MEMORY
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks Use fl_write_app_mbx( ) to write a single mailbox message together with its message
data to a mailbox by application instance. The message being written is added to the
end of the queue. Prior to making this call, the caller must fill in the MBXMSG and
the message data. The additional arguments in the current API allow the caller to
specify the ID of the owner of the mailbox and an index into the queue. The owner's
ID is used to determine which instance of the mailbox to write this message into.

FactoryLink Programmer’s Access Kit / 219


• PAK API REFERENCE LIBRARY



Note that within the same domain instance, fl_write( ) does the same thing as
fl_write_app_mbx( ) when passed a mailbox TAG. That is, the function call
fl_write_app_mbx(id, id, &mbx, mmp) ;
is equivalent to:
fl_write(id, &mbx, 1, mmp) ;

FL _ WRITE _ MBX
Write and queue a message into a mailbox. (Obsolete. See fl_write_ app_mbx( )).
Syntax #include <flib.h>
int fl_write_mbx(id_t id, TAG mbx, MBXMSG* mmp);

Arguments id_t id in Caller’s FactoryLink ID.


TAG mbx in Mailbox to be accessed.
MBXMSG* mmp in Pointer to a single mailbox message.

Returns GOOD
ERROR: if error, call the fl_errno( ) function with the caller's FactoryLink ID and it
returns one of the following errors:
FLE_NULL_POINTER
FLE_BAD_TAG
FLE_NOT_MAILBOX
FLE_NO_MESSAGES
FLE_ACCESS_DENIED
FLE_OUT_OF_MEMORY
FLE_LOCK_FAILED
FLE_LOCK_EXPIRED
Remarks This API has been retained from previous releases of FactoryLink to maintain
compatibility for users to upgrade with no changes to existing startup code. However,
new tasks should use fl_write_app_mbx( ) with additional capabilities for multi-user
systems. fl_write_mbx( ) can only be used to send messages to tasks in the same
domain instance.
fl_write_mbx(id, &mbxtag, mmp) ;
is equivalent to:
fl_write_app_mbx(id, Id, &mbxtag, mp) ;

220 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ XLATE
7
Translate a key to its associated message.
Syntax #include <flib.h>

PAK API Reference


char* fl_xlate (char* key);

Library
Arguments char* key in Pointer to key to search for.

Returns Pointer to message if key found; equal to keyptr if key not found
Remarks This function returns the text associated with the passed in key. The associations must
have been previously created by loading a message translation file via fl_xlate_init( )
and/or fl_xlate_load( ).
Example 1
Allocate a message array, such as message[ ], and call the translation function to
access messages in the message file and put the result in message[ ]. In the following
example, the function copies the string normal shutdown (the message associated
with the key SHUTDOWN) into message[ ].
char message[100];
strcpy(message, fl_xlate(SHUTDOWN));
See also “fl_xlate_init”
“fl_xlate_load”

FL _ XLATE _ INIT
Message translation initialization; loads the first message file.
Syntax #include <flib.h>
int fl_xlate_init (char* name, char* bp, uint blen);

Arguments char* name in Name of message file.

char* bp Unused parameter that remains for backward


compatibility.

uint blen Unused parameter that remains for backward


compatibility.

Returns Number of messages read and buffered or ERROR.

FactoryLink Programmer’s Access Kit / 221


• PAK API REFERENCE LIBRARY



Remarks This function, along with fl_xlate( ), comprises the basis of the message-translation
facility. These two functions allow run-time tasks to print messages stored in external
disk files called message files.
When called to initialize the message translation environment, the function
fl_xlate_init( ) starts a fresh translation tree and loads the default translation file
MASTER.TXT. The user-specified translation file is then loaded on top of the
existing definitions. Duplicate definitions are superseded by the last file loaded. The
function returns the total number of translations loaded from both the MASTER.TXT
file as well as the user-specified file or it returns ERROR if there has been an error.
The buff and len parameters of fl_xlate_init( ) are not used by the function but were
retained to stay compatible with existing code.
A task that uses the message translation facility can be written so it is independent of
the messages it prints. It is dependent on the mnemonic keys but not the messages. In
particular, it may be written so it is independent of the language the messages are
written in. Achievement of this independence is the main purpose of message
translation.
Message files are ASCII text files that can be edited and changed with an ordinary
text editor. The current working copies of these files on a FactoryLink system are in
the directory {FLINK}/MSG/{LANG} and all are assumed to have the extension
.TXT. Message files must conform to the following rules:
The message translation functions assume lines beginning with an asterisk are
comments and ignores these lines. They also ignore blank lines.
Non-comment, non-blank lines serve to translate a key to an associated message.
They must have the following form:
KEY white space MESSAGE
The message may be enclosed within double quote marks for clarity and to avoid the
stripping of leading and trailing white space by the translation function. It may
contain %, the substitution character used by PRINTF and SPRINTF.
A vertical bar (|) is allowed as a separator within the white space for compatibility
with the format of FactoryLink .KEY files.
When editing a message file, place the most commonly used messages near the
beginning of the file so access to the commonly used messages is quicker than to
other messages, particularly when the buffer in use is small.
To use the message-translation functions, a task first calls the initialization function,
which opens the message file {FLINK}/MSG/EN/RUNMGR.TXT, as shown in the
following example:
fl_xlate_init(RUNMGR, NULL, 0);

222 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

This function loads the contents of message file {FLINK}/MSG/EN/RUNMGR.TXT


into an in-memory binary tree which is sorted by message token. 7
See also “fl_xlate”

PAK API Reference


“fl_xlate_load”
“fl_xlate_set_tree”
“fl_xlate_get_tree”

Library
FL _ XLATE _ LOAD
Load the specified file (passed as a parameter) into the current translation tree
replacing any duplicate key.
Syntax #include <flib.h>
int fl_xlate_load (char* fname);

Arguments char* fname in File name to load tree data from.

Returns Number of entries loaded from this file.


ERROR
Remarks The function fl_xlate_load( ) loads the specified file into the current translation tree,
replacing any duplicate keys. The function returns the number of entries loaded from
this file or returns ERROR.
To load a new tree, an alternate tree to the default tree should have been created
previously using the fl_xlate_set_tree( ) function. The new tree becomes the default
tree into which the keys from the xlate file are loaded. Tasks may maintain more than
one translation tree.
FactoryLink determines the language currently running and loads the text file from
the correct language subdirectory under {FLINK}/MSG/{XX} where XX represents the
currently selected FactoryLink language.
Example 1
int num_msg;
num_msg = fl_xlate_init(runmgr, NULL, 0);
if (num_msg == 0)
return ERROR;
rum_msg = fl_xlate_load(iml);
if (num_msg == 0)
return ERROR;
printf(%s\n, fl_xlate(token));
Example 2
If the current language variable is not defined, the call:

FactoryLink Programmer’s Access Kit / 223


• PAK API REFERENCE LIBRARY



num_msg = fl_xlate_init(iml, NULL, 0)
loads the {FLINK}/MSG/master.txt file into the tree and then loads the
{FLINK}/MSG/iml.txt file into the tree. The return value is the total number of
translations loaded from both files. Duplicates are only counted once.
The call
num_msg = fl_xlate_load(iml)
loads the file {FLINK}/MSG/iml.txt into the tree and returns the number of
translations.
The call
num_msg = fl_xlate_load(/temp/test)
loads the file /TEMP/test.txt into the tree and returns the number of translations.
Example 3
If the current language variable is defined as DE, the following call:
num_msg = fl_xlate_init(iml, NULL, 0)
loads the {FLINK}/MSG/DE/master.txt file into the tree and then loads the
{FLINK}/MSG/DE/iml.txt file into the tree. The return value is the total number of
translations loaded from both files. Duplicates are counted only once.
The call
num_msg = fl_xlate_load(iml)
now loads the file {FLINK}/MSG/DE/iml.txt into the tree and returns the number of
translations.
The call
num_msg = fl_xlate_load(/temp/test)
still loads the file /TEMP/test.txt into the tree and returns the number of translations.
See also “fl_xlate”
“fl_xlate_init”
“fl_xlate_set_tree”
“fl_xlate_get_tree”

224 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FL _ XLATE _ GET _ TREE


7
Returns the address of the current translation tree or the string NULL if no translation
files have been loaded.

PAK API Reference


Syntax #include <flib.h>
void* fl_xlate_get_tree( void );
Return Address of the current translation tree; returns NULL if no translation files have been

Library
loaded
Remarks This is useful when a program maintains multiple translation trees. This function
returns the address of the current translation tree (default translations for FactoryLink
tasks) is returned by calling this function.
Tasks may maintain more than one translation tree. Translation files may be kept in
libraries, one per language used, for ease of use. This guarantees all tasks remain
language-independent and allows run-time tasks to use the fl_xlate( ) functions for all
message output.
Example
void *english, *french; /* pointers to 2 trees */
int num_msg1, num_msg2;
num_msg1 = fl_xlate_init(english/iml, NULL, 0);
english = fl_xlate_get_tree();
num_msg2 = fl_xlate_init(french/iml, NULL, 0);
french = fl_xlate_get_tree();
fl_xlate_set_tree (english); /* Switch to English tree */
printf (%s\n, fl_xlate(token);
fl_xlate_set_tree (french); /* Switch to French tree */
printf (%s\n, fl_xlate(token);
You may switch translation trees at any point in the program and switch back when
ready without losing any data.
See also “fl_xlate”
“fl_xlate_init”
“fl_xlate_set_tree”
“fl_xlate_get_tree”

FactoryLink Programmer’s Access Kit / 225


• PAK API REFERENCE LIBRARY



F L _ XLATE _ SET _ PROGPATH
Overrides the environment variable {FLINK}, allowing programs to support the -p
command parameter for overriding the default program directory.
Syntax #include <flib.h>
int fl_xlate_set_progpath(char* progname);

Arguments char* progname in Pointer to path of program directory to be


used for translation.

Returns The number of characters in the program path name.

FL _ XLATE _ SET _ TREE


Sets the current translation tree to the tree at the specified address. Ensuing file loads
and translations use this tree.
Syntax #include <flib.h>
void* fl_xlate_set_tree( void* tree);

Arguments void tree in Pointer to tree used for translation.

Returns Pointer sent by the programmer.


NULL
Remarks This function is useful when a program maintains multiple translation trees. This
function switches the current active translation tree (that referenced by subsequent
fl_xlate( ) calls).
This function also starts a fresh translation tree file.
Tasks may maintain more than one translation tree. Translation files may be kept in
libraries, one per language used, for ease of use. This guarantees all tasks remain
language-independent and allows run-time tasks to use the fl_xlate( ) functions for all
message output.
Example 1
void *english, *french; /* pointers to 2 trees */
int num_msg1, num_msg2;
num_msg1 = fl_xlate_init(english/iml, NULL, 0);
english = fl_xlate_get_tree();
num_msg2 = fl_xlate_init(french/iml, NULL, 0);

226 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

french = fl_xlate_get_tree();
fl_xlate_set_tree (english); /* Switch to English tree */ 7
printf (%s\n, fl_xlate(token);
fl_xlate_set_tree (french); /* Switch to French tree */

PAK API Reference


printf (%s\n, fl_xlate(token);
You switch translation trees at any point in the program and switch back when ready
without losing any data.

Library
The following example shows fl_xlate_set_tree( ) starting a fresh tree:
fl_xlate_set_tree(NULL) ; /* start new tree */
See also “fl_xlate”
“fl_xlate_init”
“fl_xlate_get_tree”
“fl_xlate_load”

FLDTP _ ACTION _ GET _ ARGS


Syntax #include <fldtp.h>
int fldtp_action_get_args(FLDTP_ACTION* ap, void*** f_argv);

Arguments FLDTP_ACTION* ap in DTP action handle.

VOID*** F_ARGV out Argument array.

Returns >=0; number of arguments


FLDTP_E_{…} error code
Remarks Function fldtp_action_get_args( ) returns the number of arguments associated with
the given action record. It also returns the handle to the argument array itself. This
array should be treated as read-only.
See also “fldtp_action_set_args”

FactoryLink Programmer’s Access Kit / 227


• PAK API REFERENCE LIBRARY



FLDTP _ ACTION _ GET _ DESTROY
Direct Tag Processing API.
Syntax #include <fldtp.h>
int fldtp_action_get_destroyf(FLDTP_ACTION* ap, FLDTP_FUNC_DESTROY* destroyf);

Arguments FLDTP_ACTION* ap in DTP action handle.

FLDTP_FUNC_DESTROY* destroyf out Destruction function pointer.

Returns FLDTP_E_GOOD
FLDTP_e_{…} error code
Remarks Function fldtp_action_get_destroyf( ) returns a pointer to the destruction notification
function associated with the given action record.
See also “fldtp_action_set_destroyf”

FLDTP _ ACTION _ GET _ ID


Syntax #include <fldtp.h>
int fldtp_action_get_id(FLDTP_ACTION* ap, void*** id);

Arguments FLDTP_ACTION* ap in DTP action handle.

void*** id out ID to associate with the given record.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_get_id( ) returns the identifier bound to the given action
record.
See also “fldtp_action_set_id”

228 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ ACTION _ GET _ PRIORITY


7
Syntax #include <fldtp.h>
int fldtp_action_get_priority(FLDTP_ACTION* ap, long* prio);

PAK API Reference


Arguments FLDTP_ACTION* ap in DTP action handle.
long* prio out Priority assigned to given record.

Library
Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_get_priority( ) returns a processing priority that has been
assigned to the given action record.
See also “fldtp_action_set_priority”

FLDTP _ ACTION _ SET _ ARGS


Syntax #include <fldtp.h>
int fldtp_action_set_args(FLDTP_ACTION* ap, short f_argc, void* f_argv[]);

Arguments FLDTP_ACTION* ap in/out DTP action handle.


short f_argc in Number of arguments in the array.
VOID*[ ] f_argv in Argument array.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_set_args( ) binds user data to the given action record. This
allows the process function to have all salient information immediately available.
Consider the typedef FLDTP_FUNC_ACTION process functions must conform to:
typedef void (*FLDTP_FUNC_ACTION) (TAG*, VAL*, short, void**);
When processing tag values, the DTP calls the process function pointed to by afunc
with its tag, its value, and a pair of user-defined arguments. The short and void**
parameters, as shown in the above typedef, are the f_argc and f_argv set using
fldtp_action_set_args( ).

FactoryLink Programmer’s Access Kit / 229


• PAK API REFERENCE LIBRARY



Arguments f_argc and f_argv define the user arguments to pass to the process
function. Function fldtp_action_set_args( ) makes a copy of void pointer array
f_argv when attaching it to the given action record. As such, the caller need not to
preserve the void pointer array afterwards.
The data the pointer within f_argv array references is arbitrary. This should be
information that the process function needs in order to process the associated tag.
See also “fldtp_action_get_args”
“fldtp_action_set_destroyf”
“fldtp_insert”

FLDTP _ ACTION _ SET _ DESTROYF


Syntax #include <fldtp.h>
int fldtp_action_set_destroyf(FLDTP_ACTION* ap, FLDTP_FUNC_DESTROY* destroyf);

Arguments FLDTP_ACTION* ap in/out DTP action handle.


FLDTP_FUNC_DESTROY* DESTROY out Destruction function
pointer.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_set_destroyf( ) attaches a destruction notification function to
the given action record. This function is called just prior to the action record being
destroyed. Action records are destroyed as a result of a DTP removal call or as part of
destroying the DTP it is attached to.
Consider the typedef FLDTP_FUNC_DESTROY process functions must conform to:
typedef void (*FLDTP_FUNC_DESTROY) (TAG*, short, void**);
The short and void** parameters, as shown in the above typedef, are the f_argc and
f_argv set using fldtp_action_set_args( ).
The main motivation for associating a destruction function with an action record is to
provide an easy mechanism to release memory referenced in the f_argv void array. If
the action record is the sole user of attached information, this destruction callback
allows the user to release it.
See also “fldtp_action_get_destroy”
“fldtp_action_set_args”
“fldtp_remove”
“fldtp_remove_group”
“fldtp_destroy”

230 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ ACTION _ SET _ ID


7
Syntax #include <fldtp.h>
int fldtp_action_set_id(FLDTP_ACTION* ap, void* id);

PAK API Reference


Arguments FLDTP_ACTION* ap in/out DTP action handle.
void* id in ID to associate with the given record.

Library
Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_set_id( ) binds an identifier to the given action record.
Setting the ID provides a mechanism for differentiating one action record from
another, either by groups or by individuals. The most common use for this ID is the
removal of a group of action records from the DTP based on this ID.
The ID is a void* and, by default, ID comparisons are based on equality. This default
comparison can be superseded with a user provided function.
See also “fldtp_action_get_id”
“fldtp_remove_group”
“fldtp_set_comparef”

FLDTP _ ACTION _ SET _ PRIORITY


Syntax #include <fldtp.h>
int fldtp_action_set_priority(FLDTP_ACTION* ap, long prio);

Arguments FLDTP_ACTION* ap in/out DTP action handle.


long prio in Priority assigned to the given record.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_action_set_priority( ) binds a processing priority to the given action
record. The action record priority controls the order simultaneous tag changes are
processed in. The default priority for action records in 0.
The priority is only considered when the DTP is processing by priority.
See also “fldtp_action_get_priority”
“fldtp_set_proc_by”

FactoryLink Programmer’s Access Kit / 231


• PAK API REFERENCE LIBRARY



FLDTP _ CHANGE _ READ
Syntax #include <fldtp.h>
int fldtp_change_read(FLDTP* dtp, id_t task_id,int start_from, FLDTP_TAG** dtp_tag, VAL* val);

Arguments FLDTP dtp in DTP action handle.

id_t task_id in Argument array.

int start_from in Read next tag that changes, starting


from:
FLDTP_READ_TOP
or
FLDTP_READ_NEXT.

FLDTP_TAG** dtp_tag Out Tag value that has changed.

VAL* val Out Tag value.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Analogous to fl_change_read( ), function fldtp_change_read( ) reads the value of
the next changed tag. The definition of next is set by the start_from parameter. Only a
single pass through the tags is made.
See also “fldtp_proc_wait”

FLDTP _ CREATE
Syntax #include <fldtp.h>
int fldtp_create(FLDTP* dtp);

Arguments FLDTP* dtp out DTP handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_create( ) allocates, initializes, and returns a DTP handle. This DTP
handle is passed in all subsequent calls to the FLDTP API.
See also “fldtp_destroy”

232 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ DESTROY
7
Syntax #include <fldtp.h>
int fldtp_destroy(FLDTP* dtp);

PAK API Reference


Arguments FLDTP* DTP in/out DTP handle.

Library
Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_destroy( ) releases the DTP handle along with all resources held by it.
This handle should not be referenced once it is destroyed.
See also “fldtp_create”

FLDTP _ GET _ COMPAREF


Syntax #include <fldtp.h>
int fldtp_set_comparef(FLDTP* dtp, FLDTP_FUNC_COMPARE* cfunc);

Arguments FLDTP* dtp in DTP handle.

FLDTP_FUNC_COMPARE* CFUNC out Function to compare IDs


with.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_get_comparef( ) returns the function used when comparing the IDs
associated with an action record.
See also “fldtp_get_compare”

FactoryLink Programmer’s Access Kit / 233


• PAK API REFERENCE LIBRARY



FLDTP _ GET _ MSGLEN
Syntax #include <fldtp.h>
int fldtp_get_msglen(FLDTP* dtp, int* msglen);

Arguments FLDTP* dtp in DTP handle.

int* msglen out Length of message read buffer.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_get_msglen( ) returns the size for the buffer used to read the value of a
message tag from the real-time database.
See also “fldtp_get_msglen”

FLDTP _ GET _ TAGCNT


Syntax #include <fldtp.h>
int fldtp_get_tagcnt(FLDTP* dtp, long* tagcnt);

Arguments FLDTP* dtp in DTP handle.

long* tagcnt out Number of tags referenced by the DTP.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_get_tagcnt( ) returns the number of unique tags inserted into the given
DTP.
See also “fldtp_insert”

234 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ INSERT
7
Syntax #include <fldtp.h>
int fldtp_insert(FLDTP* dtp, TAG* tag, FLDTP_FUNC_ACTION afunc, FLDTP_ACTION** ap);

PAK API Reference


Arguments FLDTP* dtp in/out DTP handle.
TAG* tag in Tag to process.

Library
FLDTP_FUNC_ACTION afunc in Function to process tag with.
fldtp_action** ap out Record created by insertion.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_insert( ) registers a tag with its action into the DTP. The dtp argument
specifies which DTP instance to insert into. The tag argument specifies the tag to be
processed. The afunc argument specifies the process function to use for processing
the given tag. The typedef FLDTP_FUNC_ACTION defines the Syntax the process
function must conform to:
typedef void (*FLDTP_FUNC_ACTION) (TAG*, VAL*, short, void**);
When processing tag values, the DTP calls the process function pointed to by afunc
with its tag, its value, and a pair of user-defined arguments. The short and void**
parameters, as shown in the above typedef, are an argc/argv combination analogous
to the arguments to the main routine of a C program.
It is legal to insert the same tag multiple times. In such a case, the process function
will be called for each insertion. In FactoryLink terminology, DTP supports using the
same tag to trigger several events.
See also “fldtp_action_set_args”
“fldtp_remove”

FactoryLink Programmer’s Access Kit / 235


• PAK API REFERENCE LIBRARY



FLDTP _ PROC
Syntax #include <fldtp.h>
int fldtp_proc(FLDTP* dtp, id_t task_id);

Arguments FLDTP* dtp in DTP handle.


id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_proc( ) immediately invokes all action records inserted into the given
DTP. For each action record, the associated tag is read and its action function invoked
with the tag value. Only a single pass through the tags is made.
See also “fldtp_proc_wait”
“fldtp_set_proc_by”

FLDTP _ PROC _ ACTION


Syntax #include <fldtp.h>
int fldtp_proc_action(FLDTP* dtp, FLDTP_ACTION* ap, id_t task_id);

Arguments FLDTP* dtp in DTP handle.

FLDTP_ACTION* ap in Action record handle.

id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_proc_action( ) reads the tag and invokes the action function associated
with the given action record handle.
See also “fldtp_insert”

236 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ PROC _ CHANGE


7
Syntax #include <fldtp.h>
int fldtp_proc_change(FLDTP* dtp, id_t task_id);

PAK API Reference


Arguments FLDTP* dtp in DTP handle.

Library
id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_proc_change( ) invokes the action functions bound to those tags
within the DTP that have changed. Only a single pass through the tags is made.
This function is similar to function fldtp_proc_wait( ), except it does not put the task
to sleep. Hence, the function is most useful for tasks that must poll the real-time
database because they are waiting on external events (network traffic, GUI events).
See also “fldtp_proc_wait”
“fldtp_set_proc_by”

FLDTP _ PROC _ TAG


Syntax #include <fldtp.h>
int fldtp_proc_tag(FLDTP* dtp, TAG* tag, id_t task_id);

Arguments FLDTP* dtp in DTP handle.

TAG* tag in Tag to execute all action records with.

id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_proc_tag( ) reads the tag and processes all action records associated
with it. Priority-based processing is honored by this function.
See also “fldtp_proc_wait”
“fldtp_set_proc_by”

FactoryLink Programmer’s Access Kit / 237


• PAK API REFERENCE LIBRARY



FLDTP _ PROC _ WAIT
Syntax #include <fldtp.h>
int fldtp_proc_wait(FLDTP* dtp, id_t task_id);

Arguments FLDTP* dtp in DTP handle.

id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_proc_wait( ) invokes the action functions bound to those tags within
the changed DTP. Only a single pass through the tags is made.
If no changes are outstanding when calling this function, then it puts the task to sleep
until one of the tags within DTP tags changes. Upon awakening, any changed tags are
processed before the function returns to the caller.
Function fldtp_proc_wait ( ) is the most commonly used of the DTP process
functions.
See also “fldtp_proc_change”
“fldtp_set_proc_by”

FLDTP _ REMOVE
Syntax #include <fldtp.h>
int fldtp_remove(FLDTP* dtp, FLDTP_ACTION* ap);

Arguments FLDTP* dtp in/out DTP handle.

FLDTP_ACTION* ap in/out Record to remove.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_remove( ) deletes the given action record from the DTP. If a
destruction function is associated with the action record, it is invoked during the
removal.
Removing the action record from the DTP destroys it. As such, the action record
handle should no longer be referenced after the fldtp_remove( ) call.

238 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

See also “fldtp_action_set_destroyf”


“fldtp_insert” 7
“fldtp_remove_group”

PAK API Reference


FLDTP _ REMOVE _ GROUP
Syntax

Library
#include <fldtp.h>
int fldtp_remove_group(FLDTP* dtp, TAG* tag,
FLDTP_FUNC_ACTION afunc, void* id);

Arguments FLDTP* dtp in/out DTP handle.


TAG* tag in Tag to process.
FLDTP_FUNC_ACTION afunc in Function to process tag
with.
void* id out Record created by the
insertion.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_remove_group( ) deletes a group of action records from the DTP
based on any combination of tag, action function pointer, and/or ID. Passing NULL
for parameter tag, afunc, or id excludes that parameter from being included in the
removal criteria.
For example, passing NULL for both tag and afunc means that all action records
whose ID matches parameter id will be removed. The parameters passed as NULL are
not considered as part of the removal criteria.
Whenever an action record is removed, its destruction handler, if set, is invoked.
See also “fldtp_action_set_id”
“fldtp_action_set_destroyf”
“fldtp_insert”
“fldtp_remove”

FactoryLink Programmer’s Access Kit / 239


• PAK API REFERENCE LIBRARY



FLDTP _ SET _ COMPAREF
Syntax #include <fldtp.h>
int fldtp_set_comparef(FLDTP* dtp, FLDTP_FUNC_COMPARE cfunc);

Arguments FLDTP* dtp in/out DTP handle.


FLDTP_FUNC-COMPARE cfunc in Function to compare IDs
with.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks fldtp_set_comparef( ) establishes the function to use when comparing the IDs
associated with an action record. Typedef FLDTP_FUNC_COMPARE defines the
Syntax to which the comparison function must conform:
typedef int (*FLDTP_FUNC_COMPARE) (void* , void*);

#define FLDTP_ID_SAME 0
#define FLDTP_ID_DIFF 1

The comparison function is used when removing action records based on a particular
ID. The user provided comparison function returns constant FLDTP_SAME_ID for
equivalent IDs or constant FLDTP_DIFF_ID for different ones.
The default comparison is a simple equality (void* a == void* b). Setting the
comparison function to NULL returns the DTP back to this default.
See also “fldtp_action_set_id”
“fldtp_remove_group”

240 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLDTP _ SET _ MSGLEN


7
Syntax #include <fldtp.h>
int fldtp_set_msglen(FLDTP* dtp, int msglen);

PAK API Reference


Arguments FLDTP* dtp in/out DTP handle.

Library
int msglen in New length for message read buffer.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks Function fldtp_set_msglen( ) establishes a new size for the buffer used to read the
value of a message tag from the real-time database. The default size is 80 characters.
See also “fldtp_get_msglen”

FLDTP _ SET _ PROC _ BY


Syntax #include <fldtp.h>
int fldtp_set_proc_by(FLDTP* dtp, int proc_by);

Arguments FLDTP* dtp in/out DTP handle.

int proc_by in Process by constant


FLDTP_BY_FIFO or
FLDTP_BY_PRIO.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks fldtp_set_proc_by( ) determines the order by which simultaneous tag changes are
processed. The selection of process order profoundly affects the operation of the DTP.
The following discusses the behavior of both.
Processing by first-in-first-out, or FLDTP_BY_FIFO( ), is analogous to how most
FactoryLink tasks currently operate. The order of processing mirrors the order unique
tag entries are inserted into the DTP. This manner of processing is optimal since the
value of a single tag is stored in memory at any one time. It is also the default mode of
processing unless the DTP is explicitly set otherwise.

FactoryLink Programmer’s Access Kit / 241


• PAK API REFERENCE LIBRARY



Processing by priority, or FLDTP_BY_PRIO( ), invokes change handlers based on an
ascending order of priorities. Priority-based processing begins by taking a snapshot of
all changed tags with their values. Then, the process functions for the changed tags
are invoked in order of their assigned priority. As a result, the overhead of tag
processing increases in terms of reaction time and memory use.
Unless your task has specific requirements that one action always be processed prior
to another, use FLDTP_BY_FIFO( ).
See also “fldtp_action_set_priority”

FLDTP _ WAIT
Syntax #include <fldtp.h>
int fldtp_wait(FLDTP* dtp, id_t task_id);

Arguments FLDTP* dtp in DTP handle.

id_t task_id in Task handle.

Returns FLDTP_E_GOOD
FLDTP_E_{…} error code
Remarks fldtp_proc_wait( ) is analogous to fl_wait( ) in that the task goes to sleep until one of
the tags inserted into the DTP changes. Unlike the PAK function, fldtp_wait( ) returns
immediately if one of the tags within the DTP has changed prior to invoking this
function.
See also “fldtp_proc_change”

FLNTAG _ CALC _ BASE


Normalized Tag API.
Syntax #include <flntag.h>
int flntag_calc_base(FLNTAG* ntag, TAG* tag, char* def_dims, TAG* base);

Arguments FLNTAG* ntag in FLNTAG to obtain definition with.


TAG* tag in RTDB location (tag) for reference contained
within the given ntag.
char* def_dims in Dimensions defined for the given record.

242 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

TAG* base out Base RTDB location (tag) for object


referenced by ntag. 7
Returns FLNTAG_E_GOOD

PAK API Reference


FLNTAG_E_HANDLE
FLNTAG_E_INVARG

Library
FLNTAG_E_DIMNUM
FLNTAG_E_DIMSIZ
Remarks Given a normalized tag reference, its RTDB location and its dimension definition,
function flntag_calc_base( ) calculates the RTDB location for the base of the given
ntag. For nonarrayed objects, the location of a tag reference always equals the base
tag location obtained from the object definition.
This function is commonly called during the loading of a task CT. CTs often contain
the reference string, the RTDB location for the reference string, and the dimension
definition for the object being referenced. This function uses these three pieces of
information to obtain the base location for reference.
See also “flntag_create”
“flntag_find_def”

FLNTAG _ CALC _ TAG


Normalized Tag API.
Syntax #include <flntag.h>
int flntag_calc_tag(FLNTAG* ntag, TAG* base, char* def_dims, TAG* tag);

Arguments FLNTAG* ntag in FLNTAG to obtain definition for.

TAG* base in RTDB location (tag) for base of the reference


contained within given ntag.

char* def_dims in Dimensions defined for given object.

TAG* tags out Base RTDB location (tag) for object


referenced by ntag.

Returns FLNTAG_E_GOOD
FLNTAG_E_HANDLE
FLNTAG_E_INVARG

FactoryLink Programmer’s Access Kit / 243


• PAK API REFERENCE LIBRARY



FLNTAG_E_DIMNUM
FLNTAG_E_DIMSIZ
Remarks Given a normalized tag reference, its base RTDB location, and its dimension
definition, function flntag_calc_tag( ) calculates the RTDB location for the given
ntag. For nonarrayed objects, the location of a tag reference always equals the base
tag location obtained from the object definition.
Code Sample: Converting a FLNTAG to a TAG
#include <flntag.h>
/*
* Function convert_ntag2tag() returns the RTDB location for the
* given reference.
*/
int convert_ntag2tag(FLNTAG *ntag, CT *objct, TAG *tag)
{
FLOBJREC def
int rv;
if ((rv = flntag_find_def(ntag, objct, &def) == FLNTAG_E_GOOD)
{
rv = flntag_calc_tag(ntag,
flobjrec_get_tag(&def),
flobjrec_get_dimen(&def),
tag);
}
return rv;
}
See also “flntag_create”
“flntag_find_def”

FLNTAG _ CREATE
Normalized Tag API.
Syntax #include <flntag.h>
FLNTAG* flntag_create(void);
Returns This function returns:

Type Description

FLNTAG Normalized tag instance handle.

244 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

NULL Memory allocation failure.


7
Remarks Function flntag_create( ) allocates a normalized tag instance. This handle is

PAK API Reference


subsequently passed to all other flntag_…( ) functions.
See also “flntag_destroy”

Library
FLNTAG _ DESTROY
Normalized Tag API.
Syntax: #include <flntag.h>
FLNTAG* flntag_destroy(FLNTAG* ntag);

Arguments FLNTAG* ntag in/out Handle to release.

Remarks Function flntag_destroy( ) releases all resources associated with the given handle.
This handle should not be referenced after being destroyed.
See also “flntag_create”

FLNTAG _ FIND _ DEF


Normalized Tag API.
Syntax #include <flntag.h>
int flntag_find_def(FLNTAG * ntag, CT* objct, FLOBJREC* rec);

Arguments FLNTAG* ntag in FLNTAG to obtain definition for.

CT* objct in Object CT handle.

FLOBJREC* REC OUT Definition for object referenced by ntag.

Returns FLNTAG_E_GOOD
FLNTAG_E_GENERAL
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
Remarks Function flntag_find_def( ) returns the definition for the object referenced by the
given ntag. This definition is obtained by searching the application object CT.

FactoryLink Programmer’s Access Kit / 245


• PAK API REFERENCE LIBRARY



Parameter objct, a required argument for this function, is obtained via function
ct_open_obj( ).
See also “flntag_create”
“flntag_parse_ref”
“ct_open_obj”

FLNTAG _ FIND _ TAG


Normalized Tag API.
Syntax #include <flntag.h>
int flntag_find_tag(FLNTAG* ntag, CT* objct, TAG* tag);

Arguments FLNTAG* ntag in FLNTAG to obtain object for.


CT* objct in Object CT handle.
TAG* tags out RTDB location (tag) for object
referenced by ntag.

Returns FLNTAG_E_GOOD
FLNTAG_E_GENERAL
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
FLNTAG_E_DIMNUM
FLNTAG_E_DIMSIZ
Remarks Function flntag_find_tag( ) returns the RTDB location (the tag) for the object
referenced by the given ntag. This location is obtained by searching the application
object CT for the object definition, obtaining the base RTDB location from that
definition, and finally, calculating the offset from the base if the tag is an arrayed tag.
For example, if the ntag equates to reference x[3], function flntag_find_tag( ) returns
RTDB location for x[3], not x[0].
Parameter objct, a required argument for this function, is obtained via function
ct_open_obj( ).
See Also: “flntag_create”
“flntag_calc_tag”
“flntag_parse_ref”
“ct_open_obj”

246 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLNTAG _ GEN _ OBJNAME


FLNTAG _ GEN _ REF 7
FLNTAG _ GEN _ STR

PAK API Reference


Normalized Tag API.
Syntax #include <flntag.h>

Library
int flntag_gen_str(FLNTAG* ntag, u16 incl, char* outstr, int maxlen);
#define flntag_gen_objname(ntag, outstr, maxlen) \ flntag_gen_str(ntag,FLNTAG_S_DIMEN, outstr, maxlen);
#define flntag_gen_ref(ntag, tagref, maxlen) \
flntag_gen_str(ntag, 0, tagref, maxlen);

Arguments FLNTAG* ntag in FLNTAG to generate string for.


u16 incl in Bit-wise OR-flags for components to include
within generated string.
FLNTAG_S_NODE.
FLNTAG_S_NAME.
FLNTAG_S_DIMEN.
FLNTAG_S_MEMBER.l
char* outstr out Target buffer for generated string.
If NULL, string is not generated.
int maxlen in Maximum number of characters to write to
outstr buffer.

Returns RTN>0
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
Remarks Function flntag_gen_str( ) generates the reference string to which the given ntag
equates. When nonzero, parameter incl, a bit mask, includes one or more components
from the resulting string.
Normally, the entire reference is desired and the macro flntag_gen_ref( ) can be used
to build it.
Macro flntag_gen_objname( ) can be used for cases where the object name is
needed.
See also “flntag_create”
“flntag_parse_ref”

FactoryLink Programmer’s Access Kit / 247


• PAK API REFERENCE LIBRARY



FLNTAG _ GET _ DIMEN
FLNTAG _ GET _ MEMBER
FLNTAG _ GET _ NAME
FLNTAG _ GET _ NODE
Normalized Tag API.
Syntax #include <flntag.h>
char* flntag_get_dimen(FLNTAG* ntag);
char* flntag_get_member(FLNTAG* ntag);
char* flntag_get_name(FLNTAG* ntag);
char* flntag_get_node(FLNTAG* ntag);

Arguments FLNTAG* ntag in FLNTAG whose components are being


obtained.

Returns VALUE STRING


Remarks Normalized tags consist of four components: node, name, dimension, and member.
This set of flntag_get_…( ) functions allows the caller to obtain the current value of
an individual component. All values are returned as null-terminated strings.
Currently, these entry points are implemented as macros, which return a pointer to the
private members of the FLNTAG structure. These addresses must be treated in a
read-only manner.
See also “flntag_create”
“flntag_gen_str”
“flntag_set_dimen”
“flntag_set_member”
“flntag_set_name”
“flntag_set_node”

248 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLNTAG _ PARSE _ BRKT 4 DIMS


FLNTAG _ PARSE _ COMMA 4 DIMS 7
Normalized Tag API.

PAK API Reference


Syntax #include <flntag.h>
i16 flntag_parse_brkt4dims(char* dimstr, u16* dims, u16 dimslen);

Library
i16 flntag_parse_comma4dims(char* dimstr, u16* dims, u16 dimslen);

Arguments char* dimstr in Dimension string to parse.

u16* dims out Size of each dimension found in parsed


string returned within array of u16s.
If equal to NULL, this information is
not returned.

u16 dimslen in Length of given dims array.


This prevents overwrites if the number
of dimensions exceed size of array.

Returns >=0
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
FLNTAG_E_REFSYN
Remarks Functions flntag_parse_brkt4dims( ) and flntag_parse_comma4dims( ) parses the
given dimension string and returns the number of dimensions contained within it.
These functions can also return the value of the each individual dimension as a u16
array.
Function flntag_parse_brkt4dims( ) expects dimension strings such as [2][4].
Function flntag_parse_comma4dims( ) expects dimension strings such as 2,4.
See also “flntag_parse_ref”

FactoryLink Programmer’s Access Kit / 249


• PAK API REFERENCE LIBRARY



FLNTAG _ PARSE _ REF
Normalized Tag API.
Syntax #include <flntag.h>
int flntag_parse_ref(FLNTAG* ntag, char* ref);

Arguments FLNTAG* ntag in/out FLNTAG to load according to given


reference.

char* ref in Reference to parse.

Return FLNTAG_E_GOOD
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
FLNTAG_E_REFSYN
Remarks Function flntag_parse_ref( ) parses the given object reference string and loads its
components into the given normalized tag handle. Each component is validated to
ensure it has a legal syntax.
The previous contents of the given ntag are overwritten by this operation.
See also “flntag_create”
“flntag_gen_ref”

250 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

FLNTAG _ SET _ DIMEN


FLNTAG _ SET _ MEMBER 7
FLNTAG _ SET _ NAME

PAK API Reference


FLNTAG _ SET _ NODE
Normalized Tag API.

Library
Syntax #include <flntag.h>
int flntag_set_dimen(FLNTAG* ntag, char* dimen);
int flntag_set_member(FLNTAG* ntag, char* member);
int flntag_set_name(FLNTAG* ntag, char* name);
int flntag_set_node(FLNTAG* ntag, char* node);

Arguments FLNTAG* ntag in/out FLNTAG whose components are being set.
char* value in Target set value.

Returns FLNTAG_E_GOOD
FLNTAG_E_HANDLE
FLNTAG_E_INVARG
FLNTAG_E_REFSYN
Remarks Normalized tags consist of four components: node, name, dimension, and member.
This set of flntag_set_…( ) functions allows an individual component of the
FLNTAG to be modified.
Valid syntax is enforced by these functions. The enforced rules include the following
Type Description
flntag_set_node Allowed characters are _@$ and alphanumeric.
flntag_set_name First character cannot be numeric.
flntag_set_member
flntag_set_dimen String containing dimensions delineated by brackets: [4] [5].

See also flntag_set and related functions


“flntag_create”
“flntag_gen_str”
“flntag_get_dimen”
“flntag_get_member”
“flntag_get_name”
“flntag_get_node”

FactoryLink Programmer’s Access Kit / 251


• PAK API REFERENCE LIBRARY



FLOBJREC _ GET _ CHGBITS
FLOBJREC _ GET _ DESCR
FLOBJREC _ GET _ DIMEN
FLOBJREC _ GET _ DOMAIN
FLOBJREC _ GET _ NAME
FLOBJREC _ GET _ PERWHEN
FLOBJREC _ GET _ TAG
FLOBJREC _ GET _ TYPE
Object CT API.
Syntax #include <objct.h>
u16 flobjrec_get_chgbits(FLOBJREC* rec);
char* flobjrec_get_descr(FLOBJREC* rec);
char* flobjrec_get_dimen(FLOBJREC* rec);
char* flobjrec_get_domain(FLOBJREC* rec);
char* flobjrec_get_name (FLOBJREC* rec);
u16 flobjrec_get_perwhen(FLOBJREC* rec);
TAG* flobjrec_get_tag(FLOBJREC* rec);
char* flobjrec_get_type(FLOBJREC* rec);

Arguments FLOBJREC* REC in FLOBJREC whose components are


being obtained.

Returns VALUE
Remarks This set of flobjrec_get_…( ) functions allows the caller to obtain an attribute value
from an object definition.
While most of the return values are self-explanatory, a few require more detail.
Function flobjrec_get_chgbits( ) refers to a persistence attribute, namely whether to
set the change bit on when restoring the persistent value. The value is 1 for
set-the-change-bit and 0 for not.
Function flobjrec_get_perwhen( ) refers to a persistence attribute, namely whether to
save the object value based on time, on value change, or on domain persistence
settings. The legal values for this attribute are as follows
Value Meaning
0 No persistence of value.
1 Timed-based persistence.

252 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

2 Exception-based persistence.
7
3 Time-based and exception-based persistence.
4 Domain setting persistence.

PAK API Reference


Function flobjrec_get_tag( ) returns the base RTDB location. For arrayed objects,
this is the RTDB location for the object that has all dimensions equal to zero.

Library
Currently these entry points are implemented as macros, which, in some cases, return
a pointer to the private members of the FLOBJREC structure. These addresses must
be treated in a read-only manner.
See also “ct_find_obj”
“ct_open_obj”

MAKE _ FULL _ PATH


Combine the directory and file name into a full path name.
Syntax #include <flib.h>
void make_full_path(char* fpathp, char* dpathp, char* rpathp);

Arguments char* fpathp out Buffer where full path is returned.

char* dpathp in Base directory.

char* rpathp in Name of file to be added to directory.

Returns No values
Remarks The name of the file to be added to the directory may contain a relative path.
To maintain backward compatibility with previous releases, make_full_path( ) has
been retained in FLIB, but it is currently implemented using the fl_path( ) functions.
For new development, fl_path( ) functions should be used.
void make_full_path(pathp, dirp, filep)
{
NPATH *p1;
NPATH *p2;

p1 = fl_path_alloc( );

p2 = fl_path_alloc( );
if ( dirp == NULL )

FactoryLink Programmer’s Access Kit / 253


• PAK API REFERENCE LIBRARY



fl_path_cwd(p1);
else
fl_path_set_dir(p1, dirp);
fl_path_norm(p2, filep);
fl_path_add(p1, p2);
fl_path_sys(p1, pathp, MAX_PATH);

fl_path_free(p1);
fl_path_free(p2);
}
See also fl_path( ) and related functions

254 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

SPOOL
7
Spool a file or line.
Syntax #include <flib.h>

PAK API Reference


int spool (id_t id, char* flags, char* message,length;

Library
Arguments id_t id in Caller’s FactoryLink ID.
char* flags in Pointer to zero-terminated string.
String specifies file or line to be
printed, output device to be used
(Devices 1 through 5), type of data
(text or binary) to be expected, and
whether to delete the file (assuming
file, not line, is specified) after
successful printing. The following
recognized characters determine these
actions and may or may not display in
the string.
Char. Action
B Use binary mode in
reading and printing file
or line. Send Binary ON
command sequence before
beginning and Binary
OFF sequence upon
completion of print job.
D Delete file after
successful printing.
L Print line that follows
(message specifies line
to be printed).
# Use output Device
number # (where # stands
for digit from 1-5 with
default = 1).
char* message in Pointer to character string.

FactoryLink Programmer’s Access Kit / 255


• PAK API REFERENCE LIBRARY



int length in Length in bytes of the message Value
string. Used if both the L and B flags
are specified, which means the
message string is not necessarily
zero-terminated. It may contain any
ASCII characters, including 00
hexameter string.

Do not specify both the L and D flags in the same job request. Any other combination
is permitted. The order of characters in the flags string is immaterial.
Returns A signed integer (an int) that indicates the status of the job request. A value of zero
indicates the request has been accepted and queued by the SPOOL task. Any non-zero
value indicates some sort of error has occurred.
If the return value is negative, it was not received by the SPOOL task.
If the return value is positive, it was received by SPOOL but could not be processed.
Specifically, the return values have the following meanings

Return Value Meaning


-3 Request too long (flags and message strings combined exceed
128 bytes; program error is likely cause).
-2 Request not sent (caused by another task repeatedly tying up
channel to SPOOL task).
This can only be caused by a program error in one of the tasks
running on the system. The task waits a few seconds before
retrying the request. Should subsequent retry attempts fail, the
calling task prints an informative error message, such as Print
Spooler is temporarily unavailable, and takes appropriate action.
-1 Request sent to SPOOL task, but no reply was received.
The likely cause is the SPOOL task is not running. The task
prints an error message, such as Print Spooler not running, and
either quits or finds an alternate way to output its data.
0 Request accepted and queued by SPOOL task.
1 Request has a bad flags argument and was rejected, caused by
either a non-existent output device or a program error. If the
output device does not exist, no entry displays in the Print
Spooler Configuration table for the given device number.
2 Request could not be processed because the spool queue is full;
requesting task may wish to try again later.

256 / FactoryLink Programmer’s Access Kit


PAK API REFERENCE LIBRARY

Remarks The SPOOL function is related to the FactoryLink Print Spooler task.
Print Spooler Task 7
The Print Spooler processes job requests from other FactoryLink tasks running on the

PAK API Reference


system. These job requests specify either a line to be output or a file to be printed on a
printer or other output device or file.
The task initiating the job request must be an integral part of the request itself or

Library
specify what file or line is to be printed, which output device is to be used, and what
type of data (text or binary) printed.
When the SPOOL task receives a job request, it checks to see whether the designated
output device is processing earlier requests. If the output device is busy, it queues, or
spools, the current request. Otherwise, it processes the request immediately. Requests
queued for later processing are not prioritized. In effect, printing occurs on all output
devices simultaneously.
EXAMPLES
The following examples in C illustrate how to use the SPOOL function:
Example 1
int spool(id, “2", ”C:/CONFIG.SYS", 0);
MEANING: Print the indicated text file on Device 2.
Example 2
int spool(id, “L”, “** WARNING: Line pressure LOW. *”, 0);
MEANING: Print the indicated line on Device 1 (the default printer).
Example 3
int spool(id, B3, C:/{FLINK}/USR/TASK.DAT, 0);
MEANING: Print the indicated binary data file on Device 3.
Example 4
int spool(id, D, C:/SOURCE/TEST.LOG, 0);
MEANING: Print the indicated text file on Device 1 and delete the file afterwards.
In all of these examples, the value of int should be checked. The only possible return
values in these examples are -2 through 2.

FactoryLink Programmer’s Access Kit / 257


• PAK API REFERENCE LIBRARY


258 / FactoryLink Programmer’s Access Kit


Chapter 8





Application Objects API
Reference Library 8

API Reference Library


Application Objects
Application objects consists of a hierarchy of objects grouped together in a component object
model (COM) dynamically linked library (dll) named ApplicationObjects.dll. The purpose of
this document is to outline the functionality of each of these objects as well as the way in
which they fit together. When applicable, this guide refers to other objects and subsystems
provided with FactoryLink. These objects and subsystems are mentioned only to the extent of
their relevance to application objects.

Typically, application objects are programmatically used by getting an AOObjectServer object,


and then invoking methods on it to perform actions, such as creating instances of an
application object or looking up and returning a collection of application objects classes.

The objects contained in ApplicationObjects.dll may change. It is recommended that


programmers do not early bind to these objects. Early binding in Visual Basic is the process of
adding a reference to a dll and then using the objects it provides. All application objects
support an interface in Flink7Defns.tlb that can be guaranteed not to change. It is
recommended that programmers early bind to the type library Flink7Defns.tlb and then create
their objects using the ProgID. The ProgID of each object is ApplicationObjects.ObjectName
where ObjectName is the name of the object to be created. In Figure 8-1, the name of each
object is given in the top and the name of the Flink7Defns interface it supports is given below
it in parentheses. This example creates an AOObjectServer Object using its Flink7Defns
interface:

Dim mAOServer as IAOServer

Set mAOServer = CreateObject("ApplicationObjects.AOObjectServer")

This example requires a reference to Flink7Defns.tlb (FactoryLink Object Definitions).


Sometimes it will be necessary to early bind to an object. Usually, this is when the object
publishes events.

In application objects, the AOObjectServer (IAOServer) is the only object that publishes
events. If these are required, it will be necessary to early bind to the object. The above example
would be rewritten as:

Dim withevents mAOServer as AOObjectServer

Set mAOServer = new AOObjectServer

FactoryLink Programmer’s Access Kit / 259


• APPLICATION OBJECTS API REFERENCE LIBRARY



This example requires a reference to ApplicationObjects.dll (FactoryLink Object Definitions).
Note that subsequent releases of application objects may require that you modify and
recompile your program when you early bind to ApplicationObjects.dll.
Figure 8-1 Application Objects Hierarchy

AOObjectServer
(IAOServer)

IObjects IObject Instances Instances


(IAOIObjects) (IAOIObject) (IAOIObject) (IAOIObject)

AObjects AObject
(IAOObjects) (IAOObject)

AOTVariables AOTVariable AOTvarInstances


(IAOTVariables) (IAOTVariable) IAotvarInstances

AOOPCItems IAOOPCItem
(IAOOPCItems) (IAOOPCItem)

AOIObject Data AOProperties AOProperty


(IAOIObjectData) (IAOProperties) (IAOProperty)

Legend

Class Objects

Instance Objects

Both

Returned by
AOObjectServer

260 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOO BJECT S ERVER


8
AOObjectServer is the main object that contains the basic functionality of application objects.

API Reference Library


It is generally used to return other application objects and/or to perform operations on them.

Application Objects
Flink7Defns Interface: IAOServer

Public: Yes

Creatable: Yes

Properties

SilentMode A Boolean property which dictates whether the server displays error messages or
raises errors. This property has not yet been implemented.
Type: Boolean
Access: Read/Write
ParentHWnd A long that is the parent hwnd of the window which is controlling application objects.
This property is used to control the dialogs that Application displays.
Type: Long
Access: Read/Write
TagEdit A property of type EnumFL6TagExistOptions. The value of this property determines
what happens when a config object wants to create a tag, and the tag to be created
already exists, but with different properties. For example, if tagA is to be created as an
Analog and it already exists as a Float.
By default, when an object is created, the value is FL6TagAbortIfDiff. This causes a
prompt to appear allowing the user to choose to keep the tag (FL6TagKeepExisting)
or to modify the tag (FL6TagModifyExisting). This choice can be applied to all
objects if desired. The property is reset to FL6TagAbortIfDiff when the
ApplicationObject finishes, unless the user explicitly set it.
Type: Enumeration EnumFL6TagExistOptions
FL6TagAbortIfDiff = 0
FL6TagKeepExisting = 1
FL6TagModifyExisting = 2
Access: Read/Write

FactoryLink Programmer’s Access Kit / 261


• APPLICATION OBJECTS API REFERENCE LIBRARY



AttributeModFlags This property is used in conjunction with the TagEdit property to set more
complicated rules for tag modification. By default, a dialog is presented to the
user that will set this property.
The property is reset to 0 when the application object has finished unless the user has
explicitly set it. Note that this property has no effect if the TagEdit property is not set
to FL6TagModifyExisting (2)
Rules:
1 – Modify the Domain
2 – Modify the Type
4 – Modify the Dimension
8 – Modify the dimension only if it would make it larger
16 – Modify the Description
32 – Modify the Description only if it is blank
64 – Modify the persistence settings
128 – Modify the persistence change status settings
256 – Modify the default value
512 – Modify the default value only if it is blank
1024 – Modify the Message Length
2048 – Modify the Message Length only if it would make it larger

Type: Long
Access: Read/Write

Methods

Create Creates an application object, AOObject, initializes its properties, and returns it to the
user. Note that this does not actually save the object to the database. See the Update
method for information on how to save an application object.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

262 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

Name (Optional) String parameter used to set the name


property of the AOObject object returned. 8
Type: String

API Reference Library


Application Objects
Access: In

ObjectType (Optional) Used to set the ObjectType property of


the AOObject object returned. This property
determines what the Properties collection on the
AOObject is filled with. The default is
AOApplicationObject.
Type: Enumeration AOAppObjectType
AOFlinkRecord = 0
AOFlinkFile = 1
AOApplicationObject = 2
Access: In

DefaultNumberInstances (Optional) Used to set the DefaultNumberInstances


property of the AOObject object returned.
Type: Long
Access: In

InstanceBaseName (Optional) Used to set the InstanceBaseName


property of the AOObject object returned.
Type: String
Access: In

InstanceDescription (Optional) Used to set the InstanceDescription


property of the AOObject object returned.
Type: String
Access: In

InstanceKey (Optional) Used to set the InstanceKey property of


the AOObject object returned.
Type: String
Access: In

FactoryLink Programmer’s Access Kit / 263


• APPLICATION OBJECTS API REFERENCE LIBRARY



InstanceDisableFlagField (Optional) Used to set the InstanceDisableFlagField
property of the AOObject object returned.
Type: String
Access: In

GroupDescription (Optional) Used to set the GroupDescription


property of the AOObject object returned.
Type: String
Access: In

DisableVariable (Optional) Used to set the DisableVariable property


of the AOObject object returned.
Type: String
Access: In

IAddressOffset (Optional) Used to set the IAddressOffset property of


the AOObject object returned.
Type: Long
Access: In

IAddressMultiplier (Optional) Used to set the IAddressMultiplier


property of the AOObject object returned.
Type: Long
Access: In

Return Value: AOObject


GetAOObject Returns an application object, AOObject based on either name or ID.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

ID (Optional) Used to find the AOObject being


returned. Either the ID or Name parameters must be
passed into the call.
Type: String
Access: In

264 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

Name (Optional) Used to find the AOObject being


returned. Either the ID or Name parameters must be 8
passed into the call.

API Reference Library


Application Objects
Type: String
Access: In

Return Value: AOObject


UpdateAOObject Saves the application object into the database tables. Either creates a new application
object or updates an existing object. It returns the application object that was just
updated.
Parameters:

AO Application object being updated or created.


Type: String
Access: In/Out

Return Value: AOObject


DeleteObject Deletes an application object from the database, based on either name or ID. The
object must not be used by other objects or the call will fail.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

ID (Optional) Used to find the AOObject being deleted.


Either the ID or Name parameter must be passed
into the call.
Type: String
Access: In

Name (Optional) Used to find the AOObject being deleted.


Either the ID or Name parameter must be passed
into the call.
Type: String
Access: In

Return Value: None

FactoryLink Programmer’s Access Kit / 265


• APPLICATION OBJECTS API REFERENCE LIBRARY



ReturnTVariables Retrieves an AOTVariables containing all template variables used by an application
object.
Parameters:

FlappDir The FactoryLink Application Directory.


Type: String
Access: In
ParentID (Optional) ID of the application object. If omitted,
all template variables in the application are returned.
Type: String
Access: In

Return Value: AOTVariables


AddTVariableTo Creates or updates a template variable in the application object database. The new
Database variable AOTVariable is returned.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In
ID ID of the template variable. This parameter should
be an empty string for new template variables.
Type: String
Access: In
Name Name of the template variable.
Type: String
Access: In
Value Value of the template variable. This parameter is
obsolete and should be an empty string.
Type: String
Access: In

266 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

DataSourceString A packed string representing how the template


variable gets its values. The packed string is 8
obtained by creating a FlinkCDBObjects.cTemplate

API Reference Library


Replication object (Interface ItemplateReplication).

Application Objects
Once the replication properties are set on the object,
the ReplicationString property will return the
packed string.
PresentationString A packed string representing how the template
variable is presented to the user. The packed string
is obtained by creating a FlinkCDBObjects.c
TemplatePresentation object (Interface
ItemplatePresentation). Once the presentation
properties are set on the object, the
PresentationString property will return the packed
string.
Type: String
Access: In
Description Description of the template variable.
Type: String
Access: In

Return Value: AOTVariable


FindTVariable Finds and returns a template variable from an ID or a name.
Parameters:

FlappDir The FactoryLink Application Directory.


Type: String
Access: In
TVariableID (Optional) ID of the template variable. Either the
name or the ID must be present.
Type: String
Access: In
TVariableName (Optional) Name of the template variable. Either the
name or the ID must be present.
Type: String
Access: In

Return Value: AOTVariable

FactoryLink Programmer’s Access Kit / 267


• APPLICATION OBJECTS API REFERENCE LIBRARY



ReturnChildren Returns the child application objects that an application object contains. System-
defined IDs may also be used to return all the application objects in the system.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In
Container ID of the container application object. Only objects of
type AOApplicationObject(2) can act as containers.
In addition to accepting a valid application object ID, the
system defined ID, “ApplicationObjectsRoot”, can be
used which is the root-level container that contains all
objects.
Type: String
Access: In
ID ID of the application object whose children will be
returned. This object must exist within the container. In
addition to accepting a valid object ID, the following
constants can be used to specify all the objects in the
system.
“ApplicationObjectsConfigObjRoot" returns all config
objects in the system.
“ApplicationObjectsAppObjRoot" returns all Application
objects in the system.
“ApplicationObjectsFileObjRoot" returns all Application
objects in the system.
Type: String
Access: In
Member (Optional) A qualifier used to differentiate between
multiple objects of the same type. By default, the member
parameter is an empty string. If two instances of the same
object inside of an application object exist, the member
value of “” returns the children of the first instance and a
“2” returns the children of the second object.
Type: String
Access: In

Return Value: AObjects

268 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AddChildObject Adds an object to the container object.


Parameters: 8

API Reference Library


Flapp The FactoryLink Application Directory.

Application Objects
Type: String
Access: In
ContainerID ID of the container application object. This object
must exist. Currently, only objects of type
AOApplicationObject(2) can act as containers.
Type: String
Access: In
ParentID ID of the application object that will be the parent of
the new object. This object must exist. When adding
objects to the root level of the application object,
this ID will be the same as the container ID.
Type: String
Access: In
ParentMember (Optional) A qualifier used to differentiate between
multiple objects of the same type. By default, the
member parameter is an empty string. If two
instances of the same object inside of an application
object exist, the member value of “” refers to the
first object and “2” refers to the second object.
Type: String
Access: In
ChildID ID of the application object being added to the
container. This object must exist.
Type: String
Access: In
ChildMember (Optional) A qualifier used to differentiate between
multiple objects of the same type. By default, the
member parameter is an empty string. If two
instances of the same object inside of an application
object exist, the member value of “” refers to the
first object and “2” refers to the second object.
Type: String
Access: In
Return Value: None

FactoryLink Programmer’s Access Kit / 269


• APPLICATION OBJECTS API REFERENCE LIBRARY



SetChildObjects Adds Sub Objects to the container object. This method is obsolete. Use the
AddChildObject method.
Parameters:

AO The application object the objects will be added.


Type: (AOObject)
Access: In/Out
ParentChildIDList An variant Array dimensioned as Arr(4,n) where n
is the number of child objects to add. The first tag is
the ParentID, the second tag is the ParentMember,
the third tag is the Child ID parameter, and the
fourth tag is the Child member. Note that the second
tag is dimensioned from 0 to n where the 0th tag is
ignored. See AddChildObject.
Type: Variant
Access: In

Return Value: None


Return Returns a variant array of the Ids for all of the descendents of an object.
DescendentIDs Parameters:

AO The application object to retrieve the descendents


for. This should be a container application object.
Currently, only objects of type
AOApplicationObject(2) can act as containers.
Type: (AOObject)
Access: In/Out

ContainersOnly (Optional) A boolean specifying whether only


container objects will be returned. The default is
false. The return value will be a variant array
dimensioned as Array(n) where n will be the
number of descendents. The 0th tag is ignored in the
array.
Type: Boolean
Access: In

Return Value: Variant


TVarUsed Returns a boolean specifying whether the variable is used by any Application.

270 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

Parameters:
8

API Reference Library


Flapp The FactoryLink Application Directory.

Application Objects
Type: String
Access: In

VariableID (Optional) ID of the template variable. Either the


name or the ID must be present.
Type: String
Access: In

VariableName (Optional) Name of the template variable. Either the


name or the ID must be present.
Type: String
Access: In

Return Value: Boolean


DeleteTVar Deleted a template variable a boolean specifying whether the variable is used by any
Application. The variable must not be used by any objects. Returns true if the delete
was successful.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

VariableID (Optional) ID of the template variable. Either the


name or the ID must be present.
Type: String
Access: In

VariableName (Optional) Name of the template variable. Either the


name or the ID must be present.
Type: String
Access: In

Return Value: Boolean

FactoryLink Programmer’s Access Kit / 271


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOObjectUsed Returns a boolean specifying true if the object is used in any object.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

ObjectID (Optional) ID of the object. Either the name or the


ID must be present.
Type: String
Access: In

ObjectName (Optional) Name of the object. Either the name or


the ID must be present.
Type: String
Access: In

Return Value: Boolean


RegisterFor Returns an event object of type AOEvent that will receive application object events.
Events In VB, AOEvent must be declared with the keyword with events in order to receive
application object events.
Parameters:

Return Value: IDispatch


ReturnIChildren Returns an IObject that contains all of the instantiated child objects.
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

ID Instance ID of the instantiated object.


Type: String
Access: In

272 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

InstanceNumber Instance number of the name of the object. Either


the name or the ID must be present. 8
Type: String

API Reference Library


Application Objects
Access: In

Return Value: IObjects


ModifyIObject Takes an IObject that has been modified. Each IAOInstance in its IAOInstances
property has an IAOTVarInstances object. This object has a collection of
IAOTVarInstance objects. The newvalue property of each was initially set to chr$(0)
when the object was retrieved. To modify the object, set the newvalue to the desired
value. The ModifyIObject call looks for newvalues that are not chr$(0). When it finds
one, it modifies the application object instance. The instance ID of the top most
application object instance is returned.
Parameters:

AOIObj IObject to be modified.


Type: IObject
Access: In/Out

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: String


ReturnIObject Returns an IAOIObjectData object based on the Flapp, the instanceid, the instance
Data number, and the object type. If these parameters are not specified, it gets the
information from the IAOIObject.
Parameters:

InstanceNumber Instance number to be used to look up the


information.
Type: Long
Access: In

FactoryLink Programmer’s Access Kit / 273


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOIObj (Optional) IObject to be used to look up the
information. This information can be passed in
directly instead.
Type: IObject
Access: In

Flapp (Optional) The FactoryLink Application Directory.


If not used, it will be retrieved from the AOIObj
object.
Type: String
Access: In

InstanceID (Optional) Instance ID of the instantiated object. If


not used, it will be retrieved from the AOIObj
object.
Type: String
Access: In

ObjectType (Optional) Object type of the instantiated object. If


not used, it will be retrieved from the AOIObj
object.
Type: String
Access: In

Return Value: IAOIObjectData


CopyTemplate Copies a template variable. This can be between Flapps or within the same Flapp. The
Variable new variable is returned.
Parameters:

SourceFlapp The FactoryLink Application Directory that contains


the source template variable.
Type: String
Access: In

TVariableID (Optional) Template variable ID of the source


template variable. If not specified, TvariableName
must be specified.
Type: String
Access: In

274 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

DestinationName (Optional) New template variable name. If not


specified, a unique name will be generated. 8
Type: String

API Reference Library


Application Objects
Access: In

DestinationFlapp (Optional) The destination FactoryLink Application


Directory. If not specified, it is assumed to be the
same as the source.
Type: String
Access: In

Return Value: IAOTVariable


CopyApplication Copies an application object. This can be between Flapps or within the same Flapp.
Object Any objects or template variables contained by the source object or any of its children
are also copied. The new object is returned.
Parameters:

SourceFlapp The FactoryLink Application Directory that contains


the source object.
Type: String
Access: In

AOID (Optional) Object ID of the source object. If not


specified, the AOName must be specified.
Type: String
Access: In

AOName (Optional) Object name of the source object. If not


specified, the AOID must be specified.
Type: String
Access: In

DestinationName (Optional) New object name. If not specified, a


unique name will be generated.
Type: String
Access: In

FactoryLink Programmer’s Access Kit / 275


• APPLICATION OBJECTS API REFERENCE LIBRARY



DestinationFlapp (Optional) The destination FactoryLink Application
Directory. If not specified, it is assumed to be the
same as the source.
Type: String
Access: In

Return Value: IAOObject


RenameTemplate Renames a template variable. If Successful, true is returned, otherwise false is
Variable returned. All configuration containing this template variable will be updated.
Parameters:

Flapp The FactoryLink Application Directory that contains


the template variable to be renamed.
Type: String
Access: In

TVariableID Template variable ID of the source template


variable.
Type: String
Access: In

NewName New template variable name. This name should not


be used by a different template variable.
Type: String
Access: In

Return Value: Boolean


ReturnApplication Obsolete. Constants are no longer supported.
Constants
SetApplication Obsolete. Constants are no longer supported.
ConstantValue
GetApplication Obsolete. Constants are no longer supported.
ConstantValue

276 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

GetIObject Looks up and returns an application object Instance Object (IObject).


Parameters: 8

API Reference Library


Application Objects
Flapp The FactoryLink Application Directory that contains
the instance to be retrieved.
Type: String
Access: In

InstanceID (Optional) Instance ID of the object. If not specified,


ObjectName must be specified.
Type: String
Access: In

ObjectName (Optional) Instance name of the object. If not


specified, the InstanceID must be specified. The
name was stored based on the GroupBaseName
property of the application object.
Type: String
Access: In

ParentID (Optional) If specified, the ParentInstanceID


property of the IAOObject returned is set to this
value; otherwise, ParentInstanceID is set to “?”.
Type: String
Access: In

ParentNumber (Optional) If specified, the ParentInstanceNumber


property of the IAOObject returned is set to this
value; otherwise, ParentInstanceID is set to 0.
Type: String
Access: In

IncludeInstanceData (Optional) If the value is true, the IAOInstances


object is filled with instance data otherwise it is left
uninitialized. The property InstanceDataAvailable
on the IAOObject will be set to true if
IncludeInstanceData is true. The default is true. This
value should be set to false if instance data is not
needed.
Type: Boolean
Access: In

FactoryLink Programmer’s Access Kit / 277


• APPLICATION OBJECTS API REFERENCE LIBRARY



IncludeTVarData (Optional) If the value is true, the IAOTVarInstances
object in each IAOInstance object in the
IAOInstances property of the IObject returned is
filled application objects with template variable data
otherwise it is left uninitialized. The property
InstanceTVarDataAvailable on the IAOObject will
be set to true if IncludeTVarData is true. The default
is true. This value should be set to false if template
variable data is not needed. The IncludeInstanceData
parameter must be true to set IncludeTVarData to
true.
Type: Boolean
Access: In

IncludeOPCItemData (Optional) If the value is true, the IAOOPCItems


object in each IAOInstance object in the
IAOInstances property of the IObject returned is
filled with OPC Item data otherwise it is left
uninitialized. The property OPCItemDataAvailable
on the IAOObject will be set to true if
IncludeOPCItemData is true. The default is true.
This value should be set to false if OPC Item data is
not needed. The IncludeInstanceData must be true if
the IncludeOPCItemData is true.
Type: Boolean
Access: In

Return Value: IObject

278 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

CreateIObject Creates application objects instances in the target Flapp. If successful, the instance ID
of the top most object created is returned. 8
Parameters:

API Reference Library


Application Objects
Flapp The FactoryLink Application Directory to create
application object instances in.
Type: String
Access: In

ClassName (Optional) Class name of the object. If not specified,


the ClassID must be specified.
Type: String
Access: In

ClassID (Optional) Class ID of the object. If not specified,


the ClassName must be specified.
Type: String
Access: In

NumberOfInstances (Optional) Number of instances to create. If not


specified, the NumberOfInstances property of the
IAOObject is used.
Type: String
Access: In

ParentPath (Optional) The table that acts as the top most parent
record. This is used for the parent record of Config
Objects. The notation of a path is
FlappDir/Task/Domain/Table1!FieldInfo/
Table2!FieldInfo Note that forward slashes must be
used for the path and back slashes must be used in
the Flapp Directory.
Type: String
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: String

FactoryLink Programmer’s Access Kit / 279


• APPLICATION OBJECTS API REFERENCE LIBRARY



AddObject Creates application objects instances in the target Flapp. If successful, the instance ID
Instances of the top most object added to is returned.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be added.
Type: String
Access: In

InstantiatedObj (Optional) IObject to add to. If not specified, either


the Objectname or the InstanceID must be specified.
Type: IObject
Access: In

InstanceID (Optional) Instance ID of the object to be added. If


not specified, either the InstantiatedObj or the
Objectname must be specified.
Type: String
Access: In

ObjectName (Optional) Object Name of the object, this comes


from the Group Base Name Property of the Class. If
not specified, either the InstantiatedObj or the
InstanceID must be specified.
Type: String
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: String

280 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

InstanceIDFrom Returns the InstanceID from a fully qualified name.


QualifiedObject
Parameters: 8
Name

API Reference Library


Application Objects
Flapp The FactoryLink Application Directory that contains
the instance object.
Type: String
Access: In

ObjectName Qualified name of the object, IObject to add to. The


notation GroupBase1.InstanceKey1.
GroupBase2.InstanceKey2. Alternatively, the
notation GroupBase1(InstanceNumber1).
GroupBase2(InstanceNumber2) can be used.
Type: String
Access: In

Return Value: String


CreateIObject Creates a single application object instance. The application object instance object
Instance must already exist and have at least one instance. If the call succeeds, the instance ID
of the object will be returned.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be added.
Type: String
Access: In

ObjectName (Optional) Object name of the object, this comes


from the group base name property of the class. If
not specified, InstanceID must be specified.
Type: String
Access: In

InstanceID (Optional) Instance ID of the object to be added. If


not specified, the ObjectName must be specified.
Type: String
Access: In

FactoryLink Programmer’s Access Kit / 281


• APPLICATION OBJECTS API REFERENCE LIBRARY



InstanceNumber Instance number to create. If already exists or is 0,
the call will fail.
Type: Long
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: String


DeleteIObject Deletes an entire application object instance and all its children. The application
object instance object must already exist and have at least one instance. If the call
succeeds, the instance ID of the object will be returned.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be added.
Type: String
Access: In

InstantiatedObj (Optional) IObject to be deleted. If not specified,


either the Objectname or the InstanceID must be
specified.
Type: IObject
Access: In

InstanceID (Optional) Instance ID of the object to be deleted. If


not specified, either the InstantiatedObj or the
Objectname must be specified.
Type: String
Access: In

ObjectName (Optional) Object name of the object to be deleted,


this comes from the group base name property of the
class. If not specified, either the InstantiatedObj or
the InstanceID must be specified.
Type: String
Access: In

282 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true. 8
Type: Boolean

API Reference Library


Application Objects
Access: In

Return Value: None


DeleteIObject Deletes a single application object instance. The application object instance object
Instance must already exist.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be deleted.
Type: String
Access: In

ObjectName (Optional) Object name of the object, this comes


from the group base name property of the class. If
not specified, the instanceid must be specified.
Type: String
Access: In

InstanceID (Optional) Instance ID of the object to be added. If


not specified, ObjectName must be specified.
Type: String
Access: In

InstanceNumber Instance number to delete.


Type: Long
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: String

FactoryLink Programmer’s Access Kit / 283


• APPLICATION OBJECTS API REFERENCE LIBRARY



RemoveObject Removes application object instances from an application object instance object.
Instances Instance are removed from the end of the object. If the number of instances to be
removed is more than the number of instances, the object is completely removed.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be added.
Type: String
Access: In

NumberOfInstances Number of instances to be removed.


Type: String
Access: In

InstantiatedObj (Optional) IObject to be deleted. If not specified,


either the Objectname or the InstanceID must be
specified.
Type: IObject
Access: In

InstanceID (Optional) Instance ID of the object to be deleted. If


not specified, either the InstantiatedObj or the
Objectname must be specified.
Type: String
Access: In

ObjectName (Optional) Object Name of the object to be deleted.


This comes from the group base name property of
the class. If not specified, either the InstantiatedObj
or the InstanceID must be specified.
Type: String
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: None

284 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

RefreshIObject Refreshes all configuration by reading the data sources again and updating all objects.
Note that prompt template variables are not prompted; they must be changed through 8
the ModifyIObject method.

API Reference Library


Parameters:

Application Objects
Flapp The FactoryLink Application Directory that contains
the instance object to be refreshed.
Type: String
Access: In

InstantiatedObj (Optional) IObject to be refreshed. If not specified,


either the Objectname or the InstanceID must be
specified.
Type: IObject
Access: In

InstanceID (Optional) Instance ID of the object to be refreshed.


If not specified, either the InstantiatedObj or the
Objectname must be specified.
Type: String
Access: In

ObjectName (Optional) Object name of the object to be refreshed.


This comes from the group base name property of
the class. If not specified, either the InstantiatedObj
or the InstanceID must be specified.
Type: String
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: None

FactoryLink Programmer’s Access Kit / 285


• APPLICATION OBJECTS API REFERENCE LIBRARY



RefreshIObject Refreshes all configuration in a single instance by reading the data sources again and
Instance updating all objects. Note that prompt template variables are not prompted. These
must be changed through the ModifyIObject method.
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object to be refreshed.
Type: String
Access: In

InstantiatedObj (Optional) IObject to be refreshed. If not specified,


either the Objectname or the InstanceID must be
specified.
Type: IObject
Access: In

InstanceID (Optional) Instance ID of the object to be refreshed.


If not specified, either the InstantiatedObj or the
Objectname must be specified.
Type: String
Access: In

ObjectName (Optional) Object name of the object to be refreshed.


This comes from the group base name property of
the class. If not specified, either the InstantiatedObj
or the InstanceID must be specified.
Type: String
Access: In

InstanceNumber Instances number to be refreshed.


Type: Long
Access: In

ProvideFeedback (Optional) If set to true, will cause the feedback


events to be fired. The default value is true.
Type: Boolean
Access: In

Return Value: None

286 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

QualifiedObject Returns a fully qualified name from an instance ID.


NameFrom
Parameters: 8
InstanceID

API Reference Library


Application Objects
Flapp The FactoryLink Application Directory that contains
the instance object.
Type: String
Access: In
InstanceID Instance ID of the object.
Type: String
Access: In
NameSyntax Syntax to format the name in. Values can be
AOINInstanceName(0), which returns
GroupBase1.InstanceKey1.
GroupBase2.InstanceKey2 or
AOINInstanceArray(2) which returns
GroupBase1(InstanceNumber1).
GroupBase2(InstanceNumber2) can be used.
Type: Enumeration AOINameSyntax
Access: In
InstanceNumber Instances number of the last object. If not specified,
the name ends with a GroupBase; otherwise, it ends
with an instance number or key.
Type: Long
Access: In

Return Value: String


Return Returns all root instance objects for a Flapp.
InstantiatedRoot
Parameters:
Objects

Flapp The FactoryLink Application Directory that contains


the instance objects.
Type: String
Access: In

FactoryLink Programmer’s Access Kit / 287


• APPLICATION OBJECTS API REFERENCE LIBRARY



Return Value: IObjects
ExportApplication Returns all root instance objects for a Flapp.
Object
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance objects.
Type: String
Access: In
ClassName (Optional) Classname of the object. If not specified,
the ClassID must be specified.
Type: String
Access: In
ClassID (Optional) Class ID of the object. If not specified,
the ClassName must be specified.
Type: String
Access: In
AccessDatabaseFilePath (Optional) Path of the Access Database file to export
to. If not specified, a file prompt will appear. The file
must either not exist, in which case a blank Access
export database will be created, or it must be a valid
Access export database.
Type: String
Access: In

Return Value: None


ReturnBlank Returns a path to the file where the blank instance database resides.
InstanceFile
ImportApplication Imports all objects from a valid Access export database into the specified Flapp.
Objects
Parameters:

Flapp The FactoryLink Application Directory that contains


the instance object.
Type: String
Access: In

288 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

DatabaseFilePath (Optional) Path of the Access database file to import


from. If not specified, a file prompt will appear. The 8
file must be a valid Access export database.

API Reference Library


Application Objects
Type: String
Access: In
Return Value: None
ModifyIObject Takes an IObject that has been modified. Each IAOInstance in its IAOInstances
Instance property has an IAOTVarInstances object. A specific IAOInstance will be modified.
This object has a collection of IAOTVarInstance objects. The newvalue property of
each was initially set to chr$(0) when the object was retrieved. To modify the object,
set the new value to the desired value. The ModifyIObject call looks for new values
that are not chr$(0). When it finds one, it modifies the application object instance.
The instance ID of the top most application object instance is returned.
Parameters:

AOIObj IObject that contains the instance to be modified.


Type: IObject
Access: In/Out
InstanceKey (Optional) Used to find the Instance in the AOIObj.
If not specified, the InstanceNumber must be
specified.
Type: String
Access: In
ProvideFeedback (Optional) If set to true, will cause the feedback
events to be fired. The default value is true.
Type: Boolean
Access: In
Return Value: String
DeleteAllApp Deletes all the application object classes and template variables in the Flapp.
Objects
Parameters:

Flapp The FactoryLink Application Directory.


Type: String
Access: In

Return Value: None

FactoryLink Programmer’s Access Kit / 289


• APPLICATION OBJECTS API REFERENCE LIBRARY



Events

Most events processing is done by the event servers, FlinkcdbEvents and AppObjectEvents.
The AOObjectServer provides VB events relating to instantiation progress. It is necessary to
early bind to the AOObjectServer object, not IAOServer, to use these events.
BeginFeedBack Event notifying the user that an action is about to occur.
Parameters:

ServerAction Represents what type of action is about to occur. It


is of type AOServerAction that is an enumeration
that takes the following values.
AOSA_Create = 0
AOSA_Update = 1
AOSA_Delete = 2
AOSA_Test = 3

ProvideFeedBack Event notifying the user that an action has occurred and feedback can be given to the
user.
Parameters:

Description A string containing a description of what has


occurred.

Description2 A string containing more detail about what has


occurred.

Cancel A Boolean which, if set to true by the client


application, will cancel operation.

ProvideDetails Event notifying the user that an action has occurred and feedback can be given to the
user. This event provides more detail than providefeedback
Parameters:

Description A string containing a description of what has


occurred

EndFeedBack Event notifying the user that the action has finished

290 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

IO BJECTS
8
IObjects is a collection-based object that contains IObject object types.

API Reference Library


Application Objects
Flink7Defns Interface: IAOIObjects

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on a key or index. The key is the InstanceID property.
Type: IObject
Access: Read

Methods

Add Creates an IObject and adds it to the collection.


Parameters:

InstanceID Instance ID of the IObject. This is a GUID and


therefore is unique.
Type: String
Access: In/Out

InstanceBaseName Instance base name (group base name) of the


IObject.
Type: String
Access: In/Out

Flapp The FactoryLink Application Directory.


Type: String
Access: In/Out

FactoryLink Programmer’s Access Kit / 291


• APPLICATION OBJECTS API REFERENCE LIBRARY



AppObject Application object (IAOObject) used to create the
instance.
Type: IAOObject
Access: In/Out

ParentInstanceID Instance ID of the parent object.


Type: String
Access: In/Out

ParentInstanceNumber Instance number of the parent object.


Type: Long
Access: In/Out

InstanceDataAvailable Boolean stating whether the Iobject being added has


its IAOInstances object filled.
Type: String
Access: In

Return Value: Iobject


Remove Removes an Iobject based on a key from the collection.
Parameters:

vntIndexKey The key of the object to be removed. The InstanceID


is the key.
Type: Variant
Access: In/Out

292 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

IO BJECT
8
IObject is an object, which represents a group of instantiated application objects. Each IObject

API Reference Library


may contain a group of instance objects, which represent each instance within the group.

Application Objects
Flink7Defns Interface: IAOIObject

Public: Yes

Creatable: Yes

Properties

InstanceID Instance ID of the IObject. This is a GUID and therefore is unique.


Type: String
Access: Read/Write
ParentInstanceID Instance ID of the IObject’s parent.
Type: String
Access: Read/Write
ParentInstance Instance number of the IObject’s parent.
Number
Type: Long
Access: Read/Write
AppObject Application object (IAOObject) that was used to create the group of instances.
Type: IAOObject
Access: Read/Write
Flapp Application directory.
Type: String
Access: Read/Write
Instancebase Instance base name or group base name of the object.
Name
Type: String
Access: Read/Write
Instances Object of type IAOInstances, representing the collection of instances this IObject has
created. It is optional to fill this object with instance data. See the
InstanceDataAvailable to determine whether the instance data has been loaded.
Type: IAOInstances

FactoryLink Programmer’s Access Kit / 293


• APPLICATION OBJECTS API REFERENCE LIBRARY



Access: Read/Write
InstanceData A boolean indicating whether instance data has been loaded into the object.
Available
Type: String
Access: Read/Write
GroupDescription Group description of the object.
Type: String
Access: Read/Write
InstanceTVarData A boolean indicating whether each instance in the instances property has had template
Available variable data loaded into it. Instance data must have been loaded in order to be able to
load Tvar Data.
Type: Boolean
Access: Read/Write
OPCItemData A boolean indicating whether each instance in the instances property has had OPC
Available item data loaded into it. Instance data must have been loaded in order to be able to
load OPC item data.
Type: Boolean
Access: Read/Write

Methods

Return Returns a NodeClass Key, based on an application object type.


InstantiatedNode
Parameters:
Class

AOObjectType (Optional) ObjectType to use in the calculation. If


not specified, the ObjectType of the AppObject
property is used.
Type: Enumeration AOAppObjectType
AOFlinkRecord = 0
AOFlinkFile = 1
AOApplicationObject = 2
Access: In/Out

Return Value: String

294 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

I NSTANCES
8
Instances is a collection-based object that contains the instance type objects.

API Reference Library


Application Objects
Flink7Defns Interface: IAOInstances

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object, based on the key. The key is the InstanceKey property of the
instance object.
Type: Instance
Access: Read
ItemByIndex Returns the object, based on the instance number property of the instance object.
Type: Instance
Access: Read

Methods

Add Creates an Instance object and adds it to the collection.


Parameters:

InstanceKey Instance key of the instance.


Type: String
Access: In/Out

InstanceNumber Instance number of the instance.


Type: String
Access: In/Out

FactoryLink Programmer’s Access Kit / 295


• APPLICATION OBJECTS API REFERENCE LIBRARY



InstanceBaseName Instance base name of the IObject object where the
instances collection was created.
Type: String
Access: In/Out

InstanceDescription Description of the instance.


Type: String
Access: In/Out

InstanceDisabled A Boolean stating whether the instance has been


disabled.
Type: Boolean
Access: In/Out

Return Value: Instance


Remove Removes an instance, based on a key from the collection.
Parameters:

vntIndexKey Key of the object to be removed. The InstanceKey is


the key.
Type: Variant
Access: In/Out

Return Value: None


LastInstance Returns the last (highest) instance number in the instances collection.
Number
Return Value: Long

296 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

I NSTANCE
8
Instance is an object that represents a single instance of an application objects.

API Reference Library


Flink7Defns Interface: IAOInstance

Application Objects
Public: Yes
Creatable: Yes

Properties

InstanceNumber Instance number of the instance.


Type: Long
Access: Read/Write
InstanceBase Instance base name of the group of instances the instance object resides it.
Name
Type: String
Access: Read/Write
Instance Description of the instance.
Description
Type: String
Access: Read/Write
InstanceKey Key of the instance.
Type: String
Access: Read/Write
InstanceDisabled A Boolean stating whether the instance has been disabled.
Type: boolean
Access: Read/Write
TemplateVariable A collection-based object containing information about the instantiated template
Instances variables associated with the instance. This may not have been initialized.
Type: AOTVarInstances
Access: Read/Write
NewInstance A property that is initialized to chr$(0) when the instance is created. Set this property
Description to a new value and invoke the ModifyIObject method. The new description will be
written to the instance.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 297


• APPLICATION OBJECTS API REFERENCE LIBRARY



OPCItems A collection-based object that contains information about the OPC items associated
with the instance. This may not have been initialized.
Type: AOOPCItems
Access: Read/Write

Methods

DisplayName Returns a string, which is the instance key and, optionally, the instance description.
This method is obsolete.
Parameters:

UseDescription (Optional) Boolean stating whether to include the


description property in the display name.

298 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOTVAR I NSTANCES
8
AOTVarInstances is a collection-based object that contains AOTVarInstance object types.

API Reference Library


Application Objects
Flink7Defns Interface: IAOTVarInstances

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on the key. The key is the BaseID property of the
AOTVarInstance Object.
Type: Instance
Access: Read

Methods

Add Creates an AOTvarInstance object and adds it to the collection.


Parameters:

Name Name of the template variable.


Type: String
Access: In/Out

Value Value of the template variable.


Type: String
Access: In/Out

BaseID ID of the template variable the AOTVarInstance was


derived.
Type: String
Access: In/Out

Return Value: AOTVarInstance

FactoryLink Programmer’s Access Kit / 299


• APPLICATION OBJECTS API REFERENCE LIBRARY



Remove Removes an AOTVarInstance based on a key from the collection.
Parameters:

vntIndexKey Key of the object to be removed. The InstanceKey is


the key.
Type: Variant
Access: In/Out

Return Value: None


ReturnValue Returns a value of a template variable, based on the key. The key is the base ID or the
template variable ID the AOTVarInstance was derived.
Return Value: String

300 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOTVAR I NSTANCE
8
An AOTVarInstance is an object that represents a template variable that was used in an

API Reference Library


instance of an Application object.

Application Objects
Flink7Defns Interface: IAOTVarInstance

Public: Yes

Creatable: Yes

Properties

Value Value the template variable was assigned.


Type: String
Access: Read/Write
Name Name of the template variable.
Type: String
Access: Read/Write
BaseID ID of the template variable the instance was derived from.
Type: String
Access: Read/Write
NewValue When the object is initialized, this property is set to chr$(0). When it is set to a
different value and the ModifyIObject method of the AOObjectServer is invoked, the
new value will be used to modify the configuration.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 301


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOTVARIABLES
AOTVariables is a collection-based object that contains AOTVariable object types.

Flink7Defns Interface: IAOTVariables

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on the key. The key is the ID property of the AOTVariable
Object.
Type: AOTVariable
Access: Read

Methods

Add Creates a AOTVariable object and adds it to the collection.


Parameters:

Name Name of the template variable.


Type: String
Access: In/Out

ID (Optional) ID of the template variable. If not


specified, a new ID is generated. This is a GUID and
therefore is unique.
Type: String
Access: In/Out

Value (Optional) Value of the template variable.


Type: String
Access: In/Out

302 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

DataSource (Optional) A FlinkCDBObjects.cTemplate


Replication object (Interface ItemplateReplication) 8
configured with the replication properties.

API Reference Library


Application Objects
Type: ItemplateReplication
Access: In/Out

Presentation (Optional) A FlinkCDBObjects.cTemplate


Presentation object (Interface ItemplatePresentation)
configured with the Presentation properties.
Type: ItemplatePresentation
Access: In/Out

Description Description of the template variable.


Type: String
Access: In/Out

Return Value: AOTVariable


Remove Removes an AOTVariable based on a key from the collection.
Parameters:

vntIndexKey The key of the object to be removed. The ID is the


key.
Type: Variant
Access: In/Out

Return Value: None


TVarByName Returns an AOTVariable from the collection based on the Template variable Name.
Parameters:

Name Name of the variable to find.


Type: String
Access: In

Return Value: AOTVariable

FactoryLink Programmer’s Access Kit / 303


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOTVARIABLE
An AOTVariable is an object that represents a template variable that was used in an application
object class.

Flink7Defns Interface: IAOTVariable

Public: Yes

Creatable: Yes

Properties

Value Value of the template variable.


Type: String
Access: Read/Write
Name Name of the template variable.
Type: String
Access: Read/Write
ID ID of the template variable. This is a GUID and therefore is unique.
Type: String
Access: Read/Write
Presentation A presentation object, FlinkCDBObjects.cTemplatePresentation. This contains
information on how the template variable is presented to the user. Normally, only
prompt variables use it.
Type: ITemplatePresentation
Access: Read/Write
Replication A replication object, FlinkCDBObjects.cTemplateReplication. This contains
information on how the template variable receives its values.
Type: ITemplateReplication
Access: Read/Write
Description Description of the template variable.
Type: String
Access: Read/Write

304 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

VariableData Sets the variable’s data source. This property maps is passed directly into the
Source replication object and is provided so the user does not have to access the replication 8
object directly.

API Reference Library


Type: Enumeration EnumTVDataSource

Application Objects
TVKeyboard (0)
tvgenerated (1)
tvTextFile (2)
tvExcel = (3)
tvODBC = (4)
Access: Read/Write
Properties This is a collection based object of type AOProperties. It holds named value pairs that
map into the Replication object and presentation object. The names of the properties
it holds depend upon the VariableDataSource and VariablePromptPresentation values.
When the Variable Data Source and VariablePromptPresentation is set, the object is
filled with the pertinent properties from the two objects necessary to describe the
variable. These can be modified and are saved when the Update Method is invoked.
This object was provided to so that the user does not have to access the Replication
object and presentation object directly
Type: AOProperties
Access: Read/Write
VariablePrompt Sets the variable’s presentation style. This property maps is passed directly into the
Presentation presentation object and is provided so the user does not have to access the
presentation object directly.
Type: Enumeration EnumAOPresentationStyles
AOPTextBox (0)
AOPComboBox (1)
AOPListBox (2)
AOPCheckBox (3)
AOPRadio (4)
Access: Read/Write
Flapp The FactoryLink Application Directory.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 305


• APPLICATION OBJECTS API REFERENCE LIBRARY



Methods

ValidName Checks a name for validity and returns true if it is a valid name. This does not check
to see if the variable name already exists.
Parameters:

Name Name of the variable to find.


Type: String
Access: In
ErrorMessage (Optional) If included, an error message with the
reason the name is invalid is filled in.
Type: String
Access: Out

Return Value: Boolean


Update Updates a template variable in the database using the properties collection. Use the
AddVariableToDatabase method on the AOObjectServer object when using the
replication and presentation objects directly.
Parameters:

AOServer (Optional) An AOObjectServer variable. If not


included, a new AOObjectServer object is created.
Type: AOObjectServer
Access: In/Out

Return Value: None


Delete Deletes this template variable from the database.
Parameters:

AOServer (Optional) An AOObjectServer variable. If not


included, a new AOObjectServer object is created.
Type: AOObjectServer
Access: In/Out

Return Value: None

306 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOP ROPERTIES
8
AOProperties is a collection-based object that contains AOProperty object types.

API Reference Library


Application Objects
Flink7Defns Interface: IAOProperties

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on the key. The key is the Name property of the AOProperty
Object.
Type: AOProperty
Access: Read

Methods

Add Creates an AOProperty object and adds it to the collection.


Parameters:

Name Name of the property. The name of the property is


the key.
Type: String
Access: In/Out

Value Value of the template variable.


Type: String
Access: In/Out
Return Value: AOProperty

FactoryLink Programmer’s Access Kit / 307


• APPLICATION OBJECTS API REFERENCE LIBRARY



Remove Removes an AOProperty based on a key from the collection.
Parameters:

vntIndexKey Key of the object to be removed. The name is the


key.
Type: Variant
Access: In/Out

Return Value: None

308 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOP ROPERTY
8
An AOProperty is an object that represents a general named-value pair. The name property is

API Reference Library


given the name of the property, and the value is given the value.

Application Objects
Flink7Defns Interface: IAOProperty

Public: Yes

Creatable: Yes

Properties

Value Value of the property.


Type: String
Access: Read/Write
Name Name of the property.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 309


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOOPCI TEMS
AOOPCItems is a collection-based object that contains AOOPCItem objects types.

Flink7Defns Interface: IAOOPCItems

Public: Yes

Creatable: No

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on the key. The key is the Name property of the
AOOPCItem Object.
Type: AOOPCItem
Access: Read
MiscProperties This is a collection based object of type AOProperties. It holds named value pairs.
Currently the property holds the RecordPath and the RowID of the FactoryLink
record that the configuration object created.
Type: AOProperties
Access: Read/Write

Methods

Add Creates an AOOPCItem object and adds it to the collection.


Parameters:

ItemName OPC item name. In FactoryLink, this is the tag name


– the key for the collection.
Type: String
Access: In

310 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

ItemPropertyName Name of the configuration field that resulted in this


OPC item. In FactoryLink, this is the name of the 8
field in the AC file.

API Reference Library


Application Objects
Type: String
Access: In

ItemPropertyDescription Description of the configuration field that resulted


in this OPC item. In FactoryLink, this is the
description of the field in the AC file.
Type: String
Access: In

ItemDefinition Template variable, if any, that resulted in this OPC


item.
Type: String
Access: In

ItemType OPC item type. Only items of type FlinkTag(0) are


valid.
Type: OPCItemType
Access: In

Return Value: AOOPCItem


Remove Removes an AOOPCItem based on a key from the collection. The Key is the OPC
Item.
Parameters:

vntIndexKey The key of the object to be removed. The Name is


the key.
Type: Variant
Access: In/Out

Return Value: None

FactoryLink Programmer’s Access Kit / 311


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOOPCI TEM
An AOOPCItem is an object that represents an OPC item created indirectly through
application objects.

Flink7Defns Interface: IAOOPCItem

Public: Yes

Creatable: No

Properties

ItemProperty Description of the configuration field that resulted in this OPC item. In FactoryLink,
Description this is the description of the field in the AC file.
Type: String
Access: Read/Write
ItemProperty Name of the configuration field that resulted in this OPC item. In FactoryLink, this is
Name the name of the field in the AC file.
Type: String
Access: Read/Write
ItemName OPC item name. In FactoryLink, this is the tag name.
Type: String
Access: Read/Write
ItemType OPC item type. Only items of type FlinkTag(0) are valid.
Type: OPCItemType
Access: Read/Write
MiscProperties A collection-based object of type AOProperties. It holds named value pairs. Currently
this property is not used.
Type: AOProperties
Access: Read/Write
ItemDefinition Template variable, if any, that resulted in this OPC item.
Type: String
Access: Read/Write

312 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOO BJECTS
8
AOObjects is a collection-based object that contains AOObject object types.

API Reference Library


Application Objects
Flink7Defns Interface: IAOObjects

Public: Yes

Creatable: Yes

Properties

Count Returns the number of objects in the collection.


Type: Long
Access: Read
Item Returns the object based on the key. The key is the Name property of the
AOObject Object.
Type: AOProperty
Access: Read

Methods

Add Adds an existing AOObject to the collection.


Parameters:

AO AOObject to be added. The key is the AOObject ID.


Type: AOObject
Access: In/Out

Return Value: AOObject


Remove Removes an AOObject based on a key from the collection.
Parameters:

vntIndexKey The key of the object to be removed. The AOObject


ID is the key.
Type: Variant
Access: In/Out

Return Value: None

FactoryLink Programmer’s Access Kit / 313


• APPLICATION OBJECTS API REFERENCE LIBRARY



AOO BJECT
An AOObject is an object that represents an application object class.

Flink7Defns Interface: IAOObject

Public: Yes

Creatable: Yes

Properties

ID ID of the application object. The ID is a GUID.


Type: String
Access: Read/Write
ClassName Name object class. This should be unique across all object classes in the system.
Type: String
Access: Read/Write
Description Description of the class.
Type: String
Access: Read/Write
Variables The Tvariables the object uses. This is an object of type AOTVariables
Type: AOTVariables
Access: Read/Write
ObjectType Type of object. Each object type has its own set of unique properties in the properties
collection and performs its own set of actions. Once an object has been created and
saved, changing its object type is not supported.
Type: Enumeration AOAppObjectType
AOFlinkRecord (0)
AOFlinkFile (1)
AOApplicationObject (2)
Access: Read/Write
DefaultInstances The default number of instances the object should create when it is first run. This
parameter is overridden if the AOObjectServer method call contains a Number of
Instances parameter, although this will apply only to the top-level object affected by

314 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

the call. Sub objects will continue to use their DefaultInstances property when they
are created. This must be a string that can be converted to a long integer, a template 8
variable or a ?.

API Reference Library


Type: String

Application Objects
Access: Read/Write
Properties This is a collection-based object of type AOProperties. It holds named value pairs.
The names of the properties it holds depend upon the object type. When the object is
first created, usually with the Create method on the AOObjectServer Object, the
properties collection is filled with properties pertinent to that type of object. These
can be modified and are saved when the Update Method on the AOObjectServer
Object is invoked. Currently, the following properties are supported
Object Type
AOFlinkRecord (0):

ParentTablePath Path of the parent table, if there is one. It is in the


form task/Domain/table/table… For example,
al_def/SHARED/al_group/al_info
Type: String
Access: In/Out

ParentTableFields Field values that each parent table needs to have set.
It is in the form table=‘Value’, table=‘Value’. For
example, al_group=‘GRPNAM’, al_info=‘NUM’.
The field values can be template variables.
Type: String
Access: In/Out

RecordTablePath Path of the table to be written to. It is in the form


task/Domain/table/table… For example,
al_def/SHARED/al_group/al_info/al_rel
Type: String
Access: In/Out

FactoryLink Programmer’s Access Kit / 315


• APPLICATION OBJECTS API REFERENCE LIBRARY



RecordTableFields Field values that need to be written into the
application. It is in the form Field1=‘Value’,
Field2=‘Value2’ For example,
ATAG='{TagName}',COND='ON',MSG='{AlarmD
escription}',PRIO='1'. The field values can be
template variables.
Type: String
Access: In/Out

RecordFieldAttributes Field attributes that values need to be written into


the application. Currently, only FactoryLink tags
have attributes. It is in the form Field1=AttrString1,
Field2=AttrString2. For example,
ATAG=SHARED|''|1|'{AlarmDescription}'|''
||False|False|False|False| The AttrString is a packed
string representing Tag Attributes. This string can
encoded or decoded by using the AttributeString
property on the FlinkCDBObjects.cTagAttributes
object.
Type: String
Access: In/Out

DuplicateRecordAction Action to take when a record with the same values


in the fields specified in DuplicateRecordFields
already exists.
Type: Enumeration
AODuplicateRecordAction
AOAllowDuplicates = 0
AOLeaveAsIs = 1
AOUpdate = 2
Access: In/Out

DuplicateRecordFields Fields to examine for matching values to determine


whether there is a duplicate record. Format is
Field1,Field2. For example, ATag, AID
Type: String
Access: In/Out

316 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOFlinkFile (1):
8
DuplicateRecordFields Fields to examine for matching values to determine

API Reference Library


whether there is a duplicate record. Format is

Application Objects
Field1,Field2. For example, ATag, AID
Type: String
Access: In/Out
FileRecordPath Path of the file to create. It is in the form:
task/Domain/table!$FILENAME= filename.ext, for
example:
IMLP/SHARED/IMLTAGS!$FILENAME=
dplogsim.prg. This can property can have template
variables in it.
Type: String
Access: In/Out
FileExistsAction What to do when the file exists. The choices are to
replace the file or to leave it alone. If the
FileObjectCreation property is AOFOCSameFile
(0), this value must be AOFileReplace (1)
Type: Enumeration AOFileExistsAction
AOFileLeave (0)
AOFileReplace (1)
Access: In/Out
FileObjectCreation Where to place each file object instance. Valid
choices are in the same file, or in separate files.
Type: Enumeration AOFileObjCreation
AOFOCSameFile (0)
AOFOCSeparateFiles (1)
Access: In/Out
FileHeaderText Text to place at the beginning of each file. If each
instance is in separate files, this text is written into
each file. If each instance is in the same file, this text
is written once at the beginning. This can property
can have template variables in it.
Type: String
Access: In/Out

FactoryLink Programmer’s Access Kit / 317


• APPLICATION OBJECTS API REFERENCE LIBRARY



InstanceText Text to place in the file each time an instance is
created. This can property can have template
variables in it.
Type: String
Access: In/Out
FileFooterText Text to place at the end of each file. If each instance
is in separate files, this text is written into each file.
If each instance is in the same file, this text is
written once at the end. This can property can have
template variables in it.
Type: String
Access: In/Out

AOApplicationObject (2):
Currently, objects of type AOApplicationObject do not have custom properties filled
into their properties collection.
InstanceBase Base name of the group of instances. This property can take a template variable. If the
Name GroupBaseName exists, the instance numbers will be assigned, starting at the end of
the last instance, otherwise, the instance numbers will be assigned starting at 1.
Type: String
Access: Read/Write
Instance Description of the instance. This property can take template variables.
Description
Type: String
Access: Read/Write
InstanceKey Key of the instance. If this property is specified, it must be a template variable that
resolves to a unique key for the object.
Type: String
Access: Read/Write
InstanceDisable This field is obsolete.
FlagField
Type: String
Access: Read/Write
GroupDescription Description of the base group. This property can take template variables.
Type: String
Access: Read/Write

318 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

ClassClosedIcon (Optional) Specifies a custom closed icon for an application object class in the
FlinkTree. The icon must already exist in the tree or the custom icon must have been 8
added to the tree 16x16 icons directory. When adding an icon or bitmap to the

API Reference Library


directory, it is referred to by the filename without the extension (case sensitive). The

Application Objects
current editors do not have the ability to specify icons. Note that the update method
must be called on the AOObjectServer or on the AOObject to save the icon. This
property may have template variables in it.
Type: String
Access: Read/Write
ClassOpenedIcon (Optional) Specifies a custom opened icon for an application object class in the
FlinkTree. See ClassClosed Icon Property.
Type: String
Access: Read/Write
InstanceClosed (Optional) Specifies a custom closed icon for an application object group of instances
Icon in the FlinkTree. See ClassClosed Icon Property.
Type: String
Access: Read/Write
InstanceOpened (Optional) Specifies a custom opened icon for an application object group of
Icon instances in the FlinkTree. See ClassClosed Icon Property.
Type: String
Access: Read/Write
ParameterString Reserved for future use.
Type: String
Access: Read/Write
HTMLProperty (Optional) Specifies a user-defined Web Page to use to display properties. The page
Page should exist in the {Flapp}\AppObj directory.
Type: String
Access: Read/Write
DisableVariable An template variable (including the { }) that application objects check to see if it
matches the DisableValue to determine whether to disable the object or not.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 319


• APPLICATION OBJECTS API REFERENCE LIBRARY



DisableValue An value that application objects check to see if it matches the value of the
DisableVariable value to determine whether to disable the object or not.
Type: String
Access: Read/Write
IAddressOffset Used with the IaddressMultiplier to skip rows in the datasources. The row accessed is
given by the below. Note that the Block Offset properties in the editors do not show
these values. Instead they calculate the values they display. AddressIndex =
(IAddressMultiplier * InstanceNumber) + IAddressOffset
Type: Long
Access: Read/Write
IAddressMultiplier Used with the IaddressOffset to skip rows in the datasources. The row accessed is
given by the below. Note that the Block Offset properties in the editors do not show
these values. Instead they calculate the values they display. AddressIndex =
(IAddressMultiplier * InstanceNumber) + IAddressOffset
Type: Long
Access: Read/Write
Member (Optional) Used to differentiate between multiple classes of the same type. When the
object is added to the AOObjects, if there is an identical object, the member is used to
differentiate between them.
Type: String
Access: Read/Write
Flapp The Application Directory.
Type: String
Access: Read/Write

320 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

Methods
8
FindVariable Retrieves a template variable, based upon its name. The name is not case-sensitive.

API Reference Library


Application Objects
Parameters:

Name Name of the template variable.


Type: String
Access: In

Return Value: AOTVariable


TvarsUsedIn Returns a variant array containing the template variables used in the object’s
Config configuration. The array is dimensioned from 0 to n, where n is the number of
variables. The 0th dimension is ignored.
Parameters:

Name Name of the template variable.


Type: String
Access: In

Return Value: Variant


IsContainer Returns true if the object can function as a container. Currently only objects of type
AOApplicationObject (2) can be containers.
Return Value: Boolean
DisplayName Returns a concatenated string that can be used as an object description.
Parameters:

UseDescription (Optional) Boolean. If false, the description is the


classname, the member, enclosed in parentheses, if
the member is a non-empty string, and the table if
the object is of type AOFlinkRecord. If true, the
description is as above, but with the description
appended to it.
Type: Boolean
Access: In

FactoryLink Programmer’s Access Kit / 321


• APPLICATION OBJECTS API REFERENCE LIBRARY



UseBulletChar (Optional) Boolean. If false, when the description is
separated from the rest of the string by a -, otherwise
it is separated from the rest of the string by
CHR$(149) (The bullet when using the Tahoma
font).
Type: Boolean
Access: In

Return Value: String


ReturnAOClass Returns a string representing the object class.
Parameters:

AOObjectType (Optional) If missing, the object type property of the


AOObject is used; otherwise, it is used.
Type: variant
Access: In

Return Value: String


ValidName Checks a name for validity and returns true if it is a valid name. This does not check
to see if the variable name already exists.
Parameters:

Name Name of the object to check.


Type: String
Access: In
ErrorMessage (Optional) If included, an error message with the
reason the name is invalid is filled in
Type: String
Access: Out

Return Value: Boolean


VariablesAsList Returns a variant array containing the template variables used in the object. This
differs from TvarsUsedInConfig in that the list consists of all variables added to the
object, not just those used in configuration. The array is dimensioned from 0 to n,
where n is the number of variables. The 0th dimension is ignored.
Return Value: Variant

322 / FactoryLink Programmer’s Access Kit


APPLICATION OBJECTS API REFERENCE LIBRARY

AOIO BJ D ATA
8
The AOIObjData object is a special object available for instances of the configuration of file

API Reference Library


objects. It contains the information related to the configuration written by the object.

Application Objects
Flink7Defns Interface: IAOIObjData

Public: Yes

Creatable: Yes

Properties

InstanceID Instance ID of the IObject that created the configuration.


Type: String
Access: Read/Write
InstanceNumber Instance number of the instance that created the configuration.
Type: Long
Access: Read/Write
ObjectType Type of object that pertains to the data.
Type: Enumeration AOAppObjectType
AOFlinkRecord (0)
AOFlinkFile (1)
AOApplicationObject (2)
Access: Read/Write
CFGObjTable Table path used to write the configuration record. Only valid if the object type is
Path AOFlinkRecord.
Type: String
Access: Read/Write
CFGObjRowid Row ID of the configuration record. Only valid if the object type is AOFlinkRecord.
Type: String
Access: Read/Write

FactoryLink Programmer’s Access Kit / 323


• APPLICATION OBJECTS API REFERENCE LIBRARY



Table Short name of the table of the configuration record. Only valid if the object type is
AOFlinkRecord.
Type: String
Access: Read/Write
Flapp The FactoryLink Application Directory.
Type: String
Access: Read/Write
FilePath Path of the file that was created by the object. Only valid if the object type is
AOFlinkFile.
Type: String
Access: Read/Write
RecordPath Path of the file that was created by the object in cRecordPath format. Only valid if the
object type is AOFlinkFile.
Type: String
Access: Read/Write
OwnedByAO Owner of the file where the object is attached. Only valid if the object type is
AOFlinkFile.
Type: Enumeration AOFileOwner
AOFileOwnedByAO (0)
AOFileOwnedByOther (1)
Access: Read/Write

324 / FactoryLink Programmer’s Access Kit









Part III


















Configuration PAK





325



326 / FactoryLink Programmer’s Access Kit


Chapter 9





Configuration PAK
Architecture

O VERVIEW
The Configuration PAK (CFGPAK) is a collection of software libraries, C-language source
modules, and related documentation used to design and construct programs that directly
manipulate the configuration databases of a FactoryLink application.

Users generally configure tasks, or more specifically configuration databases, using the
Configuration Explorer. Configuration Explorer provides an interactive, graphical interface to
view, add, modify, and/or delete task information within a particular application. As the user
alters this task configuration, Configuration Explorer maintains the application integrity by 9
validating new records, creating undefined tags, and recording the location of tag references.

Configuration PAK
Programs created with CFGPAK are able to automate many of the operations found in
Configuration Explorer, saving users from manually importing and exporting configuration

Architecture
using Configuration Explorer. For example, a programmable logic controller (PLC) software
package could scan the active PLC addresses and enter corresponding read/write records into
that driver’s configuration databases.

This part assumes the reader is proficient at PAK task creation; therefore, it does not cover
material found in Part I.

Required Hardware and Software


CFGPAK is a FactoryLink option layered upon the FactoryLink Programmer’s Access Kit
(PAK). All requirements as stated in Chapter 1, “Programmer’s Access Kit Overview” apply to
the CFGPAK.

Installation
To install the Configuration Databases Programmer’s Access Kit, consult your operating
system’s installation guide regarding the installation of option media.

FactoryLink Programmer’s Access Kit / 327


• CONFIGURATION PAK ARCHITECTURE
• Configuration Architecture


C ONFIGURATION A RCHITECTURE
Some basic concepts must be understood to construct a program that manipulates
configuration databases. This chapter introduces the concepts used in writing a program
incorporating CFGPAK. Topics include:
• Configuration Storage
• Configuration Sessions
• Data Structure Hierarchy

The order of these topics parallels the order of the client task usage of these resources. The
layered CFGPAK architecture enforces this ordering.

For example, configuration tables cannot be accessed until a configuration session is


established.

Configuration Storage
FactoryLink applications consist of a heterogeneous set of configuration databases, drawing
files, and Math & Logic scripts. CFGPAK groups these storage entities into three types:
• Reserved configuration databases (CDBs)
• Task CDBs
• External configuration

CFGPAK provides access to the application’s reserved and task CDBs. Reserved CDBs are
those the system maintains internally and are indirectly altered by the user. FactoryLink
development tools, such as the Configuration Explorer, manage these tables behind the scenes.
The system tables are DOMAIN, OBJECT, TYPE, and XREF. Internal constraints apply to
these tables and the CFGPAK prevents invalid alterations of them.

Reserved Table Description

domain Holds the configured SHARED and USER domains for the
application.

object Holds the object or tag definitions.

type Holds the type for the RTDB segments within the kernel.

xref Holds the object cross-reference records.

328 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK ARCHITECTURE
Configuration Architecture

Task CDBs are the physical storage for the configuration entered into the panels of
Configuration Explorer. The information contained therein directs the task to its run-time
duties. The CDB itself is a relational database table. It consists of one or more records (or
rows), each comprised of several fixed-length fields.

Tasks are often configured by more than one CDB, and these CDBs are usually related in a
manner similar to SQL’s (Structured Query Language) definition of a primary key. A primary
key is a combination of one or more fields whose values form a unique identifier for each
record in the table. Given this primary key, a record from one table can be related to one or
more records in a secondary table. By including the primary key in records of a related table,
an association forms between the related table and the table owning the primary key. This is
known as a one-to-many relationship, and these types of relationships are a prevalent theme
throughout task CDB configuration.

External configuration refers to task configuration that cannot be adequately described by a


CDB. The most conspicuous example of this are the graphics files developers edit via the
Application Editor (APPEDIT). Currently, external configuration is implemented internally 9
and support for it is not provided as part of CFGPAK.

Note: The one exception to this is the tag modification routines, where

Configuration PAK
the renaming of a RTDB object or tag propagates to all affected drawings

Architecture
and logic scripts.

Configuration Sessions
Altering an application requires referencing both system as well as application files. As such, a
configuration session is an attachment to a given FactoryLink system (FLINK) and a given
FactoryLink application (FLAPP). From the FLINK, the CFGPAK obtains the definitions for
the configurable tasks declared in the various attribute catalogs (AC), key files, and include
files. From the FLAPP, the CFGPAK attaches to the actual CDBs that contain the
configuration data.

The main focus of CFGPAK users is to alter task CDBs. However, session-level overhead must
be processed prior to manipulating task configuration. Namely, the caller needs to navigate
through the available configurable options to locate the task(s) of interest. The session
facilitates this.

When establishing a configuration session, the session first determines what tasks are available
for configuration. Since the Attribute Catalog (AC) defines the structure of a task CDB, the
presence of an AC file within the session’s FLINK of an AC ultimately determines whether a
task can be configured. However, the presence alone does not determine whether the session
will see an AC.

When establishing a configuration session, the session determines AC availability via file:
{FLINK}/ac/ac2ct.map. Among other purposes, this map cross-references a CDB to the AC

FactoryLink Programmer’s Access Kit / 329


• CONFIGURATION PAK ARCHITECTURE
• Configuration Architecture


that defines it. The map file is generated during the system installation, and its contents are
derived from the union of all AC entries enumerated in the various titles files located in the
{FLINK}/ac directory.

A TITLES file is a text file containing a list of AC files. The TITLES file that Configuration
Explorer uses is located at {FLINK}/ac/titles. All AC files listed in the TITLES file must exist
in the {FLINK}/ac directory. If an AC file does not exist, the title’s entry is ignored, because
Configuration Explorer assumes the absent AC file is for an option that has not been
purchased.

Titles File AC File (SYS.AC)

sys.ac CT "sys" , "sys" , "System Configuration Information"


itimer.ac FIELD. . .
etimer.ac ...
END

Titles file to AC to CDB relationship

In the preceding figure, the TITLES file references AC file sys.ac, which in turn references the
configuration CDB named SYS. While this may seem fairly straight forward, it is a common
failure point where CFGPAK fails to locate its target CDB definition.

Common failure scenarios are


• An AC file is not referenced within the TITLES file and is not included in the AC-to-CT
map generation process.
• An AC file is referenced within the TITLES file is missing from the FactoryLink system.
Once again, CFGPAK ignores any entries for absent AC files.
• An AC file entry is missing from the AC-to-CT map file but is in the TITLES file. This
means the TITLES file was updated after the last time the map file was updated.

330 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK ARCHITECTURE
Configuration Architecture

Data Structure Hierarchy


The data structure hierarchy is best conveyed by defining who the players are and how they
interrelate. The data structures are:

Data Structure Description

flCfgSess Configuration session handle.

flCfgAC Attributes catalog handle.

flCfgCDB Configuration database (CDB) handle.

flCfgText Configuration database text file group handle.

flCfgDom Configuration database domain field handle.


9
flCfgSel Configuration database select field handle.

Configuration PAK
flCfgSeq Configuration database sequence field handle.

Architecture
flCfgFld Configuration database data field handle.

flCfgKey Configuration database data field key file handle.

The following graph depicts how these structures are linked to each other. The library services
provide entry points your CFGPAK program can navigate through this hierarchy with and
obtain the desired handle.

FactoryLink Programmer’s Access Kit / 331


• CONFIGURATION PAK ARCHITECTURE
• Configuration Architecture

Data Structure Hierarchy

flCfgSess

flCfgAC

flCfgCDB

flCfgCDB

flCfgAC
flCfgCDB

flCfgCDB
flCfgDom

flCFgText flCfgSel flCfgSel

flCfgSeq

flCfgFld flCfgFld

332 / FactoryLink Programmer’s Access Kit


Chapter 10





Configuration PAK Library
Services

This chapter describes the general purpose and usage for the services found within CFGPAK.
Detailed information regarding these functions can be found in the API reference library. This
chapter gives an overview of the following:
• Configuration Session API (flCfgSess)
• Attributes Catalog API (flCfgAC)
• Configuration Database API (flCfgCDB, flCfgSel, flCfgFld, flCfgKey)
• Configuration Text File API (flCfgText)
• Object Database API (flCfgObj, flCfgTag) 10
• Exception Handling

Config PAK Library


To illustrate the usage of each service, a thread of constructing a configuration utility for the
FactoryLink PAK Skeleton task runs though this chapter. When the PAK option is installed
into your FactoryLink system, the source/support files for the Skeleton task are placed in

Services
directory {FLINK}/src/examples/skeleton where {FLINK} is the location of the FactoryLink
system.

FactoryLink Programmer’s Access Kit / 333


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Session API


C ONFIGURATION S ESSION API

API Call Description

flCfgSess_open Opens/creates a configuration session.

flCfgSess_close Closes/destroys a configuration session.

flCfgSess_num_ac Gets the number of ACs within the session’s FLINK.

flCfgSess_nth_ac Gets/loads an attribute catalog (AC).

A configuration session provides the environment applications are modified through. Function
flCfgSess_open( ) requires two inputs to open a session: the FactoryLink system directory
{FLINK} and the application directory {FLAPP}. Upon successfully accessing system files in
the given {FLINK} and {FLAPP}, flCfgSess_open( ) returns a session handle.

Similar to Configuration Explorer, the application must exist in order to open a session.
Opening a session will not create an application.

Once a session is open, the next step towards accessing a configuration database is to locate its
schema definition. Since attribute catalogs (ACs) contain these definitions, the AC associated
with the target task needs to be located. To locate a particular AC, use functions
flCfgSess_num_ac( ) and flCfgSess_nth_ac( ) to iterate through all ACs known to the
session.

After the program completes accessing an application configuration, it should close its session.
Closing the session flushes all disk buffers, closes all open databases files, and releases the
memory attached to the session.

334 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Session API

Code Sample: Open/Close Session


int main(int argc, char *argv[])
{
flCfgSess *sess;
int rv;

/* Open a session - specify target FLINK & FLAPP */


rv = flCfgSess_open(getenv("FLINK"), getenv("FLAPP"), &sess);
if (rv != FLCFG_E_GOOD)
{
printf("Error(%d): unable to open edit session\n", rv);
return 1;
}
10
....

Config PAK Library


. Operate on session handler
....

Services
/* Close the session and exit */
flCfgSess_close(&sess);
return 0;
}

The program seeks out a particular AC after opening a session. In the case of the Skeleton task,
the program searches through the ACs known to the session for the one associated with task
SKEL.

FactoryLink Programmer’s Access Kit / 335


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Session API


Code Sample: Locating an AC
{
flCfgSess *sess;
flCfgAC *cfgacp;
flCfgCDB *cfgcdbp;
int k, j;
int rv;
....
. Open session “sess”
....
/* find the AC for the skeleton task */
cfgacp = NULL;
for (k = 0; k < flCfgSess_num_ac(sess); k++)
{
/* First, get a handle to an AC within the FLINK */
flCfgSess_nth_ac(sess, k, &cfgacp);
if (stricmp(flCfgAC_get_task(cfgacp), "SKEL") == 0) break;
cfgacp = NULL;
}
if (cfgacp == NULL)
{
printf("Cannot find skeleton task AC\n");
flCfgSess_close(&sess);
return 1;
}
/* Print out AC header information */
printf("AC :%s(%s) - %s\n",
flCfgAC_get_task(cfgacp),
flCfgAC_get_filename(cfgacp),
flCfgAC_get_title(cfgacp));
....
. Continue processing
....

336 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Attribute Catalog API

If the search for an AC fails, there are two likely causes. One is the AC file is not listed in the
text file: {FLINK}\ac\titles. If not, append an entry for the AC file to the TITLES file. The other
failure point is an entry for the AC file is missing from file: {FLINK}\ac\ac2ct.map. If so, type
and execute “acctmgr -c -d” at the system command prompt. This utility rebuilds the
AC-to-CT mapping for all AC files referenced within the various FactoryLink TITLES files.

A TTRIBUTE C ATALOG API

API Call Description

flCfgAC_get_filename Gets AC file name.

flCfgAC_get_guid Get the AC’s associated GUID.

flCfgAC_get_task Gets AC associated task.


10
flCfgAC_open_cdbs Opens/creates AC configuration databases.

Config PAK Library


flCfgAC_close_cdbs Closes configuration databases defined within an AC.

flCfgAC_get_title Gets AC title.

Services
flCfgAC_num_hdrcdb Gets number of ACs within the session FLINK.

flCfgAC_nth_hdrcdb Gets/loads an Attribute Catalog.

flCfgAC_num_text Get the number of text file groups defined within the AC.

flCfgAC_nth_text Get a handle to the requested text file group.

Attribute Catalogs contain descriptions (or schemas) of one or more configuration databases
(CDB) utilized by a particular task. As such, the AC structure also serves as a header to the
individual table definitions. Information about the AC file is available via access functions
flCfgAC_get_filename( ), flCfgAC_get_task( ), and flCfgAC_get_title( ).

What is an Attributes Catalog (AC)


As a header, the AC provides access to the top level configuration databases described within
it. Often times, these top-level CDBs maintain a one-to-many binding with other, lower-level
configuration databases. In such a case, data in one row of a header CDB may point towards
multiple, related entries in another CDB. The Skeleton task AC illustrates this.

FactoryLink Programmer’s Access Kit / 337


• CONFIGURATION PAK LIBRARY SERVICES
• Attribute Catalog API


Code Sample: The Skeleton Task AC
* Attribute Catalog for Skeleton Task
TASK "SKEL", "Skeleton FactoryLink Task" * Task name and Title
* CT Name Database Title
CT "skeltags", "skeltags", "Tag List"
EDIT DEFAULT * Default Editing
VALIDATE DEFAULT * Default validation
PANEL "", 100, 100, 700, 500 * Initial position
FIELD "TAG", "TAG", 48, 0, "", "", 0, 0, ""
HEADING "Tag Name", 96
DOMAIN "DOMAIN", 8
SELECT "TABLE_NAME", 16 * Primary Key
SEQ "TABLE_NBR", 10 * Sequence Number
INDEX "skeltags", "DOMAIN+TABLE_NAME+TABLE_NBR", 34 *Index file,key
END
* CT Name Database Title
CT "skeltrig", "skeltrig", "Trigger Tags"
EDIT DEFAULT * Default Editing
VALIDATE DEFAUL * Default validation
PANEL "", 200, 0, 700, 500 * Initial position
FIELD "TRIGGER", "TAG", 16, 0, "TYPED", "DIGITAL", 0,
HEADING "Trigger Tag", 96
FIELD "TABLE_NAME", "CHARACTER", 16, 0, "", "", 0, 0, ""
HEADING "Table Name", 96
RELATE "skeltags", "TABLE_NAME", "skeltags"
DOMAIN "DOMAIN", 8
SEQ "TABLE_NBR", 10 * Sequence Number
INDEX "skeltrig", "DOMAIN+TABLE_NBR", 18 * Index file, key
END

The preceding AC defines one header CDB named skeltrig. It is related to another CDB named
skeltags via the field TABLE_NAME. In other words, for every row within CDB skeltrig,
there will be zero or more rows in CDB skeltags with that same value in its TABLE_NAME
field.

338 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Attribute Catalog API

Note: Be aware that this is not the complete story since a row’s domain
is also part of the relation. However, this topic is better left till when
discussing the flCfgCDB( ) API.

Accessing CDBs Defined Within an AC


When the desired AC has been located, the configuration databases defined by that AC must
be opened in order to access their schemas and value contents. Function
flCfgAC_open_cdbs( ) opens, and optionally creates the CDB files if they do not yet exist, all
databases defined by the given AC.

Code Sample: Opening an AC’s CDBs


flCfgAC *cfgacp;
flCfgCDB *cfgcdbp;
int k, j;
10
int rv;

Config PAK Library


....
. Open session “sess” and locate the SKEL AC

Services
....
/* Open/create the tables defined within the SKEL AC */
if ((rv = flCfgAC_open_cdbs(cfgacp, 1)) != FLCFG_E_GOOD)
{
printf("Error(%d): unable to open SKELETON tables\n", rv);
flCfgSess_close(&sess);
return 1;
}
....
. Process the CDB
....
flCfgAC_close_cdbs(cfgacp);
....
. Continue processing
....

FactoryLink Programmer’s Access Kit / 339


• CONFIGURATION PAK LIBRARY SERVICES
• Attribute Catalog API


Functions flCfgAC_num_hdrcdb( ) and flCfgAC_nth_hdrcdb( ) allow the caller to step
through the top-level CDBs attached to the given AC. If the case of the skeleton task, the
hdrcdb count would be 1, the skeltrig database.

Code Sample: Stepping through an AC’s top-level CDBs


....
. Have obtained AC handle “cfgacp” the session
....
/* Interrogate the SKELETON configuration definition */
for (j = 0; j < flCfgAC_num_hdrcdb(cfgacp); j++)
{
flCfgAC_nth_hdrcdb(cfgacp, j, &cfgcdbp);
printf("\tCDB: %s - %s\n",
flCfgCDB_get_name(cfgcdbp),
flCfgCDB_get_title(cfgcdbp));
....
. Do something w/ the “hdrcdb”
....
}

340 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

C ONFIGURATION D ATABASE API

API Call Description

flCfgCDB_get_name Gets the name of the configuration database (CDB).

flCfgCDB_get_title Gets CDB title.

Up to this point, most of the work has been navigating through the application to locate the
configuration databases (CDB) to be accessed. Next comes manipulation of the CDB schemas
and contents via the CDB API. At the top level are access functions to get the CDB name and
title. Beyond that, things get more involved.

Interrogating a CDB Schema


10
API Call Description

Config PAK Library


flCfgCDB_get_domfld Gets CDB domain field.

Services
flCfgCDB_num_selfld Gets CDB number of select fields.

flCfgCDB_nth_selfld Gets handle to nth select field.

flCfgCDB_find_selfld Gets handle to select field with the given name.

flCfgCDB_get_seqfld Gets CDB sequence field.

flCfgCDB_num_fld Gets CDB number of fields.

flCfgCDB_nth_fld Gets handle to nth field.

flCfgCDB_find_fld Gets handle to field with the given name.

The schema of a CDB is split internally into four categories:


• Domain field
• Select fields
• Sequence field
• Data fields

FactoryLink Programmer’s Access Kit / 341


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Functions are provided that return handles to these components of the CDB’s schema. These
functions are:
• flCfgCDB_get_domfld( )
• flCfgCDB_nth_selfld( )
• flCfgCDB_get_seqfld( )
• flCfgCDB_nth_fld( )
We provide name-based search functions for component types where multiple fields may
apply.

Given a field handle, information about the field, such as name, title, or size, can be retrieved.
The handle is also used for setting field values when reading and writing CDB records. The
functions that manipulate the four components of a CDB are as follows:

Domain Field API

API Calls Description

flCfgDom_get_name Gets domain field name.

flCfgDom_get_size Gets domain field size.

flCfgDom_get_value Gets domain value for selected row.

flCfgDom_set_value Sets domain value for next selection or write.

Most CDBs associate their records with a domain. If a domain field is present, it is always
considered part of the selection criteria (see section “Reading Configuration from a CDB”).

342 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

Select Field API

API Calls Description

flCfgSel_get_name Gets select field name.

flCfgSel_get_size Gets select field size.

flCfgSel_get_value Gets select value for selected row.

flCfgSel_set_value Sets select value for next selection or write.

Selection fields exist for CDBs whose records depend on the values of another table (API
refers to these as relate CDBs). There may be many select fields, as many as required to
uniquely bind the CDBs records to an individual record in the header table.
10
Sequence Field API

Config PAK Library


API Calls Description

Services
flCfgSeq_get_name Gets sequence field name.

flCfgSeq_get_size Gets sequence field size.

flCfgSeq_get_value Gets sequence value for selected row.

flCfgSeq_set_value Sets sequence value for next selection or write.

Sequence fields maintain the order of row entry. Maintaining this order allows Configuration
Explorer to show CDB contents in a consistent manner, as opposed to potentially showing a
different ordering of rows between editing sessions. Almost all tables have a sequence field.

FactoryLink Programmer’s Access Kit / 343


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Field (Configuration Data) API

API Calls Description

flCfgFld_get_default_tagtype Get the field’s default tag type (for tag fields).

flCfgFld_get_default_value Get the field’s default value.

flCfgFld_get_flag Get the field’s flag existence

flCfgFld_get_high Get the field’s upper boundary for its values

flCfgFld_get_key_tagtypes Get the field’s key handle of valid tag types.

flCfgFld_get_key_values Get the field’s key handle of valid values.

flCfgFld_get_low Get the field’s lower boundary for its values.

flCfgFld_get_name Gets the field’s name.

flCfgFld_get_title Get the field’s title.

flCfgFld_get_type Get the field’s types (character, number, tag, etc.).

flCfgFld_get_size Gets the field’s size.

flCfgFld_get_value Gets the field’s value for selected row.

flCfgFld_set_value Sets the field’s value for next selection or write.

All CDBs have data fields. Data fields hold the task configuration information, as opposed to
the other fields that mainly serve to organize and/or sort the data.

To illustrate, consider the following function that prints the schema for a given handle to a
CDB to stdout. This example shows how to go through the fields that make up a table as well
as how to obtain the properties of each field.

Code Sample: Exploring a CDB schema


static void dump_cdb_schema(flCfgCDB *cfgcdbp, int indent)
{
flCfgDom *cfgdomp;
flCfgSel *cfgselp;
flCfgSeq *cfgseqp;

344 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

flCfgFld *cfgfldp;
int m, n;
flCfgCDB_get_domfld(cfgcdbp, &cfgdomp);
if (cfgdomp != NULL)
{
for (n = 0; n < indent; n++)
printf("\t");
printf("Domain: %s(%d) - Domain Field\n",
flCfgDom_get_name(cfgdomp),
flCfgDom_get_size(cfgdomp));
}
for (m = 0; m < flCfgCDB_num_selfld(cfgcdbp); m++)
{ 10
flCfgCDB_nth_selfld(cfgcdbp, m, &cfgselp);

Config PAK Library


for (n = 0; n < indent; n++)
printf("\t");

Services
printf("Select: %s(%d) - %s\n",
flCfgSel_get_name(cfgselp),
flCfgSel_get_size(cfgselp),
flCfgSel_get_title(cfgselp));
}
flCfgCDB_get_seqfld(cfgcdbp, &cfgseqp);
if (cfgseqp != NULL)
{
for (n = 0; n < indent; n++)
printf("\t");
printf("Sequence: %s(%d) - Sequence Field\n",
flCfgSeq_get_name(cfgseqp),
flCfgSeq_get_size(cfgseqp));
}
for (m = 0; m < flCfgCDB_num_fld(cfgcdbp); m++)
{

FactoryLink Programmer’s Access Kit / 345


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


flCfgCDB_nth_fld(cfgcdbp, m, &cfgfldp);
for (n = 0; n < indent; n++)
printf("\t");
printf("Field: %s(%d) - %s\n",
flCfgFld_get_name(cfgfldp),
flCfgFld_get_size(cfgfldp),
flCfgFld_get_title(cfgfldp));
}
}

Key Field API


The key field is a multi-language token used to identify common configuration selections. The
key field contains a validation list for field values and/or tag types. Searches can be made at the
label, token, or ID level.

API Call Description

flCfgKey_get_filename Gets the Key file’s name.


flCfgKey_num Gets the number of entries.
flCfgKey_nth_label Gets the nth key’s label (language-dependent).
flCfgKey_nth_id Gets the nth key’s numeric ID.
flCfgKey_nth_token Gets the nth key’s token string (language-dependent).

Code Sample
DLLEXPORT int flCfgKey_num(flCfgKey *cfgkeyp);
DLLEXPORT int flCfgKey_nth_label(flCfgKey *cfgkeyp, int n, char **label);
DLLEXPORT int flCfgKey_nth_token(flCfgKey *cfgkeyp, int n, char **token);
DLLEXPORT int flCfgKey_nth_id(flCfgKey *cfgkeyp, int n, long *id);

346 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

Reading Configuration from a CDB

API Call Description

flCfgCDB_ select_begin Begins a select of data from CDB.

flCfgCDB_ select_criteria Reads header’s select values into the relate CDB.

flCfgCDB_ select_current Reads values of currently selected row.

flCfgCDB_ select_first Moves to the first row that meets selection criteria.

flCfgCDB_ select_last Moves to the last row that meets selection criteria.

flCfgCDB_ select_next Moves to the next row that meets selection criteria.

flCfgCDB_ select_previous Moves to the previous row that meets selection criteria. 10
flCfgCDB_ select_rowno Moves to row with the given number.

Config PAK Library


flCfgCDB_ select_end Ends selection of data from CDB.

flCfgCDB_ num_relatecdb Gets number of CDBs related on the given CDB.

Services
flCfgCDB_ nth_relatecdb Gets handle of nth related CDB.

flCfgCDB_rowno Gets number for currently selected row.

At its simplest usage, reading data is a four-step sequence involving four functions:

1. Function flCfgCDB_select_begin( ) initiates the selection criteria and table locks.

2. A call to function flCfgCDB_select_first( ) takes the selection criteria and positions the
record pointer on the first row that matches that criteria.

3. Function flCfgCDB_select_next( ) is called as many times as needed to visit all rows that
match the selection criteria.

4. Finally, a call to flCfgCDB_select_end( ) releases all locks and resources held on behalf of
the selection.

Given the above, an overview of how selection criteria works within Configuration Explorer
and the CFGPAK is needed. All CDBs have a primary index (it is the first INDEX listed within
an AC CT definition). This index equates to the selection criteria. For header CDBs, the most

FactoryLink Programmer’s Access Kit / 347


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


common index expression is “DOMAIN+SEQ”. Ignoring sequence number (SEQ) for now,
selections against header CDBs are for all rows within a particular domain.

To illustrate, consider the following function dump_cdb_contents( ) that prints the contents of
a table to stdout, and all tables related to it, for a particular domain.

Code Sample: Reading the CDB’s contents


static void dump_cdb_contents(flCfgCDB *cfgcdbp, char *domain, int indent)
{
char fldbuf[256];
flCfgCDB *relcdbp;
flCfgDom *cfgdomp;
flCfgSel *cfgselp;
flCfgFld *cfgfldp;
int rv;
int m, n;
memset(fldbuf, 0, sizeof(fldbuf));
flCfgCDB_get_domfld(cfgcdbp, &cfgdomp);
<step 1> if ((rv = flCfgCDB_select_begin(cfgcdbp == FLCFG_E_GOOD)
{
if ((domain != NULL) && (cfgdomp != NULL))
<step 2a> flCfgDom_set_value(cfgdomp, domain);
<step 2b> rv = flCfgCDB_select_first(cfgcdbp);
}
while (rv == FLCFG_E_GOOD)
{
....
. Print out current record (use flCfgFld_get_value() for each field).
....
for (m = 0; m < flCfgCDB_num_relatecdb(cfgcdbp); m++)
{
flCfgCDB_nth_relatecdb(cfgcdbp, m, &relcdbp);
dump_cdb_contents(relcdbp, NULL, indent+1);
}

348 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

<step 3> rv = flCfgCDB_select_next(cfgcdbp);


}
<step 4> flCfgCDB_select_end(cfgcdbp);
}

In the code sample above , the CDB handle and selection domain are passed into the function.
The steps in this procedure include:

1 Attach to the table by beginning the selection.

2 Once the selection has begun, adjust the selection criteria for the given domain and then
position on the first record matching this criteria.

3 Step through all rows tied to that domain.

4 Once all rows are exhausted, the selection is ended.


10
In the previous code sample, the segment

Config PAK Library


for (m = 0; m < flCfgCDB_num_relatecdb(cfgcdbp); m++)
{
flCfgCDB_nth_relatecdb(cfgcdbp, m, &relcdbp);

Services
dump_cdb_contents(relcdbp, NULL, indent+1);
}

illustrates accessing data in another CDB that relates to the current row of the CDB being
processed. In the example, the related CDBs are iterated through, and for each, the dump
function is called recursively. What is not obvious here is that the selection criteria is being
implicitly defined for these related CDBs. When the selection for a related CDB is begun, the
select field values are set equal to the field values found in the header CDB. This is why NULL
is being passed as the domain value. When dumping related CDBs, use the domain value of the
header row.

FactoryLink Programmer’s Access Kit / 349


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Writing Configuration to a CDB

API Call Description

flCfgCDB_row_insert Inserts a row.


flCfgCDB_row_validate Validates set entries for a row.
flCfgCDB_select_delete Deletes currently selected row.
flCfgCDB_select_update Updates currently selected row.

Writing to a CDB almost equates to reversing the function call order of the selection (reading)
process. Prior to invoking the insert, the values associated with the field handles must be set to
the values to be inserted. These values are referenced by the writer functions such as function
flCfgCDB_row_insert( ) when it inserts a row.

Inserting a Row into a CDB

When a row is inserted, the values specified for the data fields are validated. The validation
performed is equivalent to the validation performed by Configuration Explorer. As with
Configuration Explorer, any tags referenced by the newly inserted row will have a
corresponding entry made in the cross-reference databases.

The sequence field has a unique property when a row is being inserted. Since the sequence
number exists to sort records according to their entry order, the field itself is generally hidden
from the user. As such, its value is automatically generated by Configuration Explorer. In
keeping with this theme, the insert routine will automatically assign the next appropriate
sequence value to the given row when the sequence value is set to zero. Unless your program
has a need to sort records in a particular order, use this auto-assignment mechanism as it will
prevent the inappropriate assignment of the same sequence number to two records.

Code Sample: Writing a Row into a Header CDB


static int skel_insert_table(flCfgCDB *skelp, char *dom, char *tbl, char *trig)
{
flCfgDom *domfldp;
flCfgSeq *seqfldp;
flCfgFld *tblfldp;
flCfgFld *trigfldp;
flCfgValErr valerr;
int rv;

350 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

/* Locate the needed table components */


if ((flCfgCDB_get_seqfld(skelp, &seqfldp) != FLCFG_E_GOOD)
|| (flCfgCDB_find_fld(skelp,"TABLE_NAME",&tblfldp) != FLCFG_E_GOOD)
|| (flCfgCDB_find_fld(skelp, "TRIGGER", &trigfldp) != FLCFG_E_GOOD)
|| (flCfgCDB_get_domfld(skelp, &domfldp) != FLCFG_E_GOOD))
{
return RV_ERROR;
}
flCfgDom_set_value(domfldp, dom);
flCfgSeq_set_value(seqfldp, 0); /* 0 means to autoset the seq # */
flCfgFld_set_value(tblfldp, tbl);
flCfgFld_set_value(trigfldp, trig);
rv = flCfgCDB_row_insert(skelp, &valerr); 10
switch (rv)

Config PAK Library


{
case FLCFG_E_GOOD:

Services
rv = RV_GOOD;
break;
case FLCFG_E_VALERR:
printf("Validation Error: %s(%s): %s\n",
flCfgValErr_get_fldname(&valerr),
flCfgValErr_get_fldvalue(&valerr),
flCfgValErr_get_valmsg(&valerr));
rv = RV_ERROR;
break;
default:
printf("Insert error: %d\n", rv);
rv = RV_ERROR;
break;
}
return rv;
}

FactoryLink Programmer’s Access Kit / 351


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


When inserting into a relate CDB, the values for the select fields must be set as well. While
this can be explicitly done by calling flCfgSel_set_value( ), it is best to use the values within
the relations. This guarantees records will not be inserted in relate CDBs that have no owning
row in the header CDB.

For example, if tag A_SEC is inserted into table SKELTAGS with an association to skeltrig
table TBL_A and no entry for table TBL_A exists in the skeltrig CDB, the inserted row will be
an orphan.

Function flCfgCDB_select_criteria( ) loads the domain and relate values for the currently
selection record of its header CDB(s) into the given CDB handle. In the following code
sample, the row insertion into CDB SKELTAG has its domain and table name fields set the
value of the row currently selected in the SKELTRIG CDB. As such, the row is guaranteed not
to be an orphan.

Code Sample: Writing a Row into a Relate CDB


static int skeltag_insert_row(flCfgCDB *skeltagp, char *tag)
{
flCfgFld *fldp;
flCfgValErr valerr;
int rv;
/* Get the handle to the tag field */
i f (flCfgCDB_find_fld(skeltagp, "TAG", &fldp) != FLCFG_E_GOOD)
return RV_ERROR;
/*
* Load in the selection values for the current row of SKELTAG's
* header CDB (SKELTRIG)
*/
if (flCfgCDB_select_criteria(skeltagp) != FLCFG_E_GOOD)
return RV_ERROR;
/* Set the tag value and insert the row */
flCfgFld_set_value(fldp, tag);
rv = flCfgCDB_row_insert(skeltagp, &valerr);
switch (rv)
{
case FLCFG_E_GOOD:
rv = RV_GOOD;

352 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

break;
case FLCFG_E_VALERR:
printf("Validation Error: %s(%s = %s): %s\n",
flCfgValErr_get_ctname(&valerr),
flCfgValErr_get_fldname(&valerr),
flCfgValErr_get_fldvalue(&valerr),
flCfgValErr_get_valmsg(&valerr));
rv = RV_ERROR;
break;
default:
printf("Insert error: %d\n", rv);
rv = RV_ERROR;
break; 10
}

Config PAK Library


return rv;
}

Services
Updating a Row Within a CDB

Row updates and selections are closely coupled operations. In order for a row to be updated, it
must first be selected. In other words, once the target row is selected, a call to function
flCfgCDB_select_update( ) modifies that row with the given values set within the CDB
handle. Of note here is an update may affect more the currently selected row. If one or more
fields of the update are related upon by another CDB, the update propagates to these relate
CDBs. This propagation preserves the relation between the updated row and those rows related
upon it.

In all cases, the affected cross-reference database entries are updated accordingly (additions,
deletions, and/or modifications).

Consider the following code sample. Once the record for the given domain and table name has
been selected, the new values are set within the skeltrig CDB handle and the update function
invoked. If only the trigger field value is different, then the update stops at modifying the
selected row. However, if the table name field value is different, all records in the related
skeltags CDB are also updated with the new table name.

For example, if the table name is switched from T1 to T2, then all rows in the skeltags CDB
whose table name value is T1 becomes T2.

FactoryLink Programmer’s Access Kit / 353


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Code Sample: Updating a CDB Row
static int skel_upd_table(flCfgCDB *skelp, char *dom, char *tbl,
char *newtbl, char *newtrig)
{
flCfgDom *domfldp;
flCfgFld *tblfldp;
flCfgFld *trigfldp;
char *tblval;
int tblsize;
int found;
int rv;
/* Locate the needed table components */
if ((flCfgCDB_find_fld(skelp, "TABLE_NAME", &tblfldp) !=
FLCFG_E_GOOD)
|| (flCfgCDB_find_fld(skelp, "TRIGGER", &trigfldp) != FLCFG_E_GOOD)
|| (flCfgCDB_get_domfld(skelp, &domfldp) != FLCFG_E_GOOD))
{
return RV_ERROR;
}
....
. Select the record that matches the given domain and table name (params ‘dom’+‘tbl’)
....
/* If the requested table exists, update it. */
if (found)
{
flCfgValErr valerr;
flCfgFld_set_value(tblfldp, newtbl);
flCfgFld_set_value(trigfldp, newtrig);
rv = flCfgCDB_select_update(skelp, &valerr);
switch (rv)
{
case FLCFG_E_GOOD:

354 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

rv = RV_GOOD;
break;
case FLCFG_E_VALERR:
printf("Validation Error: %s(fld=%s; val=%s): %s\n",
flCfgValErr_get_ctname(&valerr),
flCfgValErr_get_fldname(&valerr),
flCfgValErr_get_fldvalue(&valerr),
flCfgValErr_get_valmsg(&valerr));
rv = RV_ERROR;
break;
default:
printf("Update error: %d\n", rv);
rv = RV_ERROR; 10
break;

Config PAK Library


}
}

Services
else
{
rv = RV_ERROR;
}
....
. End the open selection held open for the update: flCfgCDB_select_end(skelp);
....
return RV_GOOD;
}

FactoryLink Programmer’s Access Kit / 355


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Deleting a Row from a CDB

As with row updates, row deletion and selection are coupled operations. For a row to be
deleted, it must first be selected. Function flCfgCDB_select_delete( ) removes both the
currently selected row and all rows in the relate CDBs tied to that row. Also, any tags
referenced within the deleted row(s) have their corresponding cross-reference database entries
removed.

Be aware that deleting a row positions the active selection onto the next row that meets the
selection criteria. As such, function flCfgCDB_select_current( ) is called to iterate through a
selection after a delete as opposed to the standard call to function flCfgCDB_select_next( ).

Consider the following code sample. It begins by selecting all tables associated with a given
domain. Once the selection has begun, it iterates through all the records, searching for the
given table name. Upon finding the target record, the procedure deletes the record and
proceeds onto the next record by calling function flCfgCDB_select_current( ) because the
delete call has already positioned it onto the next record.

Code Sample: Deleting a Row from a CDB


static int skel_delete_table(flCfgCDB *skelp, char *domain, char *tbl)
{
flCfgDom *domfldp;
flCfgFld *tblfldp;
char *tblval;
int tblsize;
int found;
int rv;

/* Locate the needed table components */


if ((flCfgCDB_find_fld(skelp,"TABLE_NAME",&tblfldp) != FLCFG_E_GOOD)
|| (flCfgCDB_get_domfld(skelp, &domfldp) != FLCFG_E_GOOD))
{
return RV_ERROR;
}
tblsize = flCfgFld_get_size(tblfldp)+1;
if ((tblval = (char*) malloc(tblsize)) == NULL)
return RV_ERROR;

356 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

if ((rv = flCfgCDB_select_begin(skelp)) == FLCFG_E_GOOD)


{
flCfgDom_set_value(domfldp, domain);
rv = flCfgCDB_select_first(skelp);
}

found = 0;
while (rv == FLCFG_E_GOOD)
{
flCfgFld_get_value(tblfldp, tblval, tblsize);
if (strcmp(tblval, tbl) == 0)
{
flCfgCDB_select_delete(skelp); 10
rv = flCfgCDB_select_current(skelp);

Config PAK Library


}
else

Services
{
rv = flCfgCDB_select_next(skelp);
}
}

flCfgCDB_select_end(skelp);
free(tblval);
return RV_GOOD;
}

FactoryLink Programmer’s Access Kit / 357


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Database API


Multi-User Access to a CDB

API Call Description

flCfgCDB_lock Establishes a read/write lock on a CDB.

flCfgCDB_unlock Releases lock held on CDB.

For the general case, the CFGPAK automatically handles the multi-user considerations that
arise when manipulating the application’s CDBs. However, cases exist where the locking and
releasing of one or more CDBs need to be explicitly managed by the CFGPAK program. To
illustrate, consider the following code sample.

Code Sample: CDB Locking to Support Selection by Row Number


flCfgCDB_lock(cfgcdbp, 0);

if ((rv = flCfgCDB_select_begin(cfgcdbp)) != FLCFG_E_GOOD)


return;
if (flCfgCDB_select_first(cfgcdbp) == FLCFG_E_GOOD)
flCfgCDB_rowno(cfgcdbp, &rowno);
flCfgCDB_select_end(cfgcdbp);
....
. Process <Block A> - Other processes may access CDB ‘cfgcdbp’.
....
if ((rv = flCfgCDB_select_begin(cfgcdbp)) == FLCFG_E_GOOD)
rv = flCfgCDB_select_rowno(cfgcdbp, rowno);
flCfgCDB_select_end(cfgcdbp);

flCfgCDB_unlock(cfgcdbp, 0);

In the preceding sequence, CDB locking prevents the row number from being invalidated by
the operations of another process. If the lock was not held over the life of both selections,
another process could be deleting and adding rows to the CDB during the time spent in <Block
A>.

358 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Database API

Consider the following sequence of events that may occur in the absence of a lock on the CDB.

1. The CFGPAK program begins executing the code sample and remembers row number 5.
The CFGPAK program then enters the time-consuming operation represented as <Block
A>.

2. Another user starts Configuration Explorer, selects the same CDB, and deletes the row tied
to number 5. The user then adds a new row, which Configuration Explorer assigns number
5 since it is now available.

3. The CFGPAK program returns from <Block A> and selects row 5.

The above sequence represents a failure, since the row selected by the CFGPAK program is not
the row it should be accessing. That row had been deleted and replaced by Configuration
Explorer.

Therefore, locking prevents other processes from changing the state of CDB your CFGPAK
program is operating on. However, be aware no other processes can access the CDB as long as 10
the lock is held; therefore, the lock should be held as long as required to protect the entire
transaction but released immediately upon completion.

Config PAK Library


Services

FactoryLink Programmer’s Access Kit / 359


• CONFIGURATION PAK LIBRARY SERVICES
• Configuration Text File API


C ONFIGURATION TEXT F ILE API

API Call Description

flCfgText_get_filespec Gets the file specifier for the text file group.

flCfgText_get_title Gets the text file group’s title.

FactoryLink application configuration not only includes databases, but text files as well.
Within an AC file, a file specifier defines the location and name of text files that are part of the
AC task’s configuration. This file specifier may reference a single file, or it may contain a
wildcard that references a group of files. The file specifier may also indicate that the text file
location depends on a domain.

Examples of currently existing configuration text files are math and logic procedure files,
report format files, and FLLAN group definition files.

Accessing Configuration Text Files

API Call Description

flCfgText_get_domain Gets the domain for the file selection.

flCfgText_get_filepath Gets the full path of the currently selected file.

flCfgText_select_begin Begins text file group iteration.

flCfgText_select_first Selects the first text file in the group.

flCfgText_select_next Selects the next text file in the group.

flCfgText_select_end Ends text file group iteration.

flCfgText_set_domain Sets the domain for the file selection.

The location and number of configuration text files varies depending on the file specifier. The
following table should assist in choosing the correct API functions to navigate a particular file
specifer.

360 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Configuration Text File API

Example File
Implied Location Appropriate API Sequence
Specifier

net/groups Fixed path and file name. flCfgText_get_filepath()

%s/cml/cml.mak Domain dependent path. flCfgText_set_domain()


Single file name. flCfgText_flCfgText_get_filepath()

%s/procs/*.prg Domain dependent path. flCfgText_set_domain()


Multiple file names. flCfgText_select_begin()
flCfgText_select_first()
flCfgText_get_filepath()
flCfgText_select_next() 10
flCfgText_select_end()

Config PAK Library


Once the file path has been retrieved, the program can use the standard file access routines to
read and write to these files (i.e. C programmers could use function fopen() to open the file).

Services

FactoryLink Programmer’s Access Kit / 361


• CONFIGURATION PAK LIBRARY SERVICES
• Object Database API


O BJECT D ATABASE API

API Call Description

flCfgObj_add Creates a tag definition.

flCfgObj_get_cdb Obtains session object CDB handle.

flCfgObj_select_begin Initiates selection against object CDB.

flCfgObj_select_current Reads currently selected tag definition.

flCfgObj_select_delete Deletes currently selected tag definition.

flCfgObj_select_end Ends selection against object CDB.

flCfgObj_select_first Reads the first tag definition in the object CDB.

flCfgObj_select_last Reads the last tag definition in the object CDB

flCfgObj_select_name Reads tag definition for a given tag name.

flCfgObj_select_next Reads the next tag definition in the object CDB.

flCfgObj_select_previous Reads the previous tag definition in the object CDB.

flCfgObj_select_update Updates currently selected tag definition.

One of the application’s reserved configuration databases, the object database, holds all the tag
definitions. The Object CDB API, which is essentially just another CDB, inherits most of its
entry points from the standard CDB API.

However, the Object CDB is a reserved table. As such, it is best the code does not assume
anything about the name or contents of the fields found within this table since these could
change in the future. Also, numerous, system integrity rules apply to the manipulation of
records found therein. In other words, keep with the flCfgObj API when accessing the object
database as opposed to using the lower-level CDB functions.

362 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Object Database API

Locating the Object CDB Handle


The first step in accessing the object database is to get a handle to its CDB. This handle is
obtained via function flCfgObj_get_cdb( ). Given a session handle, this function returns the
handle to that session’s object CDB.

The object CDB handle is a standard CDB handle. Any functions used to interrogate the
schema definitions, as described in the CDB API chapter, are applicable.

Tag Definition API

API Call Description

flCfgTag_create Allocates tag definition.

flCfgTag_clear_attrvals Clears all attribute values within tag definition.


10
flCfgTag_destroy De-allocates tag definition.

Config PAK Library


flCfgTag_get_attrval Gets value of tag definition attribute.

flCfgTag_get_attrvalp Gets pointer to value of tag definition attribute.

Services
flCfgTag_set_attrval Sets value of tag definitions attribute.

The transfer of definitions to and from the Object CDB API is conducted via a tag definition
data structure. As such, functions have been provided to create, manipulate, and destroy this
structure.

FactoryLink Programmer’s Access Kit / 363


• CONFIGURATION PAK LIBRARY SERVICES
• Object Database API


Tag definitions consist of many attributes, such as the tag name, its domain and its dimensions.
The get and set functions provide access to all of these attributes. Instead of providing a
separate access function for each function, each attribute is assigned an ID, which the caller
passes into the get and set functions. The requested attribute value is then returned as a string
(or a string is passed in when setting an attribute value).

Attribute ID Description

FLCFGTAG_ATTR_NAME Tag name

FLCFGTAG_ATTR_DOMAIN Tag domain

FLCFGTAG_ATTR_DIMEN Tag dimension maximums

FLCFGTAG_ATTR_TYPE Tag type

FLCFGTAG_ATTR_DESCR Tag description

FLCFGTAG_ATTR_DFLTVAL Tag default value

FLCFGTAG_ATTR_MSGLEN Tag message length

FLCFGTAG_ATTR_PERWHEN Tag persistence storage frequency

FLCFGTAG_ATTR_CHGBITS Tag persistence change bit initialization

Reading Tag Definitions


In general, selecting tag definitions differs little from selecting rows from any other table since
the four step sequence of selection begin, first, next, and end applies to the object table as well.

All selections begin with a call to function flCfgObj_select_begin( ). A subsequent call to


flCfgObj_select_first( ) selects the object CDB’s first tag definition. To select a particular tag,
substitute a call to flCfgObj_select_name( ) for flCfgObj_select_first( ). This selects the
object definition for the given name or the definition for the object, which falls alphabetically
immediately after the given name should the target name not exist.

In either case, subsequent calls to flCfgObj_select_next( ) steps the caller through all
remaining tag definitions. Once the selection is complete, a call to function
flCfgObj_select_end( ) closes the operation.

364 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Object Database API

Code Sample: Printing the Name of All Tags


static void dump_object(flCfgSess *sess)
{
flCfgTag *tagp;
flCfgCDB *objp;
char *tagname;
int rv;

if (flCfgObj_get_cdb(sess, &objp) != FLCFG_E_GOOD)


{
printf("Cannot find object CDB\n");
return;
}
10
if (flCfgTag_create(&tagp) != FLCFG_E_GOOD)

Config PAK Library


return;
if (flCfgObj_select_begin(objp) != FLCFG_E_GOOD)

Services
return;

rv = flCfgObj_select_first(objp, tagp);
while (rv == FLCFG_E_GOOD)
{
flCfgTag_get_attrvalp(tagp, FLCFGTAG_ATTR_NAME, &tagname);
printf("\t%s\n", tagname);
rv = flCfgObj_select_next(objp, tagp);
}
flCfgTag_destroy(&tagp);
flCfgObj_select_end(objp);
}

Writing Tag Definitions

Writing to the object CDB equates to adding, modifying, or deleting a tag definition.

FactoryLink Programmer’s Access Kit / 365


• CONFIGURATION PAK LIBRARY SERVICES
• Object Database API


Adding a Tag Definition

Function flCfgObj_add( ) creates a new tag according to the tag definition structure passed into
it. Validation of all aspects of the proposed definition is conducted prior to its actual insertion.
Specifics regarding any validation errors are returned via the flCfgValErr structure.

A member tag (i.e., x.raw) can be created if

1. the structured tag exists (i.e., x)

and

2. the member tag’s proposed definition has the same dimensions and domain as the
structured tag.

Code Sample: Adding a Tag Definition


....
. Previously create flCfgTag and flCfgValErr structures and locate the object CDB handle.
....
flCfgTag_set_attrval(tagp, FLCFGTAG_ATTR_NAME, name);
flCfgTag_set_attrval(tagp, FLCFGTAG_ATTR_DOMAIN, dom);
flCfgTag_set_attrval(tagp, FLCFGTAG_ATTR_TYPE, type);

rv = flCfgObj_add(objp, tagp, valerr);


switch (rv)
{
case FLCFG_E_GOOD:
rv = RV_GOOD;
break;
case FLCFG_E_VALERR:
printf("Validation Error: %s(fld=%s; val=%s): %s\n",
flCfgValErr_get_ctname(valerr),
flCfgValErr_get_fldname(valerr),
flCfgValErr_get_fldvalue(valerr),
flCfgValErr_get_valmsg(valerr));
rv = RV_ERROR;
break;

366 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Object Database API

default:
printf("Insert error: %d\n", rv);
rv = RV_ERROR;
break;
}

....
. Subsequently destroy flCfgTag and flCfgValErr structures and continue work.

....

Updating a Tag Definition

Function flCfgObj_select_update( ) modifies a tag definition. As with updating a row in a


CDB, the tag definition must be selected prior to the update call.
10
This appears straight forward, but it is not. On one hand, changing non-core attributes is no
different than any other CDB update, since the change only affects the one row in the object

Config PAK Library


database. On the other hand, changing a core attribute, namely its dimension, domain, name, or
type, requires application wide modifications.

Services
To illustrate the costs of changing an object’s core attributes, consider the effects of changing
an object’s name. Changing an object’s name is expensive since every reference to that object
must be physically updated. For example, if the reference to the object is within a task’s CDB,
the row in the task CDB must be modified. Furthermore, if that object is referenced by a Math
& Logic script (also known as a PRG), all references in the script must be located, altered and
validated. This case raises ambiguous situations, such as what if the new object name conflicts
with the script’s local variable. Drawing files are another problem area For example, if a
template was used to form the object reference, a decision to either reject the new name or drop
the template association needs to be made.

The point is that changing an object’s core attributes is prone to being rejected for a wide
variety of reasons. Furthermore the operation may generate warnings that require the user to
decide whether to commit or rollback the change, such as whether to change the tag name even
though a Math & Logic script does not validate. To communicate errors and warnings between
the internals of the flCfgObj_select_update( ) function and the invoking CFGPAK program, a
series of OK-CANCEL boxes are requested via the message box callback (for more
information, see function flCfg_set_msgbox_handler( )). The responses to these dialogs
control what action the update takes.

Note: Member tag names cannot be a source or target name string for a
tag rename. For example, y cannot be renamed to x.raw, nor can x.raw be
renamed to y.

FactoryLink Programmer’s Access Kit / 367


• CONFIGURATION PAK LIBRARY SERVICES
• Object Database API


Code Sample: Changing the Name of a Tag
....
. Previously create flCfgTag and flCfgValErr structures and locate the object CDB handle.
....
if (flCfgObj_select_begin(objp) != FLCFG_E_GOOD)
return RV_ERROR;

rv = flCfgObj_select_name(objp, tagname, tagp);


if (rv == FLCFG_E_GOOD)
{
flCfgTag_set_attrval(tagp, FLCFGTAG_ATTR_NAME, newname);
rv = flCfgObj_select_update(objp, tagp, valerr);
switch (rv)
{
case FLCFG_E_GOO
rv = RV_GOOD;
break;
case FLCFG_E_VALERR:
printf("Validation Error: %s(fld=%s; val=%s): %s\n",
flCfgValErr_get_ctname(valerr),
flCfgValErr_get_fldname(valerr),
flCfgValErr_get_fldvalue(valerr),
flCfgValErr_get_valmsg(valerr));
rv = RV_ERROR;
break;
default:
printf("Rename error: %d\n", rv);
rv = RV_ERROR;
break;
}
}
else

368 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Object Database API

{
printf("Unable to locate tag to rename: %s\n", tagname);
rv = RV_ERROR;
}
flCfgObj_select_end(objp);
....
. Subsequently destroy flCfgTag and flCfgValErr structures and continue work.
....

Deleting a Tag Definition

Function flCfgObj_select_delete( ) deletes a tag definition. As with deleting a row from a


CDB, the tag definition to delete must be selected prior to the delete call. Before the tag is
deleted, the function verifies that no references to that tag exist. If references exist, the deletion
is rejected. 10
Structured tags further constrain the behavior of this function. If the tag being deleted is

Config PAK Library


structured with one or more member, there must not be any references to the member tags, or
the deletion will be rejected (if tag x is structured with a member tag x.raw, then a reference to
tag x.raw prevents tag x from being deleted). Similarly, if no references exist to the structured

Services
tag or its members, then the removal of the structured tag deletes the member tags.

Code Sample: Deleting a Tag Definition


....
. Previously create flCfgTag structure and locate the object CDB handle.
....
if (flCfgObj_select_begin(objp) != FLCFG_E_GOOD)
return RV_ERROR;
rv = flCfgObj_select_name(objp, tagname, tagp);
if (rv == FLCFG_E_GOOD)
rv = flCfgObj_select_delete(objp);
else
rv = RV_ERROR;
flCfgObj_select_end(objp);
....
. Subsequently destroy the flCfgTag structures and continue work.
....

FactoryLink Programmer’s Access Kit / 369


• CONFIGURATION PAK LIBRARY SERVICES
• Exception Handling API


E XCEPTION H ANDLING API
CFGPAK reports exceptions with return codes; however, return values often lack sufficient
precision to report why the call failed. Hence, additional information about a failure can be
obtained via the exception hooks discussed in this chapter.

CFGPAK exception handling consists of the following components:


• Return Codes and Error Messages
• Validation Errors

Return Codes and Error Messages


Whenever a CFGPAK function fails, it returns an error code as to the cause of the failure.
Exception codes to expect from a function call are listed within the function’s description in
Chapter 12, “Configuration PAK API Reference Library.”

CFGPAK Error Codes

Error Code Definition Value Description

FLCFG_E_GOOD -0 No error occurred.

FLCFG_E_INTERNAL -1 General failure indicator.

FLCFG_E_INVARG -2 Invalid argument passed to function.

FLCFG_E_MEMORY -3 Memory allocation.

FLCFG_E_MULTSESS -4 Attempt to open more than one session.

FLCFG_E_NOFILE -5 File/CDB not found.

FLCFG_E_NOACLOAD -6 AC not loaded prior to function call.

FLCFG_E_CDBCLOSED -7 Cannot access closed CDB.

FLCFG_E_ENDOFSEL -8 No more rows match selection criteria.

FLCFG_E_NOTFOUND -9 Cannot find the requested handle.

FLCFG_E_ISOPEN -10 Attempt to open an already open CDB.

FLCFG_E_ACLOAD -11 Error occurred loading or parsing AC file.

370 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Exception Handling API

Error Code Definition Value Description

FLCFG_E_ACMAP -12 Error occurred loading or parsing AC2CT map


file. Executing utility ACCTMGR may fix this.

FLCFG_E_APPOPEN -13 Cannot open application system CDBs.

FLCFG_E_BADRELATE -14 Cannot find table/field for select relation.

FLCFG_E_DBERROR -15 Internal physical database I/O failure.

FLCFG_E_DBLOCK -16 Unable to lock CDB.

FLCFG_E_VALERR -17 Validation error on insert/update.

FLCFG_E_SELBEGUN -18 Cannot perform operation when a selection on


given CDB has already begun. The select must be 10
ended first.

Config PAK Library


FLCFG_E_NOSELBGN -19 Operation requires a begin selection.

FLCFG_E_NOSSEL1ST -20 Operation requires prior select of first row.

Services
FLCFG_E_INVUPD -21 Relate CDBs cannot update domain/select fields.

FLCFG_E_RSVDTBL -22 Illegal operation for reserved table.

FLCFG_E_REFEXIST -23 Illegal request for references to object exists.

FLCFG_E_TAGEDIT -24 Error encountered during tag definition update.

CFGPAK Error Messages

API Call Description


flCfg_set_msgbox_handler Set function to direct error and warning messages.

When internal errors and warnings are encountered, additional, textual messages may be
written to stdout. These strings provide more detailed information regarding the failure than
can be provided by an error code.

However, it is likely that sending output to stdout is inappropriate for the application utilizing
CFGPAK. For example, a GUI program may re-direct these outputs to a message box. To that

FactoryLink Programmer’s Access Kit / 371


• CONFIGURATION PAK LIBRARY SERVICES
• Exception Handling API


end, function flCfg_set_msgbox_handler( ) allows a callback function to be installed directs
all message to the given function pointer.

Furthermore, for more exotic activities, input from the user is necessary to direct the lower
level CFGPAK functions how to proceed.

Code Sample: Prototype for the Message Box Callback

typedef int (*FLCFG_MBH)(char *title, char *msg, int boxtype);

Once a callback handler is set, all error message are passed to it. The arguments consist of a
title string, a message string, and a box type request. Message box type requests are:

Box Type ID Description

FLCFG_MBOX_OK Single button (OK) message box.

FLCFG_MBOX_OKCANCEL Dual button (OK & CANCEL) message box.

The callback function should return the ID of the button pressed. The button IDs are:

Box Type ID Description

FLCFG_MBID_OK Single button (OK) message box.

FLCFG_MBID_CANCEL Dual button (OK & CANCEL) message box.

If no message box callback is set, the default CFGPAK message box handler writes the title
and message to stdout, and then returns FLCFG_MBID_OK for OK message boxes or
FLCFG_MBID_CANCEL for OK-CANCEL message boxes.

372 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK LIBRARY SERVICES
Exception Handling API

Validation Error Reporting for Inserts and Updates

API Call Description

flCfgValErr_create Creates validation error structure.

flCfgValErr_clear Clears validation error structure.

flCfgValErr_destroy Destroys validation error structure.

flCfgValErr_get_ctname Gets validation error CDB (CT) name.

flCfgValErr_get_ fldname Gets validation error field name.

flCfgValErr_get_fldvalue Gets validation error field value.

flCfgValErr_get_valmsg Gets validation error field message. 10


When inserting or updating a row, the values contained therein may not be legal. Legality is

Config PAK Library


determined either by restrictions specified in the CDB definition within the AC file or by an
external validation routine. Should the prospective value of a field fail to validate, the insert or

Services
update call returns an error. When a validation failure occurs, the validation error structure
passed into the insert function is filled with details about the nature of the violation. This
information includes the violated field name, the offending value, and a message stating what
is wrong with the value.

For example, if a field is designated as a NUMBER type with a valid range of 0 to 100, an
attempt to insert a row with the value of 256 will be rejected. In this case, the function returns
code FLCFG_E_VALERR, and the validation error structure contains specifics about the
failure.

FactoryLink Programmer’s Access Kit / 373


• CONFIGURATION PAK LIBRARY SERVICES
• Exception Handling API

374 / FactoryLink Programmer’s Access Kit


Chapter 11





Configuration Database
ActiveX Component

The FactoryLink CFGPAK ActiveX control (OCX) exposes the functions of the FactoryLink
CFGPAK C library as methods and events accessible to OLE containers that support scripting,
such as Microsoft's Visual Basic.

To install and register the CFGPAK component and its DLLs, run the installation executable
located at {FLINK}\flcfgocx\flcfgocx.exe. The target directory for the installation should be
the FactoryLink directory itself.

U SING CFGPAK OCX 11


All CFGPAK OCX methods are exposed at the root level of the object. This allows the OCX
interface to closely mirror the C API, save for minor adjustments to method names. The

Library Services
functionality of the OCX method and its associated C function is equivalent.

The mapping of C-function name to OCX method name is as follows:

OCX Method Name


C-Function Name
flcfg. (method)

flCfgAC_close_cdbs AcCloseCdbs

flCfgAC_get_filename AcGetFilename

flCfgAC_get_task AcGetTask

flCfgAC_get_title AcGetTitle

flCfgAC_nth_hdrcdb AcNthHdrcdb

flCfgAC_num_hdrcdb AcNumHdrcdb

flCfgAC_open_cdbs AcOpenCdbs

flCfgCDB_find_fld CdbFindFld

flCfgCDB_find_selfld CdbFindSelfld

FactoryLink Programmer’s Access Kit / 375


• CONFIGURATION DATABASE ACTIVEX COMPONENT
• Using CFGPAK OCX

OCX Method Name


C-Function Name
flcfg. (method)

flCfgCDB_get_domfld CdbGetDomfld

flCfgCDB_get_name CdbGetName

flCfgCDB_get_seqfld CdbGetSeqfld

flCfgCDB_get_title CdbGetTitle

flCfgCDB_lock CdbLock

flCfgCDB_nth_fld CdbNthFld

flCfgCDB_nth_relatecdb CdbNthRelatecdb

flCfgCDB_nth_selfld CdbNthSelfld

flCfgCDB_num_fld CdbNumFld

flCfgCDB_num_relatecdb CdbNumRelateCdb

flCfgCDB_num_selfld CdbNumSelfld

flCfgCDB_row_insert CdbRowInsert

flCfgCDB_row_validate CdbRowValidate

flCfgCDB_rowno CdbRowno

flCfgCDB_select_begin CdbSelectBegin

flCfgCDB_select_criteria CdbSelectCriteria

flCfgCDB_select_current CdbSelectCurrent

flCfgCDB_select_delete CdbSelectDelete

flCfgCDB_select_end CdbSelectEnd

flCfgCDB_select_first CdbSelectFirst

flCfgCDB_select_last CdbSelectLast

flCfgCDB_select_next CdbSelectNext

376 / FactoryLink Programmer’s Access Kit


CONFIGURATION DATABASE ACTIVEX COMPONENT
Using CFGPAK OCX

OCX Method Name


C-Function Name
flcfg. (method)

flCfgCDB_select_previous CdbSelectPrevious

flCfgCDB_select_rowno CdbSelectRowno

flCfgCDB_select_update CdbSelectUpdate

flCfgCDB_unlock CdbUnlock

flCfgDom_get_name DomGetName

flCfgDom_get_size DomGetSize

flCfgDom_get_value DomGetValue

flCfgDom_set_value DomSetValue
11
flCfgFld_get_name FldGetName

Library Services
flCfgFld_get_size FldGetSize

flCfgFld_get_title FldGetTitle

flCfgFld_get_value FldGetValue

flCfgFld_set_value FldSetValue

flCfgObj_add ObjAdd

flCfgObj_get_cdb ObjGetCdb

flCfgObj_select_begin ObjSelectBegin

flCfgObj_select_current ObjSelectCurrent

flCfgObj_select_delete ObjSelectDelete

flCfgObj_select_end ObjSelectEnd

flCfg_set_msgbox_handler MessageBox (event)

FactoryLink Programmer’s Access Kit / 377


• CONFIGURATION DATABASE ACTIVEX COMPONENT
• OBJPACK Sample Project


For the most part, parameters for the OCX methods are the same as their related C functions.
However, pointer arguments are passed as LONG types. For example, a flCfgSess* is passed
by value as a long. Similarly, a flCfgCDB** is passed by reference as a long. CFGPAK OCX
applications should treat these long values as opaque handles, passing them between CFGPAK
methods, but not altering their values. Because all OCX “pointers” are of a generic long type,
the application must not mix types, such as passing a long representing a FLCfgSess* into a
method expecting a long representing a FLCfgCDB*.

Another difference is the return of string values. For example, consider retrieving the value of
a configuration database field. With the C library function flCfgFld_get_value(), the
application passed a target character buffer that was to be filled in by the CFGPAK function.
The related OCX method FldGetValue() returns a string instead.

The handling of constants differs between the OCX and the C library. Since there is no header
file for a control in which to define constants such as how #define FLCFG_E_GOOD is
defined in C header file flcfg.h, OCX method GetDefineValue() is added to the control. It takes
the definition's name as a parameter and returns its numeric value. The returned value can then
be used by the OCX application just as the #define could be used in the C program.

One last difference between the OCX and the C library is the message box callback for errors
and warnings. The OCX exposes event MessageBox that the user overrides instead of invoking
a callback function.

Other than noted above, the CFGPAK control works like the C library, so the function
descriptions for the C library also apply to the OCX methods.

OBJPACK S AMPLE P ROJECT


Included with the OCX CFGPAK control set is a sample Visual Basic project that is installed
to directory {FLINK}\src\examples\objpack. This VB project creates a utility that assists users
in selectively removing unused tags from their FactoryLink application.

378 / FactoryLink Programmer’s Access Kit


Chapter 12





Configuration PAK API
Reference Library

This chapter provides the following information about each API function:
• Syntax: Valid format for this function
• Arguments: List containing the following information about each argument:

1. Type

2. Name

3. Direction (input = in; output = out; or both = in/out)


12
4. Description
• Returns: Description of the returned data from the function, usually a symbolic

Reference Library
representation of the integer value returned by the function, such as ERROR or GOOD.

Config PAK API


• Remarks: Additional information about the function, such as code fragments in the C
language.
• See also: Lists related function(s).

FactoryLink Programmer’s Access Kit / 379


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG _ SET _ MSGBOX _ HANDLER
Exception API.
Syntax #include <flcfg.h>
typedef int (*FLCFG_MBH)(char *title, char *msg, int btype);
void flCfg_set_msgbox_handler(FLCFG_MBH handler);

Arguments MBH_HANDLER handler in User-defined function to handle the


message boxes of error messages

Remarks Function flCfg_set_msgbox_handler( ) allows you to install your own function to


handle error messages, such as displaying message boxes or writing the messages to a
log file.
Upon an internal exception or warning, the user-provided message box handler
receives a title string, a message string, and message box type identifier. Types of
message boxes requested are

Box Type ID Description

FLCFG_MBOX_OK Single button (OK) messsage box


FLCFG_MBOX_OKCANCEL Dual button (OK & CANCEL) message box

The function should return the ID of the button pressed. The button IDs are:

Box Type ID Description

FLCFG_MBID_OK Single button (OK) messsage box


FLCFG_MBID_CANCEL Dual button (OK & CANCEL) message box

In general, the type of message box requested is the OK box; therefore, the function
should return the ID of the OK button. The one exception is the use of the message
box during a tag definition modification where the OK-CANCEL functionality is
requested. The OK-CANCEL functionality allows the user to make the choice as to
how the activity is to proceed for cases where a trade-off is involved. For an example
of this case, please see the description for function “flCfgObj_select_previous”.
If no handler is installed, then the error messages are routed to standard output.
See Also “flCfgObj_select_previous”

380 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG AC_ CLOSE _ CDBS


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgAC_close_cdbs(flCfgSess *sess, flCfgAC *cfgacp);

Arguments flCfgSess* sess in Session handle

flCfgAC* flcfgacp in Handle to the AC to close databases

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgAC_close_cdbs( ) closes the databases defined by the given AC.
See Also “flCfgAC_close_cdbs” 12
“flCfgSess_nth_ac”

Reference Library
Config PAK API
FL C FG AC_ GET _ GUID
FL C FG AC_ GET _ FILENAME
FL C FG AC_ GET _ TASK
FL C FG AC_ GET _ TITLE
Attribute Catalog API.
Syntax #include <flcfg.h>
char* flCfgAC_get_guid(flCfgAC *cfgacp);
char* flCfgAC_get_filename(flCfgAC *cfgacp);
char* flCfgAC_get_task(flCfgAC *cfgacp);
char* flCfgAC_get_title(flCfgAC *cfgacp);

Arguments flCfgAC* flcfgacp in AC to get attribute

Returns Success: (char*) to request string.


Failure: NULL.
Remarks Returns the name of the GUID, filename, title, or task associated with the given AC
handle.
See Also “flCfgSess_nth_ac”

FactoryLink Programmer’s Access Kit / 381


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG AC_ NTH _ HDRCDB
Attribute Catalog API.
Syntax #include <flcfg.h>
int flCfgAC_nth_hdrcdb(flCfgAC *cfgacp, int n, flCfgCDB **cfgcdbp)

Arguments flCfgAC* cfgacp in AC handle


int n in Index identifier for a particular CDB
flCfgCDB** cfgcdbp out Handle to the requested CDB

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgAC_nth_hdrcdb( ) returns the handle to the nth configuration database
(CDB) tied to the given attribute catalog (AC). Given this handle, the CDB schema
and contents can be accessed.
This function is often called in conjunction with function flCfgAC_num_hdrcdb( ).
See Also “flCfgAC_nth_text”
“flCfgSess_nth_ac”

FL C FG AC_ NTH _ TEXT


Attribute Catalog API.
Syntax #include <flcfg.h>
int flCfgAC_nth_text(flCfgAC *cfgacp, int n, flCfgText **cfgtxtp)

Arguments flCfgAC* cfgacp in AC handle


int n in Index identifier for a particular text file
group
flCfgText** cfgtxtp out Handle to the requested text file group

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgAC_nth_text( ) returns the handle to the nth configuration text file
group tied to the given attribute catalog (AC). Given this handle, the text files within
this group can be accessed. .

382 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

This function is often called in conjunction with function flCfgAC_num_text( ).


See Also “flCfgAC_num_text”
“flCfgSess_nth_ac”

FL C FG AC_ NUM _ HDRCDB


Attribute Catalog API.
Syntax #include <flcfg.h>
int flCfgAC_num_hdrcdb(flCfgAC *cfgacp);

Arguments flCfgAC* cfgacp in Session handle

Returns Success: Number of header CDBs (>= 0).


Failure: FLCFG_E_{...} error code. 12
Remarks Function flCfgAC_num_hdrcdb( ) returns the number of top-level configuration
databases defined within the given AC. A top-level CDB is one that has no fields

Reference Library
Config PAK API
whose range of legal values is dependent on the contents of another table.
See Also “flCfgAC_nth_hdrcdb”
“flCfgSess_nth_ac”

FL C FG AC_ NUM _ TEXT


Attribute Catalog API.
Syntax #include <flcfg.h>
int flCfgAC_num_text(flCfgAC *cfgacp);

Arguments flCfgAC* cfgacp in Session handle

Returns Success: Number of text file groups (>= 0).


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgAC_num_text( ) returns the number of text file groups defined within
the given AC.
See Also “flCfgAC_nth_text”
“flCfgSess_nth_ac”

FactoryLink Programmer’s Access Kit / 383


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG AC_ OPEN _ CDBS
Configuration Session API.
Syntax #include <flcfg.h>
int flCfgAC_open_cdbs(flCfgSess *sess, flCfgAC *cfgacp, int create);

Arguments flCfgSess* sess in Returns session handle

flCfgAC* cfgacp in Handle to the AC to open databases


Int create in If non-zero, create the databases if they do not
already exist.

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgAC_open_cdbs( ) loads the configuration database schema definitions
(if not loaded already) from the AC and then physically opens these files. The create
flag indicates whether the function should create the databases if they do not already
exist. If the create flag is off, then error code FLCFG_E_NOFILE reports that the
tables have not yet been created.
See Also “flCfgAC_close_cdbs”
“flCfgSess_nth_ac”
“flCfgAC_get_filename”
“flCfgAC_nth_text”

FL C FG CDB_ FIND _ FLD


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_find_fld(flCfgCDB *cfgcdbp, char *name, flCfld **fldp);

Arguments flCfgCDB* cfgcdbp in Header CDB handle


char* name in Target field name
FlCfgFld** fldp out Handle to requested field

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

384 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Remarks Function flCfgCDB_find_fld( ) returns the handle to the field whose name matches the
given name. Given this handle, the field properties can be accessed.
See Also “flCfgCDB_nth_fld”
“flCfgCDB_num_fld”

FL C FG CDB_ FIND _ SELFLD


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_find_selfld(flCfgCDB *cfgcdbp, char *name,
flCfgSel **selfldp);

Arguments flCfgCDB* cfgcdbp in Header CDB handle

char* name in Target field’s name 12


FlCfgSel** selp out Handle to requested select field

Reference Library
Config PAK API
Returns Success: FLCFG_E_GOOD.
Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_find_selfld( ) returns the handle to the select field whose name
matches the given name. Given this handle, the field properties can be accessed.
See Also “flCfgCDB_nth_selfld”
“flCfgCDB_num_selfld”

FL C FG CDB_ GET _ DOMFLD


Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgCDB_get_domfld(flCfgCDB *cfgcdbp, flCfgDom **cfgdomp);

Arguments flCfgCDB* cfgcdbp in CDB handle

flCfgDom* cfgdomp out Domain field handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 385


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgCDB_get_domfld( ) returns the handle to the domain field structure for
the given CDB. The value of the domain field determines the domain to which a
given row belongs.
Most CDBs have a domain field. Error code FLCFG_E_NOTFOUND is returned for
those that do not.
See Also “flCfgCDB_nth_selfld”
“flCfgCDB_nth_fld”
“flCfgCDB_get_seqfld”

FL C FG CDB_ GET _ NAME


Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgCDB_get_name(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB to get attribute

Returns Success: (char*) to CDB name.


Failure: NULL.
Remarks Function flCfgCDB_get_name( ) returns the table name for the given CDB.
See Also “flCfgCDB_get_title”

FL C FG CDB_ GET _ SEQFLD


Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgCDB_get_seqfld(flCfgCDB *cfgcdbp, flCfgSeq **cfgseqp);

Arguments flCfgCDB* cfgcdbp in CDB handle

flCfgSeq cfgseqp out Sequence field handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

386 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Remarks Function flCfgCDB_get_seqfld( ) returns the handle to the sequence field structure
for the given CDB. The value of the sequence field determines the order that
Configuration Explorer presents the rows. Sequence values are unique among all
rows sharing the same selection criteria. In other words, the sequence number is
unique among all rows sharing the same combination of domain and selection field
values.
Most CDBs have a sequence field. For those that do not, error code
FLCFG_E_NOTFOUND is returned.
See Also “flCfgCDB_get_domfld”
“flCfgCDB_nth_selfld”
“flCfgCDB_nth_fld”

FL C FG CDB_ GET _ TITLE


Configuration Database API. 12
Syntax #include <flcfg.h>
char* flCfgCDB_get_title(flCfgCDB *cfgcdbp);

Reference Library
Config PAK API
Arguments flCfgCDB* cfgcdbp in CDB to get attribute

Returns Success: (char*) to the CDB title.


Failure: NULL.
Remarks Function flCfgCDB_get_title( ) returns the title associated with the given CDB.
See Also “flCfgCDB_get_name”

FL C FG CDB_ LOCK
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_lock(flCfgCDB *cfgcdbp, int incl_relcdbs);

Arguments flCfgCDB* cfgcdbp in CDB handle

int incl_relcdbs in If non-zero, lock related CDBs as well

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 387


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgCDB_lock( ) locks the entire CDB contents, preventing other processes
from reading or writing its contents. Locks are useful when performing complex
transactions that require others to be blocked until the operation is complete. Since
complex operations often involve the CDBs related to the given CDB, the
incl_relcdbs parameter allows the entire CDB tree to be locked with a single function
call.
Calls to function flCfgCDB_lock( ) can be nested, but care must be taken to ensure the
same number of unlock calls are made for each lock call.
See Also “flCfgCDB_unlock”

FL C FG CDB_ NTH _ FLD


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_nth_fld(flCfgCDB *cfgcdbp, int n, flCfgFld **fldp);

Arguments flCfgCDB* cfgcdbp in Header CDB handle


int n in Index identifier for a particular field
FlCfgFld** v out Handle to the requested field

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_nth_fld( ) returns the handle to the nth field tied to the given
CDB. Given this handle, the field properties can be accessed.
See Also “flCfgCDB_num_fld”

FL C FG CDB_ NTH _ RELATECDB


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_nth_relatecdb(flCfgCDB *cfgcdbp, int n, flCfgCDB **relcdbp);

Arguments flCfgCDB* cfgcdbp in Header CDB handle


int n in Index identifier for a particular CDB
flCfgCDB** relcdbp out Handle to requested CDB

388 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_nth_relatecdb( ) returns the handle to the nth relate CDB tied to
the given CDB. Given this handle, the relate CDB schema and contents can be
accessed.
A relate CDB is a table whose contents depend upon a many to one relation between
itself and its header CDB. Although most relations are one level deep, a relate CDB
may be itself a header CDB, providing multiple level of relations. These relations
commonly bind on the basis of a domain and a table name where table name is an
arbitrary string used to bind records in the relate CDB to a record in the header CDB.
This function is often called within an iteration loop in conjunction with function
flCfgCDB_num_relatecdb( ).
See Also “flCfgCDB_num_relatecdb”
12
FL C FG CDB_ NTH _ SELFLD
Configuration Database API.

Reference Library
Config PAK API
Syntax #include <flcfg.h>
int flCfgCDB_nth_selfld(flCfgCDB *cfgcdbp, int n, flCfgSel **selfldp);

Arguments flCfgCDB* cfgcdbp in Header CDB handle

int n in Index identifier for a particular field

FlCfgSel** selp out Handle to requested select field

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_nth_selfld( ) returns the handle to the nth select field tied to the
given CDB. Given this handle, the field properties can be accessed.
See Also “flCfgCDB_num_selfld”

FactoryLink Programmer’s Access Kit / 389


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG CDB_ NUM _ FLD
FL C FG CDB_ NUM _ RELATECDB
FL C FG CDB_ NUM _ SELFLD
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_num_fld(flCfgCDB *cfgcdbp);
int flCfgCDB_num_relatecdb(flCfgCDB *cfgcdbp);
int flCfgCDB_num_selfld(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: Number of requested items (>= 0).


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_num_fld( ) returns the number of data fields defined within the
given CDB.
Function flCfgCDB_num_relatecdb( ) returns the number of CDBs whose contents
are primarily dependent upon the given CDB.
Function flCfgCDB_num_selfld( ) returns the number of selection fields defined
within the given CDB.
See Also “flCfgCDB_nth_fld”
“flCfgCDB_nth_relatecdb”
“flCfgCDB_nth_selfld”

FL C FG CDB_ ROW _ INSERT


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_row_insert(flCfgCDB *cfgcdbp, flCfgValErr *ep);

Arguments flCfgCDB* cfgcdbp in CDB handle

flCfgValErr* ep out Validation error details

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

390 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Remarks Function flCfgCDB_row_insert( ) inserts a record into the given CDB, using the
values found within the CDB structure itself. Field level validation is performed, and
any such errors abort the insert. Specifics about the validation error are returned in the
flCfgValErr structure. Relations, such as whether the parent record exists, are not
checked.
When a record is inserted, a sequence number is usually associated with it. If the
given sequence value is zero, then the row is assigned the next largest sequence
number appropriate for the row's relations. Unless you have specific ordering needs, it
is best to allow flCfgCDB_row_insert( ) to assign the next available sequence number
by setting the sequence value to zero.
Function flCfgCDB_row_insert( ) updates the cross-reference (XREF) database with
any tag references contained within the inserted row.
See Also “flCfgCDB_row_validate”

FL C FG CDB_ ROW _ VALIDATE 12


Configuration Database API.

Reference Library
Syntax #include <flcfg.h>

Config PAK API


int flCfgCDB_row_validate(flCfgCDB *cfgcdbp, flCfgValErr *ep);

Arguments flCfgCDB* cfgcdbp in CDB handle

flCfgValErr* ep out Validation error details

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_row_validate( ) examines the individual field values for illegal
entries. Validation errors are returned in the flCfgValErr structure. Relations, such as
whether the parent record exists, are not checked.
See Also “flCfgCDB_row_insert”
“flCfgFld_set_value”

FactoryLink Programmer’s Access Kit / 391


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG CDB_ ROWNO
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_rowno(flCfgCDB *cfgcdbp, long *rowno);

Arguments flCfgCDB* cfgcdbp in CDB handle

long* rowno out Row number

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_rowno( ) returns the physical record number of the currently
selected row. The selected row retains this number until it is deleted, after which, the
number is eventually reassigned to a newly inserted row.
See Also “flCfgCDB_select_rowno”
“flCfgCDB_lock”
“flCfgCDB_unlock”

FL C FG CDB_ SELECT _ BEGIN


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_begin(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_begin( ) initiates the given CDB for a selection. A read
lock is placed on the CDB and the selection criteria is initialized to the values
currently held by the appropriate header CDBs, if any. Once the selection has begun,
the selection criteria may be tuned by altering the domain and/or select field values to
create a query not controlled by the contents of the header table(s). Once the selection
criteria is set, function flCfgCDB_select_first( ) is called to retrieve the first
appropriate record.

392 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

The selection criteria equates to the field values held in the domain and select fields,
as defined within the CDB schema. For selections from header CDBs, the user should
subsequently update the selection criteria by setting the domain field value since no
control record exists to derive the desired selection domain from.
Selections cannot be nested. If attempted, code FLCFG_E_SELBEGUN is returned.
The outstanding selection must be ended prior to initiating a subsequent selection.
See Also “flCfgCDB_select_first”
“flCfgCDB_select_next”
“flCfgCDB_select_end”
“flCfgDom_set_value”
“flCfgSel_set_value”

FL C FG CDB_ SELECT _ CRITERIA


Configuration Database API. 12
Syntax #include <flcfg.h>

Reference Library
int flCfgCDB_select_criteria(flCfgCDB *cfgcdbp);

Config PAK API


Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_criteria( ) is used with relate CDBs to configure their
selection criteria based upon the current selection of their header CDBs.
The most common use for this function is prior to inserting a row into a relate CDB.
Assuming the header CDB(s) are positioned on the row(s) the new record is to be
associated with, the values of the header’s selection are loaded into the relate CDB,
after which, the data fields can be filled and the row inserted, selection and data
information together.
See Also “flCfgCDB_select_first”
“flCfgCDB_row_insert”

FactoryLink Programmer’s Access Kit / 393


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG CDB_ SELECT _ CURRENT
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_current(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_current( ) reads the currently selected row database
values into memory. A call to function flCfgCDB_select_first( ) or
flCfgCDB_select_next( ) must precede this call. Error code FLCFG_E_ENDOFSEL
is returned if no row is currently selected.
The most common use for this function is after deleting a row. At this time, the
database is positioned on the next applicable row, but it has yet to be read into
memory.
See Also “flCfgCDB_select_first”
“flCfgCDB_select_next”
“flCfgCDB_select_delete”

FL C FG CDB_ SELECT _ DELETE


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_delete(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_delete( ) removes the currently selected row from the
database. Any rows in any related CDB tied to the deleted row are deleted as well.
The cross-reference (XREF) database is updated with any tag references loss by the
row deletion(s).

394 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Deletions will be disallowed if any one of the related CDBs to which the deletion may
be propagated to is held open by an active selection.
See Also “flCfgCDB_select_begin”
“flCfgCDB_select_current”

FL C FG CDB_ SELECT _ END


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_end(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD. 12


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_end( ) releases all memory and database locks held on

Reference Library
Config PAK API
behalf of a selection. For every selection begun, a corresponding end should be
issued.
See Also “flCfgCDB_select_begin”
“flCfgCDB_select_first”
“flCfgCDB_select_next”

FL C FG CDB_ SELECT _ FIRST


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_first(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_first( ) takes the values currently set as the selection
criteria and reads the first row that matches it. A call to function
flCfgCDB_select_begin( ) must precede this call. If no rows match the selection
criteria, then error code FLCFG_E_ENDOFSEL is returned.

FactoryLink Programmer’s Access Kit / 395


• CONFIGURATION PAK API REFERENCE LIBRARY



Once the record is read, the field values for the current record are available via
functions flCfgDom_get_value( ), flCfgSel_get_value( ), and flCfgFld_get_value( ).
Once a selection against the given CDB begins, it is legal to reset the selection back to
the first record by invoking this function without intermediate calls to the selection
begin/end functions.
See Also “flCfgCDB_select_begin”
“flCfgCDB_select_next”
“flCfgCDB_select_end”
“flCfgDom_get_value”
“flCfgSel_get_value”
“flCfgFld_get_type”

FL C FG C BD _ SELECT _ LAST
Object Database API
Syntax #include <flcfg.h>
int flCfgCDB_select_last(flCfgDB *Cfgcdbp);
Arguments flCfgCDB* cfgcdbp in CDB handle.
Returns Success:FLCFG_E_GOOD
Failure:FLCFG_E_{...} error code
Description Function flCfgCDB_select_last() takes the values currently set as the selection
criteria and reads the last row that matches it. A call to function
flCfgCDB_select_begin() must precede this call. If no rows match the selection
criteria, then error code FLCFG_E_ENDOFSEL is returned.
Once the record is read, the field values for the current record are available via
functions flCfgDom_get_value(), flCfgSel_get_value(), and flCfgFld_get_value().
Once a selection against the given CDB has been begun, it is legal to reset the
selection back to the first record by invoking this function without intermediate calls
to the selection begin/end functions.
See Also flCfgCDB_select_begin
flCfgCDB_select_previous
flCfgCDB_select_end
flCfgDom_get_value
flCfgSel_get_value
flCfgFld_get_value

396 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG CDB_ SELECT _ NEXT


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_next(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_next( ) reads the next record that matches the selection
criteria. This function is usually invoked several times after an initial call to the
function flCfgCDB_select_first( ). Error code FLCFG_E_ENDOFSEL is returned
once all applicable rows have been exhausted. 12
After the record is read, the field values for the current record are available via
functions flCfgDom_get_value( ), flCfgSel_get_value( ), and flCfgFld_get_value( ).

Reference Library
Config PAK API
See Also “flCfgCDB_select_begin”
“flCfgCDB_select_first”
“flCfgCDB_select_end”
“flCfgDom_get_value”
“flCfgSel_get_value”
“flCfgFld_get_type”

FL C FG CDB_ SELECT _ PREVIOUS


Configuration Database API.
Syntax #include <flcfg.h>

int flCfgCDB_select_previous(flCfgCDB *cfgcdbp);

Arguments flCfgCDB* cfgcdbp in CDB handle


Returns Success:FLCFG_E_GOOD
Failure:FLCFG_E_{...} error code
Description Function flCfgCDB_select_previoust() reads the previous record that matches the
selection criteria. This function is usually invoked several times after an initial call to
function flCfgCDB_select_last(). Once all applicable rows have been exhausted,
error code FLCFG_E_ENDOFSEL is returned.

FactoryLink Programmer’s Access Kit / 397


• CONFIGURATION PAK API REFERENCE LIBRARY



Once the record is read, the field values for the current record are available via
functions flCfgDom_get_value(), flCfgSel_get_value(), and flCfgFld_get_value().
See Also “flCfgCDB_select_begin”
“flCfgCDB_select_last”
“flCfgCDB_select_end”
“flCfgDom_get_value”
“flCfgSel_get_value”
“flCfgFld_get_value”

FL C FG CDB_ SELECT _ ROWNO


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_rowno(flCfgCDB *cfgcdbp, long rowno);

Arguments flCfgCDB* cfgcdbp in CDB handle

long rowno in Row number

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_rowno( ) selects and reads the row associated with the
given row number. A call to function flCfgCDB_select_begin( ) must precede this
call. Error code FLCFG_E_NOTFOUND is returned if no such row exists. This
function does not honor any constraints entered into the CDB selection criteria.
The most common use for this function is as part of a complex transaction where the
position of many rows must be recalled and accessed directly. Since row numbers are
subject to change in a multi-user environment, wrap the entire transaction in an lock
and unlock code block.
See Also “flCfgCDB_rowno”
“flCfgCDB_lock”
“flCfgCDB_unlock”

398 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG CDB_ SELECT _ UPDATE


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_select_update(flCfgCDB *cfgcdbp, flCfgValErr *ep);

Arguments flCfgCDB* cfgcdbp in CDB handle

flCfgValErr* ep out Validation error details

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgCDB_select_update( ) updates the currently selected row from the
database. Any rows in the related CDBs tied to the updated row are updated as well, if
the update affects the relation. The cross-reference (XREF) database is updated with 12
any tag references added, lost, or altered by the row update(s).

Reference Library
Updates are disallowed if any one of the related CDBs the update would be

Config PAK API


propagated to is held open by an active selection.
Domain values can be updated but only in header CDBs. Related CDB rows are
always dependent on their header CDB domain value. Updates to related rows are
always validated prior to committing the update. If any of these rows fail to validate,
the entire operation is aborted.
See Also “flCfgCDB_select_criteria”

FL C FG CDB_ UNLOCK
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgCDB_unlock(flCfgCDB *cfgcdbp, int incl_relcdbs);

Arguments flCfgCDB* cfgcdbp in CDB handle

int incl_relcdbs in If non-zero, unlock related CDBs as well

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 399


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgCDB_unlock( ) releases the lock held on the entire CDB contents and is
called in conjunction with function flCfgCDB_lock( ).
See Also “flCfgCDB_lock”

FL C FG D OM _ GET _ NAME
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgDom_get_name(flCfgDom *cfgdomp);

Arguments flCfgDom* cfgdomp in Domain field handle

Returns Success: (char*) to requested field name.


Failure: NULL.
Remarks Function flCfgDom_get_name( ) returns the domain field name.
See Also “flCfgCDB_get_domfld”
“flCfgDom_get_size”
“flCfgDom_get_value”

FL C FG D OM _ GET _ SIZE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgDom_get_size(flCfgDom *cfgdomp);

Arguments flCfgDom* cfgdomp in Domain field handle

Returns Success: Field width.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgDom_get_size( ) returns the domain field size.
See Also “flCfgCDB_get_domfld”
“flCfgDom_get_name”
“flCfgDom_get_value”

400 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG D OM _ GET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgDom_get_value(flCfgDom *cfgdomp, char *domval, int maxlen);

Arguments flCfgDOM* cfgdomp in Domain field handle


char* domval out Return buffer for domain value
int maxlen in Size of domval buffer

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgDom_get_value( ) returns the domain field value as filled in from a
selection operation.
12
See Also “flCfgCDB_get_domfld”
“flCfgDom_set_value”

Reference Library
Config PAK API
FL C FG D OM _ SET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgDom_set_value(flCfgDom *cfgdomp, char *domval);

Arguments flCfgDom* cfgdomp in Domain field handle


char* domval in New domain value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgDom_set_value( ) sets the domain field value in preparation for
selection, insert or update operations.
Setting the domain value usually applies only to the top-most header CDB. In other
cases, the domain value is inherited. For example, when inserting into a related CDB,
a call to flCfgCDB_select_criteria( ) normally precedes the call to function
flCfgCDB_select_first( ) so the row being inserted is related to the currently selected
row(s) within header CDB(s).
See Also “flCfgCDB_get_domfld”
“flCfgDom_set_value”

FactoryLink Programmer’s Access Kit / 401


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG F LD _ GET _ DEFAULT _ TAGTYPE
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgFld_get_default_tagtype(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field’s default tag type.


Failure: NULL
Remarks Function flCfgFld_get_default_tagtype( ) returns the field’s default tag type, if
applicable.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_value”

FL C FG F LD _ GET _ DEFAULT _ VALUE


Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgFld_get_default_value(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field’s default value.


Failure: NULL
Remarks Function flCfgFld_get_default_value( ) returns the field’s default value, if applicable.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_tagtype”

402 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG F LD _ GET _ FLAG
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_flag(flCfgFld *cfgfldp, int id);

Arguments flCfgFld* cfgfldp in Field handle


int id in Flag to get

Returns Success: FLCFG_E_GOOD


Failure: FLCFG_E_{...} error code
Remarks Function flCfgFld_get_flag( ) returns returns whether the given flag id has been
associated with the given field. The following flags can be applied to a field:
12
Flag ID Description
FLCFGFLD_FLAG_BLANK Field can be blank (optional field).

Reference Library
Config PAK API
FLCFGFLD_FLAG_HEX Field is hexadecimal.
FLCFGFLD_FLAG_OCTAL Field is octal.
FLCFGFLD_FLAG_RANGE Field does apply range check.
FLCFGFLD_FLAG_READONLY Field is read-only.
FLCFGFLD_FLAG_UPPERCASE Field forces all values to uppercase.

See Also “flCfgCDB_nth_fld”

FL C FG F LD _ GET _ HIGH
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgFld_get_high(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field’s upper bounds.


Failure: NULL
Remarks Function flCfgFld_get_high( ) returns the field’s upper bounds.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_low”

FactoryLink Programmer’s Access Kit / 403


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG F LD _ GET _ KEY _ TAGTYPES
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_key_tagtypes(flCfgFld *cfgfldp, flCfgKey **cfgkep);

Arguments flCfgFld* cfgfldp in Field handle

flCfgKey** cfgkeyp out Key file handle

Returns Success: FLCFG_E_GOOD


Failure: FLCFG_E_{...} error code
Remarks Function flCfgFld_get_key_tagtypes( ) returns a handle to a key file that lists the
valid tag types for the given field. If no tag types key file exists, then all tag types are
valid for the field.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_tagtype”

FL C FG F LD _ GET _ KEY _ VALUES


Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_key_tagtypes(flCfgFld *cfgfldp, flCfgKey **cfgkep);

Arguments flCfgFld* cfgfldp in Field handle

flCfgKey** cfgkeyp out Key file handle

Returns Success: FLCFG_E_GOOD


Failure: FLCFG_E_{...} error code
Remarks Function flCfgFld_get_key_values( ) returns a handle to a key file that lists the valid
strings for the given field. Values for key fields must come from this list. Values for
character fields may or may not come from the key file.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_value”

404 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG F LD _ GET _ LOW
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgFld_get_low(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field’s lower bounds.


Failure: NULL
Remarks Function flCfgFld_get_low( ) returns the field’s lower bounds.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_high”
12
FL C FG F LD _ GET _ NAME

Reference Library
Configuration Database API.

Config PAK API


Syntax #include <flcfg.h>
char* flCfgFld_get_name(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field name.


Failure: NULL.
Remarks Function flCfgFld_get_name( ) returns the field name.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_size”
“flCfgFld_get_type”

FactoryLink Programmer’s Access Kit / 405


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG F LD _ GET _ SIZE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_size(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: Field width.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgFld_get_size( ) returns the field size.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_tagtype”
“flCfgFld_get_type”

FL C FG F LD _ GET _ TITLE
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgFld_get_title(flCfgFld *cfgfldp);

Arguments flCfgFld* cfgfldp in Field handle

Returns Success: (char*) to requested field title.


Failure: NULL.
Remarks Function flCfgFld_get_title( ) returns the field title as specified within the AC file.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_tagtype”

406 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG F LD _ GET _ TYPE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_type(flCfgFld *cfgfldp, int id);

Arguments flCfgFld* cfgfldp in Field handle


int id in Flag type to get

Returns Success: FLCFGLD_E_TYPE {...}


Failure: FLCFG_E_{...} error code
Remarks Function flCfgFld_get_type( ) returns returns one of the following fields type IDs for
the given field:
12
Flag ID Description
FLCFGFLD_TYPE_CHARACTER Alphanumeric string.

Reference Library
Config PAK API
FLCFGFLD_TYPE_NUMBER Numeric string.
FLCFGFLD_TYPE_KEY Alphanumeric string from restrictive list.
FLCFGFLD_TYPE_TAG Tag names
FLCFGFLD_TYPE_TAGCHAR Tag name or alphanumeric string
FLCFGFLD_TYPE_TAGNUM Tag names or numeric string
FLCFGFLD_TYPE_TAGKEY Tag names or string from list.

See Also “flCfgCDB_nth_fld”

FL C FG F LD _ GET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_get_value(flCfgFld *cfgfldp, char *value, int maxlen);

Arguments flCfgFld* cfgfldp in Field handle


char* value out Return buffer for field value
int maxlen in Size of value buffer

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 407


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgFld_get_value( ) returns the field value as filled in from a selection
operation.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_default_tagtype”
“flCfgFld_get_size”

FL C FG F LD _ SET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgFld_set_value(flCfgFld *cfgfldp, char *value);

Arguments flCfgFld* cfgfldp in Field handle


char* value in New field value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgFld_set_value( ) sets the field value in preparation for an insert or
update operation.
See Also “flCfgCDB_nth_fld”
“flCfgFld_get_type”

FL C FG K EY _ GET _ FILENAME
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgKey_get_filenamee(flCfgKey *cfgkeyp);

Arguments flCfgKey* cfgkeyp in Key file handle

Returns Success: Key’s file name.


Failure: NULL.
Remarks Function flCfgKey_get_filename( ) returns the file name for the given key file.
See Also “flCfgFld_get_key_tagtypes”
“flCfgFld_get_key_values”

408 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG K EY _ NTH _ LABEL
FL C FG K EY _ NTH _ ID
FL C FG K EY _ NTH _ TOKEN
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgKey_nth_label(flCfgKey *cfgkeyp, int n, char **label);
int flCfgKey_nth_id(flCfgKey *cfgkeyp, int n, long *id);
int flCfgKey_nth_token(flCfgKey *cfgkeyp, int n, char **token);

Arguments flCfgKey* cfgkeyp in Key file handle


int n in Key file index
char** label out Key entry’s label
long* id out Key entry’s numeric ID 12
char** token out Key entry’s token

Reference Library
Config PAK API
Returns Success: FLCFG E GOOD
Failure: FLCFG_E_{...} error code.
Remarks Function flCfgKey_nth_label( ) returns the the label of the nth in the given key file.
The label is a language-specific string value. Use this string when setting the
associated field’s value, for this is what the field validation routines expect..
Function flCfgKey_nth_id( ) returns the numeric ID of the nth in the given key file.
This value is more applicable to CTGEN and the run-time environment than
configuration time.
Function flCfgKey_nth_id( ) returns the token of the nth in the given key file. The
token is a language-independent string value. Do not use this string when setting the
associated field’s value. The token string is stored in the configuration databases,
thus keeping the application configuration language independent.
See Also “flCfgFld_get_key_tagtypes”
“flCfgFld_get_key_values”

FactoryLink Programmer’s Access Kit / 409


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG K EY _ NUM
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgKey_num(flCfgKey *cfgkeyp);

Arguments flCfgKey* cfgkeyp in Key file handle

Returns Success: Number of key entries


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgKey_num( ) returns the number of key file entries.
See Also “flCfgFld_get_key_tagtypes”
“flCfgFld_get_key_values”

FL C FG O BJ _ ADD
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_add(flCfgObj *objp, flCfgTag *tagp,flCfgValErr *valerr);

Arguments flCfgCDB* objp in Object CDB handle


flCfgTag* tagp in Tag definition to add
flCfgValErr* valerr out Validation error details

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_add( ) inserts a new tag into the application. Any problems with
the proposed definition are returned via the validation error structure.
At a minimum, the given tag definition must have the name, domain, and type
attributes set within the given flCfgTag.
See Also “flCfgObj_select_delete”
“flCfgObj_select_first”
“flCfgObj_select_previous”
“flCfgTag_set_attrval”

410 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG O BJ _ GET _ CDB
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_get_cdb(flCfgSess *sess, flCfgCDB **objp);

Arguments flCfgSess* sess in Session handle


flCfgCDB** objp out Handle to object CDB

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_get_cdb( ) returns the handle to the given session object database.
With this handle, tag definitions can be read from and written to the application.
See Also “flCfgObj_select_begin” 12
“flCfgKey_get_filename”

Reference Library
Config PAK API
FL C FG O BJ _ SELECT _ BEGIN
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_begin(flCfgObj *objp);

Arguments flCfgCDB* objp in Object CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_select_begin( ) initiates a selection against the object database.
Selections cannot be nested.
All selections against the object database are sorted based on tag name.
See Also “flCfgObj_select_first”
“flCfgObj_select_name”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

FactoryLink Programmer’s Access Kit / 411


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG O BJ _ SELECT _ CURRENT
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_current(flCfgCDB *objp, flCfgTag *tagp);

Arguments flCfgCDB* objp in Object CDB handle

flCfgTag* tagp out Currently selected tag definition

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_select_current( ) reads the currently selected tag definition into
the given tag definition structure. A call to function flCfgObj_select_first( ) or
flCfgObj_select_name( ) must proceed this call. Error code FLCFG_E_ENDOFSEL
is returned if no row is currently selected.
The most common use for this function is after deleting a tag definition. At this time,
the database is positioned on the next applicable row, but it has yet to be read into
memory.
See Also “flCfgObj_select_first”
“flCfgObj_select_name”
“flCfgObj_select_delete”

FL C FG O BJ _ SELECT _ DELETE
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_delete(flCfgObj *objp);

Arguments flCfgCDB* objp in Object CDB handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_select_delete( ) removes the currently selected tag definition
from the object database. Deletions are rejected where references to that tag still exist
within the applications.

412 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

For structured tags, this constraint includes references to any of its member tags. If
there are no references to a structured tag and its members, then the delete call
removes both the currently selected tag and all of its members.
See Also “flCfgKey_get_filename”

FL C FG O BJ _ SELECT _ END
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_end(flCfgCDB *objp);

Arguments flCfgCDB* objp in Object CDB handle


12
Returns Success: FLCFG_E_GOOD.

Reference Library
Failure: FLCFG_E_{...} error code.

Config PAK API


Remarks Function flCfgObj_select_end( ) releases all memory and database locks held on
behalf of a selection. A corresponding end should be issued for every selection begun.
See Also “flCfgObj_select_begin”
“flCfgObj_select_first”
“flCfgObj_select_next”

FL C FG O BJ _ SELECT _ FIRST
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_first(flCfgObj *objp, flCfgTag *tagp);

Arguments flCfgCDB* objp in Object CDB handle

flCfgTag* tagp out First tag definition

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 413


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgObj_select_first( ) reads the first tag definition into the given tag
definition structure. A call to function flCfgObj_select_begin( ) must precede this
call.
If no tag definitions exist, error code FLCFG_E_ENDOFSEL is returned.
See Also “flCfgObj_select_begin”
“flCfgObj_select_next”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

FL C FG O BJ _ SELECT _ LAST
Object Database API
Syntax #include <flcfg.h>
int flCfgObj_select_last(flCfgObj *objp, flCfgTag *tagp);

Arguments flCfgCDB* objp in Object CDB handle


flCfgTag* tagp out First tag definition
Returns Success:FLCFG_E_GOOD
Failure:FLCFG_E_{...} error code
Description Function flCfgObj_select_last() reads the last tag definition into the given tag
definition structure. A call to function flCfgObj_select_begin() must precede this
call. If no tag definitions exist, error code FLCFG_E_ENDOFSEL is returned.
See Also “flCfgObj_select_begin”
“flCfgObj_select_previous”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

414 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG O BJ _ SELECT _ NAME
Object Database API.
Syntax #include <flcfg.h>

int flCfgObj_select_name(flCfgObj *objp, char* name, flCfgTag *tagp);

Arguments flCfgCDB* objp in Object CDB handle

char* name in Name of tag to select

flCfgTag* tagp out Tag definition for given name

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgObj_select_name( ) reads the tag definition for the given name into 12
the given tag definition structure. A call to function flCfgObj_select_begin( ) must
precede this call.

Reference Library
Config PAK API
The definition for the tag that alphabetically falls immediately after where the
requested tag would reside is read if no such tag exists. In this case, the selection
returns error code FLCFG_E_NOTFOUND. Error code FLCFG_E_ENDOFSEL is
returned if no such tag exists.
See Also “flCfgObj_select_begin”
“flCfgObj_select_next”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

FL C FG O BJ _ SELECT _ NEXT
Object Database API.
Syntax #include <flcfg.h>

int flCfgObj_select_next(flCfgObj *objp);

Arguments flCfgCDB* objp in Object CDB handle


flCfgTag* tagp out First tag definition

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 415


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgObj_select_next( ) reads the next object definition. This function is
usually multiply invoked after an initial call to function flCfgObj_select_first( ). Error
code FLCFG_E_ENDOFSEL is returned after all definitions have been exhausted.
See Also “flCfgObj_select_begin”
“flCfgObj_select_first”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

FL C FG O BJ _ SELECT _ PREVIOUS
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_previous(flCfgObj *objp);

Arguments flCfgCDB* objp in Object CDB handle


flCfgTag* tagp out First tag definition
Returns Success:FLCFG_E_GOOD
Failure:FLCFG_E_{...} error code
Description Function flCfgObj_select_previous() reads the previous object definition. This
function is usually multiply invoked after an initial call to function
flCfgObj_select_last(). Once all definitions have been exhausted, error code
FLCFG_E_ENDOFSEL is returned.
See Also “flCfgObj_select_begin”
“flCfgObj_select_first”
“flCfgObj_select_end”
“flCfgTag_get_attrval”

FL C FG O BJ _ SELECT _ UPDATE
Object Database API.
Syntax #include <flcfg.h>
int flCfgObj_select_update(flCfgObj *objp,
flCfgTag *tagp,flCfgValErr *valerr);

Arguments flCfgCDB* objp in Object CDB handle


flCfgTag* tagp in Tag definition to add
flCfgValErr* valerr out Validation error details

416 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_TAGEDIT.
FLCFG_E_{...} error code.
Remarks Function flCfgObj_select_update( ) modifies the currently selected tag definition.
Given tag definition tagp, the currently selected row attributes are compared and the
differences updated accordingly. If one or more of the changed attributes are one of
the core attributes (dimension, domain, name, and type), the update is propagated
throughout the entire application. This includes task CDBs, Math & Logic procedure
files, and drawing files.
Since changing a core attribute results in sweeping changes, many constraints are
placed upon this capability in order to preserve the integrity of the application. Should
the proposed definition update violate the application’s integrity, these violations are
reported back to the use via the message box handler (see function
“flCfg_set_msgbox_handler”for details).
See Also “flCfg_set_msgbox_handler”
12
“flCfgKey_get_filename”

Reference Library
“flCfgObj_select_delete”

Config PAK API


FL C FG S EL _ GET _ NAME
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgSel_get_name(flCfgSel *cfgselp);

Arguments flCfgSel* cfgselp in Field handle

Returns Success: (char*) to requested field name.


Failure: NULL.
Remarks Function flCfgSel_get_name( ) returns the selection field name.
See Also “flCfgCDB_nth_selfld”
“flCfgSel_get_size”
“flCfgSel_get_value”

FactoryLink Programmer’s Access Kit / 417


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG S EL _ GET _ SIZE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSel_get_size(flCfgSel *cfgselp);

Arguments flCfgSel* cfgselp in Field handle

Returns Success: Field width.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSel_get_size( ) returns the selection field size.
See Also “flCfgCDB_nth_selfld”
“flCfgSel_get_name”
“flCfgSel_get_value”

FL C FG S EL _ GET _ TITLE
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgSel_get_title(flCfgSel *cfgselp);

Arguments flCfgSel* cfgselp in Field handle

Returns Success: (char*) to requested field title.


Failure: NULL.
Remarks Function flCfgSel_get_title( ) returns the selection field title as specified within the
AC file.
See Also “flCfgCDB_nth_selfld”
“flCfgSel_get_name”

418 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG S EL _ GET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSel_get_value(flCfgSel *cfgselp, char *value, int maxlen);

Arguments flCfgSel* cfgselp in Field handle

char* value out Return buffer for selection field value

int maxlen in Size of value buffer

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSel_get_value( ) returns the selection field value as filled in from a 12
selection operation.
See Also “flCfgCDB_nth_selfld”

Reference Library
Config PAK API
“flCfgSel_get_name”
“flCfgSel_get_size”

FL C FG S EL _ SET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSel_set_value(flCfgSel *cfgselp, char *value);

Arguments flCfgSel* cfgselp in Field handle

char* value in New select field value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSel_set_value( ) sets the selection field value in preparation for
selection, insert, or update operations. When selecting data from a CDB, the values
set within the select field are ANDed together and form the where clause.

FactoryLink Programmer’s Access Kit / 419


• CONFIGURATION PAK API REFERENCE LIBRARY



Normally, one does not directly set the select values. As these values are derived from
another CDB (to relate the given CDB to its parent, or header) these values are
implicitly managed for selections or indirectly set for insert/update operations via
function flCfgCDB_select_criteria( ).
See Also “flCfgCDB_nth_selfld”
“flCfgSel_get_value”

FL C FG S EQ _ GET _ NAME
Configuration Database API.
Syntax #include <flcfg.h>
char* flCfgSeq_get_name(flCfgSeq *cfgseqp);

Arguments flCfgSeq* cfgseqp in Sequence field handle

Returns Success: (char*) to requested field name.


Failure: NULL.
Remarks Function flCfgSeq_get_name( ) returns the sequence field name.
See Also “flCfgCDB_get_seqfld”
“flCfgSeq_get_size”
“flCfgSeq_get_value”

FL C FG S EQ _ GET _ SIZE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSeq_get_size(flCfgSeq *cfgseqp);

Arguments flCfgSeq* cfgseqp in Sequence field handle

Returns Success: Field width.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSeq_get_size( ) returns the sequence field size.
See Also “flCfgCDB_get_seqfld”
“flCfgSeq_get_name”
“flCfgSeq_get_value”

420 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG S EQ _ GET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSeq_get_value(flCfgSeq *cfgseqp, long *value);

Arguments flCfgSeq* cfgseqp in Sequence field handle

long* value out Return buffer for sequence value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSeq_get_value( ) returns the sequence field value as filled in from a
selection operation.
12
See Also “flCfgCDB_get_seqfld”
“flCfgSeq_set_value”

Reference Library
Config PAK API
FL C FG S EQ _ SET _ VALUE
Configuration Database API.
Syntax #include <flcfg.h>
int flCfgSeq_set_value(flCfgSeq *cfgseqp, long value);

Arguments flCfgSeq* cfgseqp in Sequence field handle

long value in New sequence field value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSeq_set_value( ) sets the sequence field value in preparation for an
insert or update operation.
For inserts, it is often best to set this value to zero. The insertion function then assigns
the next available sequence number to the row.
See Also “flCfgCDB_get_seqfld”
“flCfgSeq_set_value”

FactoryLink Programmer’s Access Kit / 421


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG S ESS _ CLOSE
Configuration Session API.
Syntax #include <flcfg.h>
int flCfgSess_close(flCfgSess **sess);

Arguments flCfgSess** sess in/out Address of session handle. Set to NULL upon
session closure

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSess_close( ) closes the given session. Any configuration databases
held open within the session are closed at this time. Also, the call releases memory
held internally for the session.
All AC, CDB, or other handles tied to the closed session become invalid.
See Also “flCfgSess_open”

FL C FG S ESS _ NTH _ AC
Configuration Session API.
Syntax #include <flcfg.h>
int flCfgSess_nth_ac(flCfgSess *sess, int n, flCfgAC **cfgacp);

Arguments flCfgSess* sess in Session handle


Int n in Index identifier for particular AC
flCfgAC** cfgacp out Handle to requested AC

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSess_nth_ac( ) returns the handle to the nth attribute catalog tied to
the given session. Given this handle, the configuration databases defined within it can
be accessed.
This function is often called within an iteration loop in conjunction with function
flCfgSess_num_ac( ).
See Also “flCfgSess_num_ac”
“flCfgSess_open”

422 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG S ESS _ NUM _ AC
Configuration Session API.
Syntax #include <flcfg.h>
int flCfgSess_num_ac(flCfgSess *sess);

Arguments flCfgSess* sess in Session handle

Returns Success: Number of ACs (>= 0)


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgSess_num_ac( ) returns the number of attribute catalogs found within
the given session’s {FLINK}. Attribute Catalogs are a grouping of configuration
database schemas and handles associated with a particular task. You obtain a CDB
handle through an AC. 12
The AC-to-CT map, ASCII file {FLINK}/ac/ac2ct.map is the source for this
information. If the number of ACs appears to be less than it should (as if it is omitting

Reference Library
your PAK task), it is likely the TITLES file, ASCII file {FLINK}/ac/titles, is missing

Config PAK API


the AC entry for that task. If so, add it to the TITLES file. Then, update the map file
by executing “acctmgr -c -d” at the system prompt. This re-creates the map file based
on AC entries in the TITLES file.
See Also “flCfgSess_num_ac”
“flCfgSess_open”

FL C FG S ESS _ OPEN
Configuration Session API.
Syntax #include <flcfg.h>
int flCfgSess_open(char *flink, char *flapp, flCfgSess **sess);

Arguments char* flink in {FLINK} directory

char* flapp in {FLAPP} directory

flCfgSess** sess out Returns session handle. This is set to NULL


if open fails.

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 423


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgSess_open( ) creates a configuration session and attaches to the
system files within the target application. During the process, files within the given
FactoryLink system directory are loaded and used to interpret the application files.
Once all initialization activities succeed, a handle to the session is returned to the
caller. Otherwise, one of the error codes is returned.
The target application must exist in order to open it.
Currently, two limitations exist on the opening of sessions. First, a configuration
session can only be open for one application at a time. The API enforces this and
returns error code FLCFG_E_MULTSESS.
Second, all sessions must reference the same FactoryLink directory for as many times
as configuration sessions are opened and closed. System errors result from the latter
case.
See Also “flCfgSess_close”

FL C FG TAG _ CLEAR _ ATTRVALS


Object Database API.
Syntax #include <flcfg.h>
int flCfgTag_clear_attrvals(flCfgTag *tagp);

Arguments flCfgTag* tagp in Tag definition structure

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgTag_clear_attrvals( ) sets all attributes within the given tag definition
structure to a null string.
See Also “flCfgKey_get_filename”

424 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG TAG _ CREATE
FL C FG TAG _ DESTROY
Object Database API.
Syntax #include <flcfg.h>
int flCfgTag_create(flCfgTag **tagp);
int flCfgTag_destroy(flCfgTag **tagp);

Arguments flCfgTag** tagp in/out Tag definition structure

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgTag_create( ) allocates and returns a handle to a tag definition
structure. These are passed into object database calls. The returned flCfgTag has all
attributes initialized to a null string. 12
Function flCfgTag_destroy( ) releases a tag definition.

Reference Library
See Also “flCfgKey_get_filename”

Config PAK API


“flCfgObj_select_delete”
“flCfgObj_select_name”
“flCfgObj_select_previous”

FL C FG TAG _ GET _ ATTRVAL


FL C FG TAG _ GET _ ATTRVALP
Object Database API.
Syntax #include <flcfg.h>
int flCfgTag_get_attrval(flCfgTag *tagp, int id, char *val, int maxlen);
int flCfgTag_get_attrvalp(flCfgTag *tagp, int id,char **val);

Arguments flCfgTag* tagp in Tag definition


int id in Attribute ID

flCfgTag_get_attrval( ):

char* val out Value buffer


int maxlen in Size of value buffer

FactoryLink Programmer’s Access Kit / 425


• CONFIGURATION PAK API REFERENCE LIBRARY



flCfgTag_get_attrvalp( ):

char** val out Pointer to attribute value (read only)

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Functions flCfgTag_get_attrval( ) and flCfgTag_get_attrvalp( ) return the value for
the requested attribute set within the given tag definition structure.
See Also “flCfgObj_select_first”
“flCfgObj_select_name”
“flCfgTag_set_attrval”

FL C FG TAG _ SET _ ATTRVAL


Object Database API.
Syntax #include <flcfg.h>
int flCfgTag_set_attrval(flCfgTag *tagp, int id, char *val);

Arguments flCfgTag* tagp in Tag definition structure

int id in Attribute ID

char* val in Target attribute value

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgTag_set_attrval( ) sets the value for the requested attribute within the
given tag definition structure.
See Also “flCfgKey_get_filename”
“flCfgObj_select_previous”
“flCfgTag_clear_attrvals”
“flCfgTag_get_attrval”

426 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG TEXT _ GET _ DOMAIN


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_get_domain(flCfgText *cfgtxtp, char **domain);

Arguments flCfgText* cfgtextp in Text file group handle

char* domain out Current domain

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgText_get_domain( ) returns the current domain from which text files
are being accessed through character handle domain.
12
For cases where text files for the given handle are not domain specific, this function
returns FLCFG_E_NOTFOUND.

Reference Library
See Also “flCfgAC_nth_text”

Config PAK API


“flCfgText_get_filespec”
“flCfgText_set_domain”

FL C FG TEXT _ GET _ FILEPATH


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_get_filepath(flCfgText *txtp, char **fpath);

Arguments flCfgText* cfgtextp in Text file group handle

char* fpath out Full path name of currently selected file

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgText_get_filepath( ) returns the full path of the currently selected file.
For text file groups that consist of a single file, this function should be called without
invoking the text file selection routines. There is no need to select a file, when there
is only one possible choice.

FactoryLink Programmer’s Access Kit / 427


• CONFIGURATION PAK API REFERENCE LIBRARY



For text file groups that consist of multiple files, this function must be called after
having selected a text file with functions flCfgText_select_…().
See Also “flCfgAC_nth_text”
“flCfgText_select_begin”

FL C FG TEXT _ GET _ FILESPEC


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_get_filespec(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle from which to get file
specifier

Returns Success: (char*) to the text file group’s file specifier.


Failure: NULL
Remarks Function flCfgText_get_filespec( ) returns the file specifier associated with the given
handle, as defined within the AC. This specifier may be for a single file, or it might
include a wildcard for configuration that consists of a group of files. Unless a full
path is specified, the file specifier is evaluated as a path relative to the session’s
application directory.
The specifier may also consists on a leading “%s” format string. This means that the
text files reside in a application directory relative path which is dependent on a
domain.
See Also “flCfgAC_nth_text”
“flCfgText_get_domain”

FL C FG TEXT _ GET _ TITLE


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_get_title(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle from which to get title

Returns Success: (char*) to the text file group’s title.


Failure: NULL

428 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Remarks Function flCfgText_get_title( ) returns the title associated with the given handle.
See Also “flCfgAC_nth_text”

FL C FG TEXT _ SELECT _ BEGIN


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_select_begin(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgText_select_begin( ) initiates an iteration through all text files that
12
belong to the given text group cfgtxtp. This iteration is constrained by the current
domain, if applicable.

Reference Library
Config PAK API
For cases where only a single text file applies to the given handle, this function
returns error FLCFG_E_TEXTONE. For this case, an iterator is not needed to access
what files belong to the text group. Function flCfgText_get_filepath() should be
called to locate the file path instead.
See Also “flCfgAC_nth_text”
“flCfgText_select_first”
“flCfgText_select_end”
“flCfgText_set_domain”

FL C FG TEXT _ SELECT _ FIRST


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_select_first(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

FactoryLink Programmer’s Access Kit / 429


• CONFIGURATION PAK API REFERENCE LIBRARY



Remarks Function flCfgText_select_first( ) positions the iterator on the first file that is a
member of the text file group cfgtxtp. Function flCfgText_get_filepath() can then be
called to return the path to the selected file. For cases where no text files exist, this
function returns error FLCFG_E_ENDOFSEL.
See Also “flCfgText_get_filepath”
“flCfgText_select_begin”
“flCfgText_select_end”

FL C FG TEXT _ SELECT _ NEXT


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_select_next(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgText_select_next( ) positions the iterator on the next file that is a
member of the text file group cfgtxtp. Function flCfgText_get_filepath() can then be
called to return the path to the selected file. For cases where no text files exist, this
function returns error FLCFG_E_ENDOFSEL.
See Also “flCfgText_get_filepath”
“flCfgText_select_first”
“flCfgText_select_end”

FL C FG TEXT _ SELECT _ END


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_select_end(flCfgText *cfgtxtp);

Arguments flCfgText* cfgtextp in Text file group handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.

430 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

Remarks Function flCfgText_select_end( ) positions the iterator on the first file that is a
member of the text file group cfgtxtp. This function should be invoked once the
selection through the files is complete.
See Also “flCfgText_select_begin”

FL C FG TEXT _ SET _ DOMAIN


Configuration Session API.
Syntax #include <flcfg.h>
int flCfgText_set_domain(flCfgText *cfgtxtp, char *domain);

Arguments flCfgText* cfgtextp in Text file group handle

char* domain in Current domain


12
Returns Success: FLCFG_E_GOOD.
Failure: FLCFG_E_{...} error code.

Reference Library
Config PAK API
Remarks Function flCfgText_set_domain( ) sets the current domain from which text files shall
be selected.
For cases where text files for the given handle are not domain specific, this function
returns error FLCFG_E_NOTFOUND.
See Also “flCfgAC_nth_text”
“flCfgText_select_begin”
“flCfgText_get_domain”

FactoryLink Programmer’s Access Kit / 431


• CONFIGURATION PAK API REFERENCE LIBRARY



FL C FG VAL E RR _ CREATE
FL C FG VAL E RR _ DESTROY
Validation Error API.
Syntax #include <flcfg.h>
int flCfgValErr_create(flCfgValErr **valerrp);
int flCfgValErr_destroy(flCfgValErr **valerrp);

Arguments flCfgValErr** valerr in/out Validation error handle

Returns Success: FLCFG_E_GOOD.


Failure: FLCFG_E_{...} error code.
Remarks Function flCfgValErr_create( ) allocates and returns a validation error handle. These
are passed into CDB insert and update calls.
Function flCfgValErr_destroy( ) releases a validation error handle.
See Also “flCfgValErr_get_ctname”
“flCfgValErr_get_fldname”
“flCfgValErr_get_fldvalue”
“flCfgValErr_get_valmsg”

432 / FactoryLink Programmer’s Access Kit


CONFIGURATION PAK API REFERENCE LIBRARY

FL C FG VAL E RR _ GET _ CTNAME


FL C FG VAL E RR _ GET _ FLDNAME
FL C FG VAL E RR _ GET _ FLDVALUE
FL C FG VAL E RR _ GET _ VALMSG
Validation Error API.
Syntax #include <flcfg.h>
char* flCfgValErr_get_ctname(flCfgValErr *valerrp);
char* flCfgValErr_get_fldname(flCfgValErr *valerrp);
char* flCfgValErr_get_fldvalue(flCfgValErr *valerrp);
char* flCfgValErr_get_valmsg(flCfgValErr *valerrp);

Arguments flCfgValErr* valerrp in Sequence field handle


12
Returns Success: (char*) to requested string.
Failure: NULL.

Reference Library
Config PAK API
Remarks Function flCfgValErr_get_…( ) returns the specifics associated with a validation
error.
See Also “flCfgText_get_domain”

FactoryLink Programmer’s Access Kit / 433


• CONFIGURATION PAK API REFERENCE LIBRARY


434 / FactoryLink Programmer’s Access Kit








I


Part III









RAPD PAK













435



436 / FactoryLink Programmer’s Access Kit


Chapter 13





RAPD Principle

O VERVIEW
The FactoryLink Rapid Application Protocol Drive technology is the basis for the RAPD
Programmer’s Access Kit (RAPD PAK). This technology affords FactoryLink software
developers and application designers an alternative to the existing External Device Interface
(EDI) method. The new technology allows a reduction in driver software and applications
development.

The RAPD PAK is based on the Intertask Mail Exchange (MCI) library. The MCI library
defines a method for FactoryLink tasks to communicate via mailbox tags.

Compliant with FactoryLink open architecture, client tasks created with the RAPD PAK are
fully integrated into FactoryLink development and run-time systems.

I NSTALLATION
The following files are on your system after installing the software components:
• {FLINK}\INC\MCI3.H
• {FLINK}\INC\MCI3_FMT.H
• {FLINK}\INC\MCI3_INT.h
• {FLINK}\LIB\MCI3.LIB

{FLINK} designates which FLINK environment setting or directory the FactoryLink system 13
software has been installed in.

The current version of MCI PAK is 3.0. RAPD Principle


You must also have the FactoryLink Programmer’s Access Kit installed. Your driver will not
compile or link properly without FactoryLink PAK.

FactoryLink Programmer’s Access Kit / 437


• RAPD PRINCIPLE
• RAPD Principle


RAPD P RINCIPLE
The RAPD Principle is based on FactoryLink mailbox communications. RAPD involves at
least two tasks. The I/O translator (IOX) and a protocol driver task developed using the MCI
library.

The two tasks communicate with one another via FactoryLink mailbox tags. The IOX task
makes requests upon the driver task to send and fetch data to/from a device, such as an RTU or
PLC. The driver task concerns itself only with communicating with an external device. The
IOX task provides all data conversions and tag storage.

All data is based on dataset definitions. These datasets define contiguous regions of data within
an external device. The IOX task and a protocol driver task pass datasets through their
respective mailbox tags. Data is directly packaged and unpackaged within a dataset.

MCI specifications and APIs define the method for processing datasets.

The following figure illustrates the RAPD principle with the IOX task and protocol driver
communicating via FactoryLink mailboxes.

The RAPD Principle

Aside from storage duties, the IOX task provides for data conversions (analog to float, IEEE
conversions) for I/O data to/from a protocol driver.

438 / FactoryLink Programmer’s Access Kit


RAPD PRINCIPLE
Compiling with MCI Library

C OMPILING WITH MCI L IBRARY


When compiling your program with the MCI library, you must define the data direction (byte
ordering) on the platform you are using. This is achieved by the following compiler directive:

FLAGS =...-DHOST_LOW_2_HIGH (used in the CFLAGS environment definition)

or

#define HOST_LOW_2_HIGH (used within a C header file)

For example, if your host machine uses an INTEL processor or compatible processor, data is
stored in LOW/HIGH format. You should then specify -DHOST_LOW_2_HIGH in the CFLAGS
directive or use a #define HOST_LOW_2_HIGH in your header file.

At run time, the MCI library makes the appropriate data conversions when using the data
format functions. Failure to define the correct data direction at compile time results in incorrect
data placement.

13

RAPD Principle

FactoryLink Programmer’s Access Kit / 439


• RAPD PRINCIPLE
• Compiling with MCI Library

440 / FactoryLink Programmer’s Access Kit


Chapter 14





MCI Messaging

This chapter discusses how the IOX task and a RAPD driver task communicate using the MCI
APIs by detailing the messaging scheme. Topics include:
• Mailbox Communications
• Datasets
• I/O Functionality
• Exception Write Function
• Data Directions
• MCI and LANS

A RAPD protocol driver and the IOX task communicate via FactoryLink mailboxes using the
MCI interface library. This process includes:

1 The IOX task translates I/O data bidirectionally to a protocol driver in the form of MCI
messages.

2 The protocol driver translates these requests into protocol messages to an external device.

3 Then, based on the results from the external device, the protocol driver responds via an MCI
message to the IOX task.

The method of creating, setting and extracting the message parameters are facilitated through
the various MCI function calls.
14

IMX Messaging

FactoryLink Programmer’s Access Kit / 441


• MCI MESSAGING
• Mailbox Communications


M AILBOX C OMMUNICATIONS
The IOX task and a RAPD protocol driver communicate through FactoryLink mailbox tags.
The mailbox API functions only accept the MBXMSG data structure. This data structure
contains user definable members with specific definitions. The following defines the generic
FactoryLink MBXMSG data structure:
typedef struct _MBXMSG /* client mailbox message */
{
MSG mm_msg; /*actual message to be sent */
/* (refers to message data) */
TAG mm_mbx; /* source mailbox (usually owned
/by sender of this message) */
u16 mm_type; /message type (for translation */
/to and from canonical form) */
u16 mm_user1; /* reserved for sender & receiver */
/* (usually message subtype) */
u32 mm_user2; /* reserved for sender & receiver */
/* (usually sequence number) */
id_t mm_sendid; /* task id of sender */

}MBXMSG;

The structure contains the following user definable members:


mm_msg This parameter is a standard message type MSG. This parameter must
always be specified with a pointer to a user buffer for sending or receiving
data together with the length of the buffer.
mm_mbx This parameter contains a valid mailbox tag. A mailbox user may specify a
mailbox tag when sending. The receiving task may use this mailbox tag to
send a response message back to the original sender.
mm_type
mm_user1
mm_user2 These three parameters are user definable.
mm_sendid This parameter must always be set with the task ID of the owner of the
mailbox, which means the sending task specifies its own task ID.

442 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Mailbox Communications

Every task using mailbox communication under FactoryLink uses the MBXMSG structure and
assigns its own meaning to the user definable members.

Caution: Do not directly access structure tags when using the


MCIPAK.

The MCIPAK always accesses MCI structures via macros or functions.

The sub-sections that follow describe the members of the MBXMSG structure.

mm_msg
The mm_msg parameter of the MBXMSG structure stores a data header in front of the data to
send (I/O data). The length of this header is 8 bytes. This means the programmer must always
reserve the first 8 bytes of the message buffer for a header area.

Therefore, the mm_msg data member is a structure that includes a data header of structure
type MCIHDR followed immediately by some I/O data. The size should be at least 8 bytes plus
the size of the I/O data to pass.

The layout of the header is defined in the following structure:


typedef struct _MCIHDR {
struct { /* structure with info of dataset */
unsigned version: 4; /*version of MCI used */
unsigned handling: 1; /* encoded or normal write */
unsigned reserved0: 3; /* reserved */
unsigned bnd_dir: 1; /* direction of data */
unsigned bit_dir: 1; /* direction of data */
unsigned bnd_start: 1; /* start of boundary data */
14
unsigned bit_start: 1; /* start of bit data */
unsigned boundary: 4; /* boundary of basic data tag */
} i;
IMX Messaging
ushort len; /* length of data */
ushort start; /* start address of data */
ushort cde; /* conversion code */
}MCIHDR;

FactoryLink Programmer’s Access Kit / 443


• MCI MESSAGING
• Mailbox Communications


Following is a description of each member of the MCIHDR structure:
version Specifies the version of the MCI library currently used. The current version
is ver 3.0 and is used for compatibility reasons.
handling Specifies the writing mode of the current data in the MCI message. The
receiving task uses this information for accessing the external device. The
handling can be either a normal or encoded write. Refer to “I/O
Functionality” on page 452 for information about the difference between a
normal and encoded write.
bnd_dir Specifies the direction of the data on a tag boundary. External devices can
have different directions of ordering their data in native format. Usually this
depends upon what kind of CPU the device is using.
For example, on a personal computer using an INTEL processor, the
ordering of the bytes within a word is from low to high (LSB first, MSB
second) whereas a Siemens PLC orders its bytes within a word from high to
low (MSB first, LSB second). In this case, the LSB bytes must be switched
with the MSB bytes to get the right value for data coming into the PC from
the device. For outgoing data from the PC, the LSB/MSB pair must be
switched to meet the MSB/LSB requirement in the Siemens PLC.
bit_dir Specifies the direction of single bits of a boundary tag. The principle of the
direction for bits is the same as described in the bnd_dir parameter.
bnd_start Specifies the offset of addressing in the external device for boundary tags.
bit_start Specifies the offset of addressing for bits within a boundary tag.
boundary Specifies the boundary of addressing in the dataset. Every external device
has one or more data types that are read or written through the protocol. A
specific data type has a method of addressing single tags within a dataset.
This method specifies the minimal size of a tag that can be addressed. This
size is called the boundary of that specific data type.
For example, a data type in an external device must be addressed on the size
of words. Address 1 specifies the first word, address 2 the second word.
This means this data type has a word boundary, and a word is the smallest
tag that can be read or written.
len Specifies the length of the data in the current command. The length of the
data must be specified in the number of tags according to the boundary of
the data type.
start Specifies the start address of the data in the external device.

444 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Mailbox Communications

CDE Means code extension and specifies the operation code that should be taken
upon the data. An MCI data header always specifies the operation on the
data that must be taken. The following CDE identifiers are a sample of the
possible operational codes:
CDE_B0_15 Bit operation bit 0 - 15
CDE_B16_3 Bit operation bit 16- 31
CDE_NIBBLE Nibble operation
CDE_BYTE Signed byte operation
CDE_UBYTE Unsigned byte operation
CDE_SIGNED Signed word operation
CDE_UNSIGNED Unsigned word operation

CDE_UBCD Word BCD operation


CDE_LONG Signed long operation
CDE_ULONG Unsigned long operation
CDE_LBCD Long BCD operation

CDE_SIEMENS_FLT Siemens floating point operation


CDE_SINGLE_IEEE_FLT IEEE single precision floating point operation
CDE_DOUBLE_IEEE_FLT IEEE double precision floating point operation
CDE_BLOCK Block operation on data
CDE_STRING String operation

These codes are used primarily for exception write cases (except CDE_BLOCK). In an
exception write example, a CDE_UNSIGNED code could be used to specify a write of a single
unsigned word. The receiving task (driver) would then generate a command according to the
specific protocol to write the single word. 14
The code CDE_BLOCK is used for block operations.
IMX Messaging
For example, if the mm_type data member of the MBXMSG structure indicates an
MCI_READ_REQ(and the CDE is CDE_BLOCK, the driver performs a block read operation.
Refer to “I/O Functionality” on page 452 for details about CDE codes.

Operations Codes (Extensions (CDE) )

The CDE operation codes are used in case of an exception write (normal or encoded) to specify
which action the write must take. CDE codes are built up with a base CDE code and an
additional bit number to specify the exact operation.

FactoryLink Programmer’s Access Kit / 445


• MCI MESSAGING
• Mailbox Communications


For example, the base CDE code for bit manipulations is 0x0100. The final CDE code will be
0x0103 if an operation must be completed on bit 3.

The MCI library defines the following base CDE codes.

CDE Definition CDE Description

CDE_B0_15 0x0100 Bit manipulations bit 0-15

CDE_B16_31 0x0110 Bit manipulations bit 15 - 31

CDE_NIBBLE 0x0300 Nibble manipulations

CDE_BYTE 0x0400 Signed byte manipulations

CDE_UBYTE 0x0500 Unsigned byte manipulations

CDE_SIGNED 0x0600 Signed integer manipulations

CDE_UNSIGNED 0x0700 Unsigned integer manipulations

CDE_UBCD 0x0780 Short BCD manipulations

CDE_ULONG 0x0800 Signed long manipulations

CDE_LBCD 0x0900 Unsigned long manipulations

CDE_ULONG 0x0980 Long BCD manipulations

CDE_LBCD 0x0A00 Siemens float manipulations

CDE_SIEMENS_FLT 0x0A80 IEEE single floating point manipulations

CDE_SINGLE_IEEE_FLT 0x0B00 IEEE double floating point manipulations

CDE_BLOCK 0x0C00 Block data manipulations

CDE_STRING 0x0C80 String manipulations

For example, the following code must be specified if an operation must be performed on the
left byte of a variable of type u16:
CDE_UBYTE + 8 (bits) = 0x0508

446 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Mailbox Communications

mm_type
The definition of the mm_type member of the MBXMSG data structure is as follows:
typedef struct _MCITYPE {
unsigned type: 4; /* type of MCI message */

unsigned ident: 1; /* use of MSG CTRL tag or address */


unsigned more: 1; /* more data to come: yes or no */
unsigned org_host_dir: 1; /* set the originating host direction */
unsigned reserved: 1; /* reserved */

unsigned station_id: 8; /* originating station id of message */

}MCITYPE;

The type parameter specifies what kind of MCI message is being sent or received. The
following types are available:

MCI_QUERY_CMD /* MCI info message */


MCI_QUERY_RSP /* MCI info message feed back */
MCI_QUERY_ERROR /*MCI info message feed back */

MCI_READ_REQ /* read request */


MCI_READ_RSP /* read feed back */
MCI_READ_ERROR /* read feed back */
14

MCI_WRITE_REQ /* write request */ IMX Messaging


MCI_WRITE_RSP /* write feed back */
MCI_WRITE_ERROR /* write feed back */

MCI_RCV_ACT /* unsolicited receive active */


MCI_RCV_RDY /* unsolicited receive ready */
MCI_RCV_ERROR /* unsolicited receive ready */

FactoryLink Programmer’s Access Kit / 447


• MCI MESSAGING
• Mailbox Communications


ident Parameter in the MCITYPE structure that specifies whether a dataset
control tag is used. This tag is not used anymore and is still specified for
compatibility reasons with older versions of the MCI library.
more Tag used for specifying consecutive messages data must be contiguous in.
This tag is not currently used.
org_host_dir Specifies the data direction of the originating host and is used internally by
the MCI library for converting the MCI header.
station_id Tag specifies the remote station in case messages are sent over a LAN.

mm_user1
The layout of the mm_user1 parameter for the MCIMSG structure is defined as follows:
u16 mm_user1 ----> job sequence number

This data member holds a job sequence number used to keep track of messages from one task
to another. A programmer is not obligated to make use of this data member.

mm_user2
The layout of the mm_user2 parameter for the MBXMSG structure is defined as follows:
u32 mm_user2 ----> dataset control tag

This data member holds the dataset control tag used to identify a block of data being
exchanged between two MCI tasks. This parameter must always be specified whenever
sending an MCI message.

448 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Datasets

D ATASETS
The previous section describes the data structure of the mailbox message. This section
discusses the dataset information that goes into the mailbox message.

The concept of a dataset is key to understanding how a RAPD driver interacts with the IOX
task. The following subsection discusses datasets from the perspective of an application. Refer
to “I/O Functionality” on page 452 for details about the use of datasets as they pertain to
specific MCI messages.

Dataset Definition
A dataset for an application is defined as a contiguous area of storage location within an
external device. These locations are sometimes referred to as memory locations, registers,
addresses, files, or regions. The exact terminology is dependent on the type of device. The
protocol driver uses a dataset definition as the key to either read or write data from/to an
external device.

Transactions between the IOX task and a driver are based on passing dataset information back
and forth between the tasks. If the IOX task has a request for a protocol driver to act on a
WRITE operation, it defines some dataset parameters in a message to the driver. The driver
receives the message and, according to the dataset information received, carries out the
directive.

Datasets Defined in an Application


A dataset is defined as a FactoryLink digital tag in a driver’s Dataset Definition table. It is then
referenced in the IOX Tag Definition table.

A driver’s Dataset Definition table includes the following:


• Mailbox tag identification 14
• Start address (first tag to access for the dataset)
• Length specifier (number of contiguous tags to access)
IMX Messaging
• Associated completion tags for the operation (READ, WRITE, UNSOLICITED)

The following graphic displays an example of a dataset definition within a driver’s Dataset
Definition table (the driver used in this example is called Widget).

FactoryLink Programmer’s Access Kit / 449


• MCI MESSAGING
• Datasets

The following IOX Dataset Definition table shows a reference to the same dataset defined in
the driver Dataset Definition table. The data collected on the dataset is stored in the tag defined
in the Data Tag field.

In this case, it is a tag array that stores 20 consecutive tags starting with the tag at address 1.
Therefore, if a READ request occurs on the dataset analog_ds[0], 20 consecutive tags, residing
in the external device, starting at address 1 are stored in widget_analogs[0] (tag at address 1, tag
at address 2, tag at address 3 … tag at address 20).

For purposes of this illustration, the tags being collected on this dataset are all analog type data
(16 bits wide). They are stored in analog tags when read. The data comes from the same analog
tags when written to the external device.

There are other fields in the same IOX table, but they are explained in detail in the I/O
Translator information on the documentation CD.

Passing and Processing a Dataset


The following steps outline passing and processing a dataset:

1. The IOX task determines a READ or WRITE trigger has occurred for a referenced dataset
• The IOX task creates a mail message and sets certain parameters in the message based on
the given dataset.
• The message is mailed to the driver owning the dataset.

450 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Datasets

2. The driver detects an MCI event on the dataset and the mail message is received.
• A protocol message is built on the dataset parameters defined in the message by the IOX
task.
• The driver sends the message to the external device.
• The device sends a response back to the driver.
• The driver packages a response message to the IOX task, which may or may not include
data received from the device, by setting some parameters on the dataset and mails a
message to the IOX task.

3. The IOX task detects a response event from the driver.


• If the response contains data from a device (a result of a READ request), depending on
the conversion settings, the data may be converted or directly stored into the designated
tags.

The following depicts the flow of a dataset from the IOX task to the protocol driver.

1
mail message containing I/O Translator
dataset information the driver
must know to operate on 3
data returned in
mail message
from the driver
dataset translated into FactoryLink
protocol messages Workstation
Protocol Driver
exchange of
protocol messages
2
14

The external device may have internal regions allocated for IMX Messaging
data storage dedicated to certain data types. For example, this
external device may have address regions reserved for analog
(16 bit words) data.

Therefore, to gain access to 100 consecutive analog addresses,


External Device starting at address 10, a dataset would be defined in the
(RTU, PLC) application with starting address of 10 and length of 100. When
the dataset is used in say a BLOCK READ operation, addresses
10, 11, 12, 13, ..., 99, 100 will be accessed.

FactoryLink Programmer’s Access Kit / 451


• MCI MESSAGING
• I/O Functionality


I/O F UNCTIONALITY
You implement the following common functions for external device drivers with the MCI
interface library:
• Block read function
• Block write function
• Exception write function
• Encoded write function
• Unsolicited receive function

Every task that implements MCI functionality has an MCI mailbox. Different MCI tasks that
communicate with each other write MCI messages into each other’s MCI mailboxes.

For example, both the IOX task and the protocol driver have their own MCI mailbox tag. If the
IOX task wants to address a command to the protocol driver, it writes a message in the protocol
driver mailbox.

The following sections discuss the common functions supported by the MCI library. The
examples give you an idea of how the messages are constructed so they can be decoded and a
driver can respond to them.

Before discussing the various request functions, note that the IOX task performs a query of all
datasets from protocol drivers at startup. The query function Mci_Ds_Query( ) (used only by
IOX tasks) is automatically answered by the MCI library event check routine in a driver.

The original dataset definitions must be retrieved at startup because this IOX task completely
defines the dataset parameters in an MCI message to a driver. Since tasks can span a network,
this information eases the burden on a driver from having to constantly retrieve a dataset’s
original definition.

The Block Read Function


A block read means the IOX task generates a request for the protocol driver to read a complete
dataset (first tag to last tag) defined in the protocol driver.

The layout of the MBXMSG structure for a block read request is as follows:
Block Read Request
mm_msg.m_ptr = pointer to message buffer containing only an MCI data header
mm_msg.m_max = not applicable
mm_msg.m_len = length of the size of MCI data header
mm_mbx = IOX mailbox (reply mailbox)

452 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
I/O Functionality

mm_type.type = MCI_READ_REQ
mm_type.ident = MCI_TAG
mm_type.more = Not applicable
mm_type.ident = local host direction
mm_type.station_id = local station id
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = IOX FactoryLink Task ID

The layout of the data header structure for a block read request is displayed as follows (the
header is the part of the message buffer pointed to by mm_msg.m_ptr in the preceding figure):
Data Header for a Block Read Request
version: =3
handling: = not applicable
bnd_dir: = MCI_HIGH_2_LOW
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =1
boundary: = MCI_WORD_BND
len; = 80
start; = 10
cde; = CDE_BLOCK

After the block read request is sent to the driver, the driver creates a protocol message based on
the header data and then responds to the IOX task with data collected from the device. The 14
response looks similar to the following:
Block Read Response MBXMSG Structure
IMX Messaging
mm_msg.m_ptr = pointer to a message buffer (contains an MCI data header + data)
mm_msg.m_max = not applicable
mm_msg.m_len = length of received data including the MCI data h
mm_mbx = not applicable
mm_type.type = MCI_READ_RSP
mm_type.ident = MCI_TAG
m_type.more = not applicable

FactoryLink Programmer’s Access Kit / 453


• MCI MESSAGING
• I/O Functionality


mm_type.org_host_dir = originating host data direction
mm_type.station_id = remote station id
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = IOX FactoryLink Task ID

Block Read Response Data Header (MCIHDR)


version: =3
handling: = not applicable
bnd_dir: = MCI_HIGH_2_LOW
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =1
boundary: = MCI_WORD_BND
len; = 80
start; = 10
cde; = CDE_BLOCK

Data Retrieved
data
.
.
data
data

The IOX task reads this message from its own mailbox and analyzes the received data. The
length of the received data is located in the mm_msg.m_len member of the MBXMSG
structure. This member contains the total number of characters received, including the data
header.

In this example, the block read was successful. If the protocol driver encounters an error while
gathering the data, it sends an error to the IOX task. The function Mci_Send_Error( ) can be
used with Mci_Read_Error( ) as the error code parameter. The IOX task displays the error on
the run manager screen.

When both the IOX task and a driver exist on the same machine, a block read request is
expedited through a direct trigger of the targeted dataset with no mail exchanged.

454 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
I/O Functionality

Over a LAN, the IOX task sends a mail message containing a block read request. For a driver,
the MCI library hides the method the request is delivered in. In either case, the block read
request is handled by the driver in a common manner.

Block Write Function


You can write a contiguous block of data with one command to the external device with the
block write function. The IOX task generates a block write request for the protocol driver by
gathering and formatting the data and generating an MCI message. The data gathered is from
tags from the FactoryLink real-time database. The following MCI message is an example of a
block write request from the IOX task:
Block Write MBXMSG Structure
mm_msg.m_ptr = pointer to a message buffer (contains an MCI data header + data)
mm_msg.m_max = not applicable
m_msg.m_len = length of data to send inc. MCI data header
mm_mbx = IOX mailbox tag
mm_type.type = MCI_WRITE_REQ
mm_type.ident = MCI_TAG
mm_type.more = not applicable
mm_type.org_host_dir = local host data direction
mm_type.station_id = local station id
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = IOX FactoryLink Task ID

Block Write Response Data Header (MCIHDR)


14
version: =3
handling: = MCI_NORMAL_WRITE IMX Messaging
bnd_dir: = MCI_LOW_2_HIGH
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =0
boundary: = MCI_WORD_BND
len; = 80

FactoryLink Programmer’s Access Kit / 455


• MCI MESSAGING
• I/O Functionality


start; = 10
cde; = CDE_BLOCK

Tag Data To Output


data
.
.
data
data

The driver extracts the information from the header area as well as the accompanying tag data
to create a protocol message to send to the device.

The response from the driver to the block write request from the IOX task is in the following
form:
Block Write Response MBXMSG Structure
mm_msg.m_ptr = pointer to a message buffer (contains only an MCIHDR structure)
mm_msg.m_max = not applicable
mm_msg.m_len = length of the MCI data header
mm_mbx = not applicable
mm_type.type = MCI_WRITE_RSP
mm_type.ident = MCI_TAG
mm_type.more = not applicable
mm_type.org_host_dir = originating host direction
mm_type.station_id = remote station id
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = IOX FactoryLink Task ID

Block Write Response Data Header (MCIHDR)


version: =1
handling: = MCI_NORMAL_WRITE
bnd_dir: = MCI_LOW_2_HIGH
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =0

456 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
I/O Functionality

boundary: = MCI_WORD_BND
len; = 80
start; = 10
cde; = CDE_BLOCK

Use Mci_Write_Error( ) as a parameter on a call to Mci_Send_Error( ) if an error occurs on the


write operation. The IOX task displays the error on the run-time manager screen.

14

IMX Messaging

FactoryLink Programmer’s Access Kit / 457


• MCI MESSAGING
• Exception Write Function


E XCEPTION W RITE F UNCTION
There are two types of exception writes:
• Normal exception writes
• Encoded exception writes

Normal Exception Write


Single tags of different types within a dataset can be written directly to the external device
using a normal exception write. The IOX task generates an MCI message with the single tag
specified. The message from the IOX task is displayed looking similar to the following:
Exception Write Request MBXMSG Structure
mm_msg.m_ptr = pointer to a message buffer (contains a data header (MCIHDR) + data)
mm_msg.m_max = not applicable
mm_msg.m_len = length of data to send inc. MCI data header
mm_mbx = IOX mailbox tag
mm_type.type = MCI_WRITE_REQ
mm_type.ident = MCI_TAG
mm_type.more = not applicable
mm_type.org_host_dir = local host data direction
mm_type.station_id = local station id
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = IOX FactoryLink Task ID

Exception Write Request Data Header (MCIHDR)


version: =3
handling: = MCI_NORMAL_WRITE
bnd_dir: = MCI_LOW_2_HIGH
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =0
boundary: = MCI_WORD_BND
len; = not applicable
start; = 27

458 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Exception Write Function

cde; = CDE_BYTE

The exception write MCI message differs from the block write message in that the operation
code CDE specifies what kind of write should be performed. The length of the data is not
specified because an exception write always implies only one tag is to be sent. The CDE code
implies the data size of the tag itself. In the preceding example, a byte of data is written to a
word area.

Sometimes writing out the data cannot be accomplished in one operation. In the case of writing
a data tag that is a byte (8 bits) to an area in a device that has a word boundary (16 bits), it may
take two operations. The device protocol may not support direct byte operations, so the
solution is:
• Read the word area
• Patch in the byte value
• Write out the word to the device

After the driver has carried out the write operation, it responds to the IOX task in the same
manner as in a response to a block write. You can test for an exception write request to see if it
can be transformed into a normal block write. Being able to transform an exception write
(read-before-write) to a block write reduces message traffic. This is determined by a call to
Mci_ Ds_Evaluate_Write( ). The results of this function determine if the exception write can
be converted into a block write.

Encoded Exception Write

The encoded exception write function is the same as the exception write function but differs in
that it does not directly write to the tag in the external device. The definition of the MCI
message is exactly the same as described with the exception write function except the
following member differs:
handling: = MCI_ENCODED_WRITE

The encoded write (also called coded) causes the driver to perform a block write. The block
14
write is to an area in the device (PLC) that causes the device to perform an internal logic
procedure to make a direct change of a desired data item. This function has been introduced
because the exception write can be very slow for operations on data smaller than the boundary IMX Messaging
of the dataset. In the method for normal exception writes described previously, the tag to
manipulate must be read first, patched, and then written back. This is time consuming and
results in an increase in message transactions.

The encoded write request is used if the C option is chosen in the IOX task under the
Exception Write column. How one implements the encoded write feature in a driver depends
on the protocol. The driver receives a message that would normally be sent as an exception
write except the CDE code is different. The driver must extract the information and then create
a block write message based on the extracted data.

FactoryLink Programmer’s Access Kit / 459


• MCI MESSAGING
• Exception Write Function


With the encoded write, it is not necessary to first read and then write back the exception tag.
The operation on the tag is written only once. The performance of exception write requests can
be optimized using this method. For this function, the driver must be able to address a block of
registers.

The information taken from the exception write request from the IOX task is written into the
block of registers. When the block is sent out to the external device, the external device ladder
logic performs the required operation based on data contained in the block write.

After the protocol driver has performed the exception write, it generates an MCI response
message and sends it back to the IOX task. This is accomplished in the same manner as the
block write function. An Mci_Write_Error( ) can be set in an Mci_Send_Error( ) function call
in case an error occurs.

Unsolicited Receive Function


The requests discussed previously are activated by the IOX task. It is also possible for external
devices to spontaneously send data to a FactoryLink station. This method of communication is
the unsolicited receive function. The protocol driver receives the unsolicited data from a
device and then sends the unsolicited data to the IOX task. The protocol driver generates the
following message to the IOX task:
Unsolicited Receive Ready MBXMSG Structure
mm_msg.m_ptr = pointer to message buffer (contains a data header (MCIHDR) + data)
mm_msg.m_max = not applicable
mm_msg.m_len = length of data to send inc. MCI data header
mm_mbx = protocol driver mailbox tag
mm_type.type = MCI_RCV_RDY
mm_type.ident = MCI_TAG
mm_type.more = Yes or No
mm_type.org_host_dir = local host data direction
mm_type.station_id = local station id*
mm_user1 = Job sequence number
mm_user2 = dataset control tag
mm_sendid = protocol driver FactoryLink Task ID

Unsolicited Receive Ready Request Header (MCIHDR)


version: =1

460 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Exception Write Function

handling: = not applicable


bnd_dir: = MCI_LOW_2_HIGH
bit_dir: = MCI_HIGH_2_LOW
bnd_start: =0
bit_start: =0
boundary: = MCI_WORD_BND
len; = 20
start; = 27
cde; = CDE_BLOCK

Unsolicited Data
data
.
.
data
data

The IOX task receives this message, identifies the data with the dataset control tag, and
processes the data.

A driver must qualify an incoming message by matching it against a defined dataset. It is


inconsequential for a driver to send a message to the IOX task if no dataset is defined for it. If
the incoming message has no dataset match, the message is rejected.

If the protocol driver encounters an error while receiving unsolicited data, it sends an
Mci_Rcv_Error( ) code in an Mci_Send_Error ( ) function to the IOX task. The IOX task
displays the error on the run manager screen. 14

IMX Messaging

FactoryLink Programmer’s Access Kit / 461


• MCI MESSAGING
• Data Directions


D ATA D IRECTIONS
A very important issue with external devices and host machines is the direction of data.
Problems occur whenever the direction of data of the host machine (where the driver is
running) differs from the data direction of the external device.

For example, the data direction on the host can be from high to low and the external device
direction from low to high. If a word (2 bytes) is being read from the device, the bytes of this
word must be swapped. When a long data type is being read, then the bytes of this long data
type must be reversed in order to get a readable value. The following figure illustrates this
principle.
I/O Translator Data Directions

In MCIPAK, a group of defined data direction dependent functions are used to retrieve tags of
variable size from a dataset. The following example shows how to use some of these functions:
#define HOST_HIGH_2_LOW
char buffer[ 256];
void *data = buffer;
if( Mci_Get_Bnd_Dir( &ds) == MCI_HIGH_2_LOW)
analog = Mci_Get_Word_H2L( data); /* device stores data in high to low format and the host machine uses
high/low also no conversion is done*/
else
analog = Mci_Get_Word_L2H( data); /* device stores data in low to high format but the host uses
high/low, bytes are swapped*/

462 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Data Directions

You must decide in the code which function to use at run time depending on the data direction
of the external device data. At compile time, the source code also requires a decision on the
data direction of the host. You determine this when making a program definition (PDEF) of
HOST_HIGH_2_LOW or HOST_LOW_2_HIGH. This definition forces the compiler to insert
different macros in the source code depending on the host data direction. These macros are
listed in the file format3.h.

Combinations of CDE Code


The MCI specification defines the direction of data in all cases of communication (LAN and
non-LAN). The direction definition can differ because of the combination of the CDE code and
data boundary in an MCI message.

Data Header Direction

The data header is a special part of the message buffer and is always placed in front of the I/O
data. The direction of the header is always in the data direction of the host platform where the
software is running. This means if the IOX task and the protocol driver are running on the
same system, no conversion is needed for the header structure. In the MBXMSG structure of
an MCI message, Org_Host_Dir( ) is defined to specify the data direction of the originating
host. If this data direction differs from the local host data direction, the header part must be
converted. MCIPAK handles this automatically using the MCI library.

Block Data Commands

The block read and write functions operate with contiguous blocks of data. The CDE operation
of the MCI message is always set to Cde_Block( ). In this case, the data direction always
corresponds to the direction set in the MCI message and applies to the set boundary. The IOX
task (sender of the MCI message) is responsible for ensuring the data is valid and corresponds
to the direction set in the message.

Exception Data Commands 14


The CDE code influences the exception data operations.
IMX Messaging
For example, in an MCI message from the IOX task, the CDE code is set to Cde_Byte( ) (size
is byte) and the boundary for the dataset is a word.

FactoryLink Programmer’s Access Kit / 463


• MCI MESSAGING
• Data Directions


Two situations are possible for exception data messages:
• Size of the data the CDE code operates on is equal to or greater than the data boundary
• Size of the data the CDE code operates on is smaller than the data boundary

In the first case, the single exception tag is either the same size or greater than the destination
area. If the tag is the same size as the destination area, the tag can be written out as a simple
block write operation (the IOX task automatically determines this for a driver).

If the tag is greater than the destination area, as in the following figure, it is still considered a
block write operation. This figure illustrates a byte ordering situation. The IOX task takes care
of switching the data correctly for the driver. The driver assumes the data is adjusted correctly
and does not have to make any conversions before writing it to the device.
I/O Translator Exception Data Commands

In the second case, the CDE code defines a data tag smaller than the destination area in the
device.

For example, if a byte is to be written to a word area (16 bits) in a device, what byte (left or
right) must the data be written to? The CDE code specifies the proper byte. If the left byte is
the desired byte and it is unsigned, the CDE code is set to 0x0508 (CDE_UBYTE+8(bits)).
The 8 signifies to start at bit 8 that gives bits 8 to 15, which is the left byte.

464 / FactoryLink Programmer’s Access Kit


MCI MESSAGING
Data Directions

Converting MCI Messages


A protocol driver can receive an MCI message from an IOX task that differs from the defined
dataset in data direction or boundary. The MCI message must be converted to meet the
characteristics of the dataset. This is only done in the case of a send request from the IOX task
to the driver because all datasets received from a driver to the IOX task can be forwarded as
they are. The IOX task handles different data directions and determines the required
conversions.

A driver should never convert the MCI message block data functions. For block operations, the
protocol driver has no information about the data types (actual I/O data) the IOX task stores in
the MCI message. Types can be greater than the dataset boundary, such as a long being written
to a word area, and need more conversion. But the driver cannot correctly do the switching.
Therefore, block write message requests received from the IOX task must match the
corresponding dataset exactly; otherwise, the write message request cannot be sent to the
external device. The IOX task takes care of this for the driver. In the case of response data
resulting from a block read request, it is forwarded as is to the IOX task, and the IOX task
performs the necessary conversions.

The exception write commands can usually be transformed in size. This is dependent on where
the data has to be written or destination boundary in the external device as defined by the
dataset.

The problem with exception writes is the dataset has to be read first (read-patch-write) because
it may only be necessary to manipulate a portion of the dataset.

For example, after a read when a byte must be changed in a word, the byte value can be
manipulated in the word then written back out to the device. Failure to perform a read
operation as the first step may cause the other byte in the word to inadvertently get changed.
Subsequently, read-before-writes result in an increase in message traffic.

The MCI library includes a function called Mci_Ds_Evaluate_Write ( ) to reduce


read-before-write operations. This function determines whether a dataset can be written out in
14
one message or if it requires a read-before-write. The function essentially checks the size of the
data to write out against the data boundary of the area in the external device. If the CDE type is
smaller than the data boundary, as in a CDE_BYTE operation for a dataset with a word IMX Messaging
boundary, then the word (u16) is cast down to a byte size. The result is the data now changes
from a u16 to u8, essentially breaking down the word into a byte. The dataset can now be
written out in one operation. It depends on the external device whether or not data can be
reduced because reducing the data effectively or casting a word down to a byte causes a loss of
data.

FactoryLink Programmer’s Access Kit / 465


• MCI MESSAGING
• MCI and LANS


MCI AND LANS
Two MCI tasks (the IOX task and a protocol driver) can run on different computers
communicating with one another. Because the two computers can differ in data direction
(different platforms), MCI supplies information specifying where the dataset came from and
what kind of data orientation it has. The following tags of mm_type in the MBXMSG structure
are used in case a message is sent over a LAN:
mm_type.org_host_dir = local host data direction
mm_type.station_id = local station id

The org_host_dir tag specifies the data direction of the originating host. Because the MCI
header is always in the host format, this tag is checked against the local host data direction. If
they do not match, the MCI header must be converted to the local host data direction. The MCI
library takes care of this conversion automatically; therefore, no code is required to be
implemented in a protocol driver to handle this.

The station identification is a unique number of the host station on the LAN. The user must
assign this number and keep it unique over the LAN. The station identification can be passed
to the driver task as a program argument. You can use the station id number for checking if a
message did or did not originate over a LAN.

If tasks are to support communications over a LAN, some information must be exchanged
between the tasks before they can begin communications. The tasks are probably running on
separate nodes in two different FactoryLink applications, which means all tag ids are most
likely not consistent. MCI uses the dataset control tag for identification of the dataset. But, if a
problem prevails, the dataset control tags cannot be exchanged as they exist because the
remote application does not recognize the dataset control tag.

To resolve the problem, dataset information must first be exchanged between the tasks by the
IOX task using the Mci_Query_Cmd( ) function. This function is used to retrieve all
information about a dataset. The receiving task, usually a protocol driver, responds to the
request. The MCI library handles this automatically for a driver, so you need not implement
code to do this.

Once the information about the dataset control tags have been exchanged, further
communications between the tasks is possible. You must perform a dataset registration in order
to link the local and remote datasets. The MCI library does this automatically for the
developer. The only requirement for developing a task for use with the FactoryLink LAN is to
execute a query command at start-up for every dataset used (the IOX task automatically does
this). The MCI library transparently handles all further requirements needed for LAN
communication.

466 / FactoryLink Programmer’s Access Kit


Chapter 15





Writing a RAPD Driver

O VERVIEW
This chapter discusses designing a protocol driver using the MCI libraries. The following
outlines the basic flow of code for any driver:

1. Initialize the driver task as a FactoryLink task.

2. Make system setup calls to the MCI library.

3. Make an initialization call to the MCI library.

4. Define the characteristics of each data set and register them one at a time.

5. Go into the main loop of the program and check for MCI events. The loop terminates when
it detects the task is to terminate.

6. Make a call to exit the MCI library services after the loop terminates.

Sample code listing is as follows:


/* This program details example source code of a protocol driver that will setup a (one) dataset, register the dataset and then wait for
MCI events on the dataset.
*/
char buf[ 256]; /* global receive buffer */
int process_ds(MCIDS *); /* prototype of user event function for dataset */

int main(){
15

Writing a RAPD Driver


MCIDS ds, /* MCI temporary dataset for passing information */
*reg_ds; /* pointer to the final registered dataset */
MORE_INFO more_info; /* additional information associated with the dataset */
MCISYSTEM sys; /* MCI system information structure */
TAG iox_mbx, /* IOX task’s MCI mailbox */
protocol_mbx, /* protocol driver task’s MCI mailbox */
ds_ctrl; /* dataset control tag */
MSG b; /* buffer parameters */

/*set this task up as a FactoryLink task */


task_id = ...............etc

FactoryLink Programmer’s Access Kit / 467


• WRITING A RAPD DRIVER
• Overview

/* set the specific system parameters required by MCI of this task */


Mci_Sys_Set_Task_Id(&sys, task_id);
Mci_Sys_Set_Station_Id(&sys, 0); /* use if using the LAN feature */
Mci_Sys_Set_Mbx(&sys, protocol_mbx);
Mci_Sys_Set_Functions(&sys, MCI_ALL_FNC);

/* initailize the MCI */


if(Mci_Init(&sys) != GOOD) exit(1);

/*only one dataset will be defined in this example, of course you may have many more datasets in your task */

/* set all characteristics of the dataset before registering */


b.m_ptr = buf;
b.m_max = 256;

Mci_Set_R_Buffer (&ds,b); /* create the default buffer */


Mci_Set_T_Buffer (&ds,b); /* create a temporary buffer */
Mci_Set_Ds_Ctrl (&ds,&ds_ctrl); /* set dataset control tag /
Mci_Set_Name (&ds, “Control_Tag”); /* set tag name as listed in FactoryLink RTDB */
mx_Set_Snd_Mbx ( &ds, iox_mbx); /* IOX driver mailbox to send cmd /
mx_Set_Boundary ( &ds, MCI_WORD_BND); /* this dataset pertains to data that exists on a word
boundary (i.e. 16 bit word) */

Mci_Set_Bnd_Dir ( &ds, MCI_HIGH_2_LOW); /* every word is stored in the device in HIGH to LOW
format*/
Mci_Set_Bit_Dir ( &ds, MCI_HIGH_2_LOW); /* bits in a word in the device are stored in HIGH to LOW
format */
Mci_Set_Bnd_Offset ( &ds, 0); /* boundary offset starts at 0 */
x_Set_Bit_Offset ( &ds, 0); /* bit offset starts at 0 */
Mci_Set_Start ( &ds, 10); /* first tag in this dataset resides at address 10 in the device */
Mci_Set_Len ( &ds, 20); /* there are 20 contiguous tags for this dataset, address 10, 11, 12,..., 29
*/
Mci_Set_Udata ( &ds, ( void *)&more_info); /* attach the more information structure to this dataset
more_info would have been set with some supplemental information that may
be used with this dataset (i.e. device station id, port, etc.... this is up to
the developer to assign any supplemental information.*/
Mci_Set_Ufnc ( &ds, process_ds); /* call back function that will be invoked whenever an event
occurs on this dataset. */

/* register this information to the MCI and receive a pointer to the registered dataset */
if( ( reg_ds = Mci_Ds_Register ( ds)) != GOOD) exit( 0);
/* go into the main task loop */

468 / FactoryLink Programmer’s Access Kit


WRITING A RAPD DRIVER
Overview

while ( fl_test_term_flag( ..... ) /* continue to loop until the task has been terminated */
{
/* call the check event function of MCI on a polling basis */
if( Mci_Event_Check() == GOOD) {
/* do additional processing and other tasks here (i.e. check for unsolicited messages coming in) */
.............................
}
fl_sleep(1000); /* let other tasks have a chance to run */
}
Mci_Exit();
exit( 0);
end program */

The function Mci_Set_R_Buffer( ) is called to establish a default message buffer. This


message buffer is used for defining the MCIHDR and I/O data parameters in a message. This
message buffer is used over and over. In order to call up the use of the default buffer later, call
the function Mci_Ds_Prepare( ).

You define a temporary message buffer other than the default buffer by making a call to
Mci_Set_T_Buffer( ). In the example, a temporary buffer is used because, although the default
buffer was previously defined, it was not set as the current message buffer. The subsequent
MCI calls (Mci_Set_( )) require a message buffer to be defined. If this is not done, the program
attempts to write to an unallocated memory block.

Setting the dataset tag name has to be extracted from the CT record of the dataset. The example
included here has the name hard coded as Control_Tag.

The polling method (Mci_Event_Check( )) is used in a driver because the driver may have to
perform other duties, such as check its communications port for incoming or unsolicited data.

Arriving events are always per single dataset. They do not come in groups or as lists; therefore,
every event is processed in a first-come-first-served order. Every event that occurs corresponds 15
to a single dataset. When a dataset event occurs, the procedure you defined is invoked. That

Writing a RAPD Driver


procedure operates on the dataset accordingly.

The sample code shows a single dataset. A typical driver has to support more than one dataset,
so each must be setup according to each dataset CT record and then registered with the MCI
library one at a time. The dataset information in the sample code does not show that it came
from a CT record. In an actual driver, the dataset CT records are used as the source for
characteristics of a dataset.

FactoryLink Programmer’s Access Kit / 469


• WRITING A RAPD DRIVER
• Overview


The following sample illustrates the function you designed to call for a block read event for the
dataset:.

./*
* Example of user event function. This is automatically called by the MCI library when a dataset this function is defined for has an
event active for the dataset.
*/
int process_ds( MCIDS *ds); /* user event function for dataset */

MORE_INFO more_info; /* supplemental information for a dataset */


char cmd[256], respdata[256];
int len;

/* check what kind of message has been received */

switch( Mci_Get_Type( ds) ) {

case MCI_WRITE_REQ: ...........


break;
.
.
case MCI_READ_REQ: /* block read operation */

/* retrieve the pointer to supplemental dataset information, this could be information such as CT data associated with the
dataset or any other info you like.*/

more_info = Mci_Get_Udata_Ptr( ds);

/* read the request from the mail queue */


if( Mci_Recv( ds) != GOOD) ......../* handle the error */

/* initiate the read command for this dataset on the external device */

build_cmd(ds, &cmd); /* build the protocol cmd msg to perform the block read */
query_device(&cmd, &respdata, &len); /* query the device (send the message) */
bld_IOX_resp(ds, respdata); /* build response to IO translator */
Mci_Send(ds); /* send response to block read request to the IOX*/

break;

default:

470 / FactoryLink Programmer’s Access Kit


WRITING A RAPD DRIVER
IOX - Driver Communications

..........
break;
}
return GOOD;
}

Typically, for every dataset, a single user defined procedure is defined. The procedure should
handle any kind of event possible on a single dataset.

IOX - D RIVER C OMMUNICATIONS


Once the IOX task sends a request to a driver, the driver must respond positively or negatively.
The IOX task does not keep track of outstanding requests to a protocol driver. If an error
carrying out an IOX request occurs, such as while sending a command to a device, I/O errors
occur, Mci_Send_Error( ) notifies the IOX task of this error.

The IOX task does not have to prompt (block and exception requests) drivers for data. Drivers
may also send unsolicited messages (messages sent by an external device on its own) to the
IOX task.

15

Writing a RAPD Driver

FactoryLink Programmer’s Access Kit / 471


• WRITING A RAPD DRIVER
• Error Codes


E RROR C ODES
The MCI library returns error codes in the range as listed in the following tables. The first table
is exactly the same as the standard FactoryLink error codes.

Standard FactoryLink Errors

Error Number Description


1 Internal error.
2 Out of memory.
3 Operating system error.
4 Initialization not successful.
5 Initialization not successful.
6 Incorrect function.
7 Incorrect argument.
8 Incorrect data.
9 Bad data.
10 Null pointer assignment.
11 Change flag not set.
12 Procedure table full.
13 Bad procedure name.
14 Bad user name.
15 Bad option.
16 Incorrect check sum.
17 No options.
18 No key.
19 Bad key.
20 No port available.
21 Port busy.
22 FactoryLink already active.

472 / FactoryLink Programmer’s Access Kit


WRITING A RAPD DRIVER
Error Codes

Error Number Description


23 No lock.
24 Lock failed.
25 Lock expired.
26 Wait failed.
27 Termination flag set.
28 Q-size too big.
29 Q-size changed.
30 No tag list.
31 Tag list changed.
32 Wake up failed.
33 No signals.
34 Signaled.
35 Not a mailbox.
36 No messages.
37 Access denied.
38 Attribute failure.
39 Invalid attribute.
40 Attribute not defined.
41 Application exists. 15

Writing a RAPD Driver


42 RTDB does not exist.
43 No task bit.
44 Not a lite task.

FactoryLink Programmer’s Access Kit / 473


• WRITING A RAPD DRIVER
• Error Codes


Intertask Mail Exchange Errors

Error Number Description


50 Bad message type.
51 Message with dataset control tag not found in
queue.
52 No messages available to query.
53 Bad receive mailbox tag.
54 Bad mailbox send tag.
55 Bad dataset control tag.
56 Message cannot be adjusted.
57 Operation too big for variable.
58 Unknown boundary.
59 Function not supported.
60 No message for this index present.
61 Received remote dataset was not defined on this
system.
62 Received dataset was not registered.
63 WARNING: message is not queued.
64 Message is rejected because of problems in the
remote MCI.
65 Illegal method of addressing bits on bit boundary.
66 Tag cannot be written at once; read before writing.

474 / FactoryLink Programmer’s Access Kit


Chapter 16





MCI Reference Library

F UNCTION C ATEGORIES
The functions in MCI are divided into different categories depending on the operation to be
performed. This chapter lists all MCI functions in these categories.

Caution: Functions listed with an asterisk (*) should not be used


directly in a RAPD task because the MCI library uses them
internally.

General MCI

Global Functionality
Mci_Init Initializes the MCI.
Mci_Exit Exits the MCI.
Mci_Recv Receives a MCI message from the MCI mailbox.
Mci_Send Sends an MCI message to a MCI mailbox.
Mci_Send_Error Sends an error response depending on type of message.
Mci_Mirror Reverses data.
Mci_Place_Data Places data on the exact spot within a tag.
Mci_Get_CDE_Size Gets the size in byte of a CDE type.
Mci_Buffer_Alloc Allocates a buffer for use with MCI.
16
Dataset Functionality

IMX Reference Guide


Mci_Ds_Register Registers a dataset to the MCI.
Mci_Ds_Prepare Loads the default parameters of a dataset.
Mci_Ds_Query Sends a query command of the dataset to the remote task.
Mci_Ds_Remove Removes all datasets with same id from the mailbox queue.
Mci_Ds_Trigger Triggers a dataset for reading by the protocol driver.
Mci_Ds_Evaluate_Write Checks and converts the dataset for exception writing.

Event Functionality
Mci_Event_Retrieve Gets the event arrays for true event driven processing.
Mci_Event_Check Checks for MCI events on a polled basis.

FactoryLink Programmer’s Access Kit / 475


• MCI REFERENCE LIBRARY
• Function Categories


Queue Functionality
*Mci_Q_Init Initializes the queue at start up of MCI.
Mci_Q_Num Determines the number of messages in the queue.
Mci_Q_Query Queries a message with index x in the mailbox queue.
Mci_Q_Ds_Srch Searches for the dataset in the mailbox queue.

MCI Header (MCIHDR)


Mci_Get_Version Gets the version of the MCI.
*Mci_Set_Version Sets the version of the MCI.
Mci_Get_Handling Gets the writing mode of this dataset.
Mci_Set_Handling Sets the writing mode of this dataset.
Mci_Set_Bnd_Dir Sets the data direction of boundary data.
Mci_Get_Bnd_Dir Gets the data direction of boundary data.
Mci_Set_Bit_Dir Sets the data direction of bit data.
Mci_Get_Bit_Dir Gets the data direction of bit data.
Mci_Set_Bnd_Offset Sets the data offset addressing of boundary data.
Mci_Get_Bnd_Offset Gets the data offset addressing of boundary data.
Mci_Set_Bit_Offset Sets the bit offset addressing of bit data.
Mci_Get_Bit_Offset Gets the bit offset addressing of bit data.
Mci_Set_Boundary Sets the boundary of the data.
Mci_Get_Boundary Gets the boundary of the data.
Mci_Set_Start Sets the start address of the data.
Mci_Get_Start Gets the start address of the data.
Mci_Set_Len Sets the length of the data in boundary tags.
Mci_Get_Len Gets the length of the data in boundary tags.
Mci_Set_CDE Sets the operation code of the write function.
Mci_Get_CDE Gets the operation code of the write function.

MCI System (MCISYS)


Mci_Sys_Get_Task_Id Gets the FactoryLink task id set on MCI.
Mci_Sys_Set_Task_Id Sets the current task FactoryLink task id.
Mci_Sys_Get_ Gets the local station id number.
Station_Id
Mci_Sys_Set_ Sets local station id number.
Station_Id
Mci_Sys_Get_Mbx Gets the task MCI mailbox tag.
Mci_Sys_Set_Mbx Sets the task MCI mailbox tag.

476 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
Function Categories

Mci_Sys_Get_ Gets the supported function of the current MCI task.


Functions
Mci_Sys_Set_Functions Sets the MCI functions supported by the current task.

MCI Message (MCIMSG)


Mci_Get_Type Gets the type of the MCI message.
Mci_Set_Type Sets the type of the MCI message.
Mci_Get_Org_Host_Dir Gets the data direction of the originating host.
Mci_Set_Org_Host_Dir Sets the data direction of the originating host.
Mci_Get_Station_Id Gets the station id where the message came from.
Mci_Set_Station_Id Sets the station id on the message.
Mci_Get_Job_ Gets the job sequence number of the message.
Sequence
Mci_Set_Job_ Sets the job sequence number of the message.
Sequence
Mci_Get_Ds_Ctrl Sets the dataset control tag.
Mci_Set_Ds_Ctrl Gets the dataset control tag.
Mci_Get_U_Buffer Gets the pointer to the MCI data.
Mci_Get_Org_Buffer Gets the pointer to the original buffer (inclusive of the MCI header).
Mci_Get_R_Buffer Gets the default msg buffer defined at registration time.
Mci_Set_R_Buffer Sets the default msg buffer for the dataset.
Mci_Reset_Buffer Clears the msg buffer.
Mci_Get_Snd_Mbx Gets the send MCI mailbox tag.
Mci_Set_Snd_Mbx Sets the send MCI mailbox tag.
Mci_Get_Index Gets the index of the message in the mailbox queue at the moment.
Mci_Set_Index Gets the index of the message in the mailbox queue.

MCI Dataset (MCIDS) 16


Mci_Get_Name Gets the name of the dataset control tag.

IMX Reference Guide


Mci_Set_Name Sets the name of the dataset control tag.
Mci_Get_Udata_Ptr Gets the pointer to the user defined buffer.
Mci_Set_Udata_Ptr Sets the pointer to the user defined buffer.
Mci_Get_Ufnc_Ptr Gets the pointer to the user function.
Mci_Set_Ufnc_Ptr Sets the pointer to the user function.

FactoryLink Programmer’s Access Kit / 477


• MCI REFERENCE LIBRARY
• Function Categories


MCI Data Manipulation
The data manipulation functions are used to set and retrieve data on datasets. The functions
depend on the direction of the data in the dataset and the host direction defined in the MCI task
at compile time.
Mci_Get_Byte_Bit_H2L Gets bit out of byte with data direction high to low.
Mci_Set_Byte_Bit_H2L Sets bit on byte with data direction high to low.
Mci_Get_Byte_Bit_L2H Gets bit out of byte with data direction low to high.
Mci_Set_Byte_Bit_L2H Sets bit on byte with data direction low to high.
Mci_Get_Word_Bit_ Gets bit out of word with data direction high to low.
H2L
Mci_Set_Word_Bit_ Sets bit on word with data direction high to low.
H2L
Mci_Get_Word_Bit_ Gets bit out of word with data direction low to high.
L2H
Mci_Set_Word_Bit_L2H Sets bit on word with data direction low to high.
Mci_Get_Long_Bit_H2L Gets bit out of long with data direction high to low.
Mci_Set_Long_Bit_H2L Sets bit on long with data direction high to low.
Mci_Get_Long_Bit_L2H Gets bit out of long with data direction low to high.
Mci_Set_Long_Bit_L2H Sets bit on long with data direction low to high.
Mci_Get_Byte_Left_ Gets the left byte out of word wit data direction high to low.
H2L
Mci_Set_Byte_Left_ Sets the left byte on word with data direction high to low.
H2L
Mci_Get_Byte_Left_ Gets the left byte out of word with data direction low to high.
L2H
Mci_Set_Byte_Left_ Sets the left byte on word with data direction low to high.
L2H
Mci_Get_Byte_Right_ Gets the right byte out of word with data direction high to low.
H2L
Mci_Set_Byte_Right_ Sets the right byte on word with data direction high to low.
H2L
Mci_Get_Byte_Right_ Gets the right byte out of word with data direction low to high.
L2H
Mci_Set_Byte_Right_ Sets the right byte on word with data direction low to high.
L2H
Mci_Get_Word_H2L Gets a word with data direction high to low.
Mci_Set_Word_H2L Sets a word with data direction high to low.
Mci_Get_Word_L2H Gets a word with data direction low to high.
Mci_Set_Word_L2H Sets a word with data direction low to high.
Mci_Get_Long_H2L Gets a long with data direction high to low.
Mci_Set_Long_H2L Sets a long with data direction high to low.
Mci_Get_Long_L2H Gets a long with data direction low to high.
Mci_Set_Long_L2H Sets a long with data direction low to high.

478 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

Mci_Get_RLong_H2L Gets a reversed long with data direction high to low.


Mci_Set_RLong_H2L Sets a reversed long with data direction high to low.
Mci_Get_RLong_L2H Gets a reversed long with data direction low to high.
Mci_Set_RLong_L2H Sets a reversed long with data direction low to high.
Mci_Get_Double_H2L Gets a double with data direction high to low.
Mci_Set_Double_H2L Sets a double with data direction high to low.
Mci_Get_Double_L2H Gets a double with data direction low to high.
Mci_Set_Double_L2H Sets a double with data direction low to high.

MCI API S
This section provides the following information about each MCI API function:
• Syntax: Valid format for this function
• Arguments: List containing the following information about each argument:
• Type
• Name
• Description
• Returns: Description of the returned data from the function, usually a symbolic
representation of the integer value returned by the function, such as ERROR or GOOD.
• Remarks: Additional information about the function, such as code fragments in the C
language.
• See also: Lists related function(s).

Caution: Some functions listed warn the programmer not to


incorporate them into a driver. They are listed here only for
documentation purposes.
16
M CI _B UFFER _A LLOC
IMX Reference Guide
Allocates a buffer for transferring data using the MCI.
Syntax int Mci_Buffer_Alloc( MSG *msg)

Arguments MSG* msg Pointer to FactoryLink message structure.

Returns GOOD.
Error: FLE_OUT_OF_MEMORY.

FactoryLink Programmer’s Access Kit / 479


• MCI REFERENCE LIBRARY
• MCI APIs


Remarks This function allocates an MCI buffer and sets the pointer directly to the message.
The application must first set the length of the buffer using the m_max parameter.
This function can be used for setting allocating buffers for use with MCI but is not
strictly necessary. In case the application wants to allocate its own buffers, it should
also allocate space for the MCIHDR part, which is always in front of the data. The
buffer can be set by either using the Mci_Set_R_Buffer( ) or Mci_Set_T_Buffer( ).
The pointer to the first tag in the buffer must be retrieved using Mci_Get_U_Buffer( ).
The pointer to the original allocated buffer can be retrieved using
Mci_Get_Org_Buffer( ).

M CI _D S _E VALUATE _W RITE
Evaluates the MCI dataset to see if it is possible to write this dataset in one operation.
A write operation is treated as an exception write (reading before writing) or a block
write.
Syntax intMci_Ds_Evaluate_Write( MCIDS *dataset)

Arguments MCIDS* dataset Pointer to MCI dataset structure.

Returns GOOD: Tag can be written at once.


MCI_X_WRITE( ): Tag cannot be written at once. Read, patch and write back.
Remarks This function is used by protocol drivers for evaluating if a received exception write
command can be written at once to the external device. The function checks the
received dataset parameters against the registered parameters and tries to convert it so
it can be written with one command. If it cannot be written with one command and
cannot be converted, the tag must be read first from the external device, patched with
the new value and written back.
The criteria used for evaluation is if the size of the tag to write is smaller than the data
boundary of the external device, it cannot be written at one time because data in the
external device will be overwritten.
This function speeds up communication because, in most cases, one write command
is needed against a read before a write.
This function can alter the received dataset parameters and data in order to convert it.

480 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _D S _P REPARE
Loads the default values set at registering time on the dataset.
Syntax int Mci_Ds_Prepare( MCIDS *dataset, MSG *buffer)

Arguments MCIDS* dataset Pointer to MCI dataset structure.


MSG* buffer Pointer to buffer information.

Returns GOOD.
Remarks The prepare function can be used before sending an MCI message to a remote task.
After preparing the dataset, the type of the MCI command must be set and all tags of
the dataset can be redefined to meet the characteristics of the command.

M CI _D S _Q UERY
Sends a query request for information of the dataset to the remote task where the
dataset has been defined.
Syntax int Mci_Ds_Query( MCIDS *dataset)

Arguments MCIDS* dataset Pointer to MCI dataset structure.

Returns GOOD.
Errors:
MCI_BAD_CTRL.
MCI_BAD_SNDMBX.
FLE_NULL_POINTER.
FLE_BAD_TAG. 16
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES. IMX Reference Guide
FLE_ACCESS_DENIED.
FLE_OUT_OF_MEMORY.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
Remarks Usually I/O translator tasks use this function at initialization time in order to retrieve
all the information on a dataset.
Protocol drivers do not use this function.

FactoryLink Programmer’s Access Kit / 481


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _D S _R EGISTER
Registers a dataset for use with the MCI library.
Syntax MCIDS *Mci_Ds_Register(MCIDS *dataset)

Arguments MCIDS* dataset Pointer to MCI dataset structure.

Returns Success: Pointer to internal registered dataset.


Error: NULL pointer is returned.
Remarks Every dataset for use with the MCI must be registered first at initialization time.
Before registering, all relevant information of the dataset must be set first using MCI
functions. The MCI library will return a pointer to the final registered dataset that the
application can use for referencing.

M CI _D S _R EMOVE
Removes all datasets from the task MCI mailbox queue that have the same MCI
functionality and dataset control tag.
Syntax intMci_Ds_Remove(MCIMSG *dataset)

Arguments MCIDS* dataset Pointer to MCI dataset structure.

Returns GOOD.
Errors:
MCI_WRONG_INDEX.
MCI_NOT_FOUND.
FLE_OUT_OF_MEMORY.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_ACCESS_DENIED.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
MCI_BAD_CTRL.

482 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

Remarks This function scans all active messages in the MCI mailbox queues and removes
those messages that have the same MCI functionality and dataset control tag.
The MCI has four command capabilities: QUERY, READ, WRITE and RECEIVE.
For every message removed and representing an active command from the queue, an
error message with error MCI_MSG_REJECTED( ) is sent to the originating task.

M CI _D S _TRIGGER
Triggers a dataset for reading by the remote MCI task.
Syntax intMci_Ds_Trigger(MCIDS *dataset)

Arguments MCIDS* dataset Pointer to MCI dataset structure.

Returns GOOD.
Errors:
MCI_BAD_CTRL.
MCI_BAD_SNDMBX.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_ACCESS_DENIED.
FLE_OUT_OF_MEMORY.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
16
Remarks The I/O translator tasks uses this function to read a complete dataset. The function
sends an MCI read command to the remote task, which is usually a protocol driver. If
the protocol driver remains in the same application, the dataset control tag is IMX Reference Guide
triggered. If the communication is over a LAN, a mailbox message is generated.
Triggering only the dataset control tag is a faster way of communication.

FactoryLink Programmer’s Access Kit / 483


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _E VENT _C HECK
Calls every program cycle if the MCI events are handled on polling basis and not on
events.
Syntax intMci_Event_Check(void)
Arguments None
Returns GOOD: No errors occurred while processing events.
Errors:
FLE_NULL_POINTER.
FLE_BAD_ARGUMENT.
FLE_NO_CHANGE.
FLE_LOCK_FAILED.
FLE_BAD_TAG.
Remarks This function must be called every program cycle if MCI events are to be handled on
a polling basis. Tasks that cannot start an fl_wait( ) function because other events
outside FactoryLink can occur complete this.
The handling of an MCI event is exactly the same as with the event driven mode of
MCI.

M CI _E VENT _R ETRIEVE
Gets the event arrays for true event driven processing.
Syntax int Mci_Event_Retrieve( TAG **tags, void **datasets, u32 *num,
int (__cdecl **e_fnc)( void *ds, VAL val))

Arguments TAG **tags Pointer to hold internal MCI array of event tags.
void **datasets Pointer to hold internal MCI array of datasets.
u32 *num Pointer to total number of MCI events.
--- **e_fnc Pointer to hold internal MCI array of function pointers.

Returns GOOD: All parameters are filled with the internal MCI pointer values.

Remarks If a task wants to operate in an event driven mode, this function retrieves the events of
the MCI. The following arrays are returned:

484 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

Tags: return a list of all tags that can generate an MCI event. This tag list can be
added to the applications tag list and passed to the fl_wait_.. functions of FactoryLink.
FactoryLink Datasets: return a list of pointers to all registered datasets of the MCI.
This pointer must be used as first parameter of the user function in case of event.
e_fnc: return a list of event function pointers that must be called in case of an MCI
event.
The data of every index of the three arrays correspond to each other. If an MCI event
occurs, the event function with the event index and corresponding data must be
called. For example:
e_fnc[ index]( dataset[ index], val);
The value val can be retrieved from the fl_wait... functions. The application must call
the event function supplied by the MCI, and then the event function automatically
calls the user function registered with the dataset.

M CI _E XIT
Exits the Inter-Task Mail Exchange library for use.
Syntax intMci_Exit( void)
Arguments None
Returns GOOD.
Remarks This function frees all internal resources of the MCI library and should be called just
before exiting the application.

M CI _G ET _B IT _D IR
Gets the direction of bit information within the boundary tags.
Syntax ucharMci_Get_Bit_Dir( MCIDS *dataset 16

IMX Reference Guide


Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Returns the direction of bit data, either


Mci_High_2_Low.
Mci_Low_2_High.

FactoryLink Programmer’s Access Kit / 485


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _G ET _B IT _O FFSET
Gets the bit addressing offset determined by the external device.
Syntax uchar Mci_Get_Bit_Offset( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Returns the bit addressing offset, either 0 or 1.

M CI _G ET _B ND _D IR
Gets the boundary of normal data in the dataset MCI message.
Syntax ucharMci_Get_Bnd_Dir( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Direction of data, either


Mci_High_2_Low.
Mci_Low_2_High.

M CI _G ET _B ND _O FFSET
Gets the boundary addressing offset determined by the external device.
Syntax ucharMci_Get_Bnd_Offset( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Returns the addressing offset, either 0 or 1.

M CI _G ET _B OUNDARY
Gets the boundary of data for this dataset.
Syntax ucharMci_Get_Boundary( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

486 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

Returns Returns the data boundary, which can be one of the following:

MCI_BIT_BND Boundaries on bit basis.


MCI_BYTE_BND Boundaries on character basis (1 char).
MCI_WORD_BND Boundaries on word basis (2 char).
MCI_LONG_BND Boundaries on long basis (4 char).
MCI_DBL_BND Boundaries on double basis (8 char).

M CI _G ET _CDE
Gets the operation code CDE that indicates the operation on the data in case of an
exception write.
Syntax u16Mci_Get_CDE( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Returns the CDE code.

M CI _G ET _CDE_S IZE
Returns the size of the data according to the operation (CDE) specified.
Syntax intMci_Get_CDE_Size( ushort cde)

Arguments ushort cde Operation code.

Returns Size of the tag according to CDE code, which can be one of the following
16
0 MCI_BIT_BND Boundaries on bit basis (1 char 1 bit).

IMX Reference Guide


1 MCI_BYTE_BND Boundaries on character basis (1 char).
2 MCI_WORD_BND Boundaries on word basis (2 char).
4 MCI_LONG_BND Boundaries on long basis (4 char).
8 MCI_DBL_BND Boundaries on double basis (8 char).

Errors:
ERROR CDE code does not exist.
Remarks The size of the tag returned also corresponds to the boundary of the tag.

FactoryLink Programmer’s Access Kit / 487


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _G ET _D S _C TRL
Gets the dataset control tag of this received dataset message.
Syntax TAG Mci_Get_Ds_Ctrl( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The dataset control tag.


Remarks The application does not usually use this function because the MCI always returns
with the correct dataset.

M CI _G ET _H ANDLING
Gets the handling of a write command on the dataset message.
Syntax uchar Mci_Get_Handling( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns None
Remarks The mode of writing, either
MCI_NORMAL_WRITE.
MCI_ENCODED_WRITE.

M CI _G ET _I NDEX
Gets the index of the dataset message in the mailbox queue.
Syntax uint Mci_Get_Index( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The index into the mailbox queue.


Remarks The index into the mailbox queue must not be saved for later use because the indices
in the queue can change. If an MCI event occurs, the MCI library always returns
datasets with the index set. If the application wants to read the dataset later, it must
first search the dataset in the queue and not use a saved index.

488 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _G ET _J OB _S EQUENCE
Gets the job sequence number of the received dataset message.
Syntax u16 Mci_Get_Job_Sequence( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The job sequence number of the received message.

M CI _G ET _L EN
Gets the length of the data in the dataset message in tags according to the boundary
size.
Syntax u16 Mci_Get_Len( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The length of the data in the message.

M CI _G ET _N AME
Gets the name of the dataset control tag as specified in the FactoryLink real-time
database.
Syntax char *Mci_Get_Name( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Pointer to character string containing the dataset control name.


Remarks The name set during registration is returned.
16
M CI _G ET _O RG _H OST _D IR
Gets the originating host data direction. IMX Reference Guide
Syntax ucharMci_Get_Org_Host_Dir( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The data direction of the originating host, either


MCI_HIGH_2_LOW.
MCI_LOW_2_HIGH.

FactoryLink Programmer’s Access Kit / 489


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _G ET _R_B UFFER
Gets the registered buffer parameters of this dataset.
Syntax MSG*Mci_Get_R_Buffer( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Pointer to a FactoryLink MSG structure that contains the parameters of the buffer.
Remarks This function retrieves the buffer parameters which were set during registration of
this dataset. The dataset uses this buffer if it is not overruled by using the functions
Mci_Ds_Prepare( ) or Mci_Set_T_Buffer( ).

M CI _G ET _S ND _M BX
Gets the MCI mailbox tag of this dataset used for sending messages.
Syntax TAGMci_Get_Snd_Mbx( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The tag of the MCI send mailbox for this dataset.
Remarks This tag must be set during dataset registration.

M CI _G ET _S TART
Gets the start address of the data in the dataset message.
Syntax u16 Mci_Get_Start( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The start address of the data.

M CI _G ET _S TATION _I D
Gets the remote station id received from on the dataset message.
Syntax uchar Mci_Get_Station_Id( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Return The unique remote station identification number.

490 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _G ET _T_B UFFER
Gets the buffer parameters currently set on this dataset.
Syntax MSG* Mci_Get_T_Buffer( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Pointer to a FactoryLink MSG structure that contains the parameters of the buffer.
Remarks This function retrieves the buffer parameters currently set on the dataset. This can be
the default parameters (at registration) or a buffer that overruled the default.

M CI _G ET _TYPE
Gets the type of the MCI message.
Syntax uchar Mci_Get_Type( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The type of the message, which can be one of the following:

MCI_QUERY_CMD MCI information message.


MCI_QUERY_RSP MCI information message feed back.
MCI_QUERY_ERROR MCI information message feed back.
MCI_READ_REQ Read request.
MCI_READ_RSP Read feed back.
MCI_READ_ERROR Read feed back. 16
MCI_WRITE_REQ Write request
MCI_WRITE_RSP Write feed back. IMX Reference Guide
MCI_WRITE_ERROR Write feed back.
MCI_RCV_ACT Unsolicited receive active.
MCI_RCV_RDY Unsolicited receive ready.
MCI_RCV_ERROR Unsolicited receive ready.

FactoryLink Programmer’s Access Kit / 491


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _G ET _U_B UFFER
Gets the pointer to the first tag of the dataset data buffer currently set.
Syntax char * Mci_Get_U_Buffer( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Character to the first data tag.


Remarks The buffer set on a dataset for holding data contains an MCIHDR and data. The
application cannot use the original pointer but must retrieve the pointer to the user
function using this function. The original buffer pointer and the data pointer differ
from each other.

M CI _G ET _U DATA _P TR
Gets the pointer to the additional user dataset information buffer.
Syntax char * Mci_Get_Udata_Ptr( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Pointer to the user buffer.

M CI _G ET _U FNC _P TR
Gets the user function pointer called when an MCI event occurs.
Syntax int (*)( MCIDS *)Mci_Get_Ufnc_Ptr( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns Pointer to the user function that takes a pointer to a dataset as parameter.

M CI _G ET _VERSION
Gets the version of the MCI which generated this dataset message.
Syntax uchar Mci_Get_Version( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns The version number of the MCI that generated this dataset message.

492 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _I NIT
Initializes the MCI library for use.
Syntax int Mci_Init( MCISYSTEM *sys)

Arguments MCISYSTEM sys Mci system information.

Returns GOOD.
FLE_OUT_OF_MEMORY.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
Remarks This function must be called before any other function of the MCI library.

M CI _M IRROR
Reverses a character buffer of specified length.
Syntax void Mci_Mirror( char *buf, ushort length)

Arguments char *buf Source buffer for reversing.


ushort length Length of buffer in characters.
16
Returns None

IMX Reference Guide


Remarks Reverses a character buffer of specified length. This function is used internally in the
MCI library for converting data tags of host machines with different data directions.

FactoryLink Programmer’s Access Kit / 493


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _P LACE _D ATA
Places data in the correct position within a tag depending on the direction of the data.
Syntax void Mci_Place_Data( MCIMSG *dataset, char bnd_dir)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


char bnd_dir Final boundary of data.

Returns None
Remarks This function gets the first tag of the message buffer (I/O data area), checks the
operation code (CDE) and places the data in the correct position in the tag, and
converts the tag to the final boundary.
This function is usually used for exception write commands that require only one tag
and, for the most part, is only used internally in the MCI library.
For example, when a message has the CDE code CDE_B0_15 with a specific bit
number set, the bit value is placed on the position of the bit number. The data
direction of the data tag changes to the direction specified.

M CI _Q_D S _ SRCH
Searches the task MCI mailbox queue for a certain dataset.
Syntax int Mci_Q_Ds_Srchl( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns GOOD: Dataset has been found.


Errors:
MCI_NOT_FOUND.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
Remarks This function searches the active MCI messages for a message with the same dataset
control tag. If a message is found, the index of the message in the queue is set on the
dataset.

494 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

Indices in the queue should not be saved for later use because they can change.

*M CI _Q_I NIT
Initializes the task MCI mailbox queue.
Syntax int Mci_Q_Init( void)
Arguments None
Returns GOOD.
Errors:
FLE_OUT_OF_MEMORY.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
Remarks This function initializes the mailbox queue by deleting every message in the queue
except for query messages. It is not advisable for an application to use this function.
This function is called by the MCI library at start up.

M CI _Q_N UM
Determines the number of active MCI messages in the task mailbox queue.
Syntax int Mci_Q_Num( uint *num)

Arguments uint *num Number of messages in the MCI. 16

IMX Reference Guide


Returns GOOD.
Errors:
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.

FactoryLink Programmer’s Access Kit / 495


• MCI REFERENCE LIBRARY
• MCI APIs


Remarks Returns the number of active MCI messages in the MCI mailbox queue of the task.
This number can differ from the total number of messages in the queue.

M CI _Q_Q UERY
Queries a dataset in the queue but does not remove the dataset.
Syntax int Mci_Q_Query( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns GOOD.
Errors:
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
Remarks Before querying the dataset, the index in the queue must be valid. This is
accomplished by using the Mci_Set_Index( ) function. The query function only
returns data of the MCI section, MCIMSG. This means only a limited number of MCI
functions can be used (no functions that operate on the MCIHDR section). Usually
the application does not have to use this function because the MCI library queries the
new message (before calling the user function) with every event.

M CI _R ECV
Retrieves an MCI message from the task mailbox.
Syntax int Mci_Recv( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns GOOD.Errors:
MCI_WRONG_INDEX.
FLE_NULL_POINTER.
FLE_BAD_TAG.

496 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_ACCESS_DENIED.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.
MCI_BAD_CTRL.
Remarks This function reads an MCI message from the task MCI mailbox using the parameters
set on the dataset, such as the index in the mailbox queue. The function removes the
message from the mailbox queue. Prior to calling this function, the task sets a
different message buffer to store the message when it is pulled from the mailbox. If
this is not done, the message buffer defined at registration time for the dataset is used.
The message buffer is contained inside the dataset structure.

M CI _R ESET _B UFFER
Resets the buffer parameters on the dataset message.
Syntax void Mci_Reset_Buffer( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.

Returns None
Remarks Resets the buffer parameters on the dataset currently used. If no other buffer is set, the
default buffer set during registration is used in subsequent MCI calls.

M CI _S END
Sends a dataset to a remote task through the designated send MCI mailbox of the
dataset. 16
Syntax int Mci_Send( MCIDS *dataset)

Arguments MCIDS *dataset Pointer to MCI dataset structure. IMX Reference Guide
Returns GOOD.
Errors:
MCI_BAD_CTRL.
MCI_BAD_SNDMBX.
FLE_NULL_POINTER.
FLE_BAD_TAG.

FactoryLink Programmer’s Access Kit / 497


• MCI REFERENCE LIBRARY
• MCI APIs


FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_ACCESS_DENIED.
FLE_OUT_OF_MEMORY.
FLE_LOCK_FAILED.
FLE_LOCK_EXPIRED.

Remarks This function sends the dataset to the remote task using the send (remote task
mailbox) mailbox which was set at registration time. All parameters must be defined
for the dataset before calling this function. Default parameters, which were set at
registration time, can be set by using the Mci_Ds_Prepare( ) function. After
retrieving default values, specific value can then be set on the same dataset, such as
the command type (which must be set).

M CI _S END _E RROR
Sends an MCI error message to the remote task depending on the type of the dataset.
Syntax int Mci_Send_Error( MCIDS *dataset, u16 error)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


u16 error Error number.

Returns GOOD.
Errors:
MCI_BAD_TYPE.
MCI_BAD_CTRL.
MCI_BAD_SNDMBX.
FLE_NULL_POINTER.
FLE_BAD_TAG.
FLE_NOT_MAILBOX.
FLE_NO_MESSAGES.
FLE_ACCESS_DENIED.
FLE_OUT_OF_MEMORY.
FLE_LOCK_FAILED.

498 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

FLE_LOCK_EXPIRED.
Remarks This function generates an MCI error message depending on the dataset type and
sends it to the remote task. This function is usually used after an MCI event, which
means all relevant parameters are already set on the dataset. No preparation is
required other than the call to the function. The function uses an independent internal
message buffer for sending the message. It returns with the MCI message buffer
parameters reset to NULL.
See Also “Mci_Set_Type”

M CI _S ET _B IT _D IR
Gets the direction of bit information within the boundary tags.
Syntax void Mci_Set_Bit_Dir( MCIDS *dataset, uchar dir)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar dir Bit data direction.

Returns None
Remarks The direction of bit data, either
Mci_High_2_Low.
Mci_Low_2_High.

M CI _S ET _B IT _O FFSET
Sets the bit addressing offset determined by the external device.
Syntax void Mci_Set_Bit_Offset( MCIDS *dataset, uchar offset)
16
Arguments MCIDS *dataset Pointer to MCI dataset structure.
uchar offset Bit addressing offset of ds. IMX Reference Guide
Returns None
Remarks The bit addressing offset can be either 0 or 1.

FactoryLink Programmer’s Access Kit / 499


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _S ET _B ND _D IR
Sets the boundary of normal data in the dataset MCI message.
Syntax void Mci_Set_Bnd_Dir( MCIDS *dataset, uchar dir)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar dir Data direction.

Returns None
Remarks The direction of data, either
Mci_High_2_Low.
Mci_Low_2_High.

M CI _S ET _B ND _O FFSET
Sets the boundary addressing offset determined by the external device.
Syntax void Mci_Set_Bnd_Offset( MCIDS *dataset, uchar offset)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar offset Boundary addressing offset of ds.

Returns None
Remarks The boundary addressing offset can be either 0 or 1.

M CI _S ET _B OUNDARY
Sets the boundary of data of this dataset message.
Syntax void Mci_Set_Boundary( MCIDS *, uchar bnd)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar bnd Boundary to set.

Returns None
See Also Mci_Get_Boundary( )

500 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _S ET _CDE
Gets the operation code CDE that indicates the operation on the data in case of an
exception write.
Syntax void Mci_Set_CDE( MCIDS *dataset, u16 cde)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


u16 cde Operation code.

Returns None

M CI _S ET _D S _C TRL
Sets the dataset control tag on this dataset.
Syntax void Mci_Set_Ds_Ctrl( MCIDS *dataset, TAG ctrl)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


TAG ctrl Dataset control tag.

Returns None
Remarks The application will probably use this function once: just before registering the
dataset. After the dataset has been registered, the application does not have to call this
function.

M CI _S ET _H ANDLING
Sets the handling of a write command on the dataset message.
Syntax void Mci_Set_Handling( MCIMSG *, uchar mode) 16

IMX Reference Guide


Arguments MCIDS *dataset Pointer to MCI dataset structure.
uchar mode Mode for writing.

Returns None
Remarks The mode of writing, either
MCI_NORMAL_WRITE.
MCI_ENCODED_WRITE.

FactoryLink Programmer’s Access Kit / 501


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _S ET _I NDEX
Sets the index of the dataset message in the mailbox queue.
Syntax void Mci_Set_Index( MCIDS *dataset, uint index)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uint index Index in the queue.

Returns None
Remarks This function should not be used by the application directly because the search
function of the MCI library automatically sets the index of the dataset in the queue.

M CI _S ET _J OB _S EQUENCE
Sets the job sequence number on the dataset message.
Syntax void Mci_Set_Job_Sequence( MCIDS *dataset, u16 num)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


u16 num Sequence number to set.

Returns None
Remarks This function is used to set a sequence number on command for keeping track of the
command. The responding task returns the same job number as received.

M CI _S ET _L EN
Sets the length of the data in the dataset message in tags according to the boundary
size.
Syntax void Mci_Set_Len( MCIDS *dataset, u16 len)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


u16 len Length of data.

Returns None

502 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _S ET _N AME
Sets the name of the dataset control tag on the dataset for registering.
Syntax void Mci_Set_Name( MCIDS *dataset, char *name)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


char *name Dataset control tag name.

Returns None
Remarks The dataset control tag name must be set before registering. The tag name must
correspond to the tag id.

M CI _S ET _O RG _H OST _D IR
Sets the originating host data direction.
Syntax void Mci_Get_Set_Org_Host_Dir( MCIDS *dataset, uchar dir)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar dir Originating data direction.

Returns None
Remarks The application should not use this function because the MCI library sets this
parameter.

M CI _S ET _R_B UFFER
Sets the registered buffer parameters of this dataset. 16
Syntax void Mci_Set_R_Buffer( MCIDS *dataset, MSG *buf)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


IMX Reference Guide
MSG *buf Buffer parameters.

Returns None
Remarks This function must be called before registering a dataset. The function sets the default
buffer the MCI library uses if it is not overruled.

FactoryLink Programmer’s Access Kit / 503


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _S ET _S ND _M BX
Sets the MCI mailbox tag of this dataset used for sending messages.
Syntax void Mci_Set_Snd_Mbx( MCIDS *dataset, TAG send)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


TAG send MCI send mailbox tag.

Returns None
Remarks This function must be called before registering the dataset. Afterwards, the function is
not used.

M CI _S ET _S TART
Sets the start address of the data in the dataset message.
Syntax void Mci_Set_Start( MCIDS *dataset, u16 start)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


u16 start Start address.

Returns None

M CI _S ET _S TATION _I D
Sets the remote station id received from the dataset message.
Syntax void Mci_Set_Station_Id( MCIDS *dataset, uchar station)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar station Unique station identification.

Returns None
Remarks This function can be used to set the local station identification number but is not to be
used by the application because this is completed internally by the MCI library. The
station id set during initialization is used.

504 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _S ET _T_B UFFER
Sets the temporary buffer parameters of this dataset. The default parameters are
overruled.
Syntax void Mci_Set_T_Buffer( MCIDS *dataset, MSG *buf)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


MSG *buf Buffer parameters.

Returns None
Remarks This function sets the buffer parameters on the dataset. This overrules the default
buffer parameters, but they are preserved. If the default parameters must be used,
reset the buffer parameters with Mci_Reset_Buffer( ) before executing other
functions.

M CI _S ET _TYPE
Sets the type of the MCI message.
Syntax void Mci_Set_Type( MCIDS *dataset, uchar type)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar type Type of message.

Returns None
See Also “Mci_Get_Type”

M CI _S ET _U DATA _P TR 16
Sets the pointer to the additional user dataset information buffer.
Syntax void Mci_Set_Udata_Ptr( MCIDS *dataset, char *buf) IMX Reference Guide

Arguments MCIDS *dataset Pointer to MCI dataset structure.


char *buf Additional dataset information.

Returns None
Remarks The application sets a pointer to a user defined buffer of a dataset. This buffer is used
for specifying additional dataset information. This data can be retrieved when MCI
events occur. This function must be called before registering the dataset.

FactoryLink Programmer’s Access Kit / 505


• MCI REFERENCE LIBRARY
• MCI APIs


MCI_S ET _U FNC _P TR
Sets the pointer to the user function.
Syntax void Mci_Set_Ufnc_Ptr( MCIDS *dataset, int (*u_fnc)( MCIDS *))

Arguments MCIDS *dataset Pointer to MCI dataset structure.


--- *ufnc User function pointer.

Returns None
Remarks The user function pointer must be set and is called if an MCI event occurs on this
dataset. The user function must accept a pointer to the dataset as parameter and return
an integer.

*M CI _S ET _VERSION
Sets the version of the MCI library on the dataset message.
Syntax void Mci_Set_Version( MCIDS *dataset, uchar version)

Arguments MCIDS *dataset Pointer to MCI dataset structure.


uchar version Version to set.

Returns None
Remarks The application should not use this function because the version is set internally by
the MCI library.

MCI_SYS_GET_FUNCTIONS
Gets the MCI functions supported by this task as registered at initialization.
Syntax ushort Mci_Sys_Get_Functions( MCISYSTEM *sys)

Arguments MCISYSTEM *sys Mci system information.

Returns The supported functionality.

506 / FactoryLink Programmer’s Access Kit


MCI REFERENCE LIBRARY
MCI APIs

M CI _S YS _G ET _M BX
Gets the MCI mailbox tag as registered for this task.
Syntax TAG Mci_Sys_Get_Mbx( MCISYSTEM *sys)

Arguments MCISYSTEM *sys Mci system information.

Returns Returns the tag value of the MCI systems mailbox tag of this task.

M CI _S YS _G ET _S TATION _I D
Gets the station id of this host machine as registered in the MCI library.
Syntax uchar Mci_Sys_Get_Station_Id( MCISYSTEM *sys)

Arguments MCISYSTEM *sys Mci system information.

Returns The station id number of the host machine.


Remarks The station id number must be unique over the LAN.

M CI _S YS _G ET _TASK _I D
Gets the FactoryLink task id currently registered in the MCI library.
Syntax u16 Mci_Sys_Get_Task_Id( MCISYSTEM *sys)

Arguments MCISYSTEM *sys Mci system information.

Returns The FactoryLink task id number.


Remarks This id should match the task id of the current FactoryLink task.
16
M CI _S YS _S ET _M BX
Sets the MCI mailbox tag for registering for this task. IMX Reference Guide
Syntax void Mci_Sys_Set_Mbx( MCISYSTEM *sys, TAG mbx)

Arguments MCISYSTEM *sys Mci system information.


TAG mbx MCI systems mailbox tag.

Returns None
Remarks This task should be called before the Mci_Init( ) function with the mailbox tag used
for MCI communication.

FactoryLink Programmer’s Access Kit / 507


• MCI REFERENCE LIBRARY
• MCI APIs


M CI _S YS _S ET _S TATION _I D
Sets the station id of this host machine for registering in the MCI library.
Syntax void Mci_Sys_Set_Station_Id( MCISYSTEM *sys, uchar station)

Arguments MCISYSTEM *sys Mci system information.


uchar station Unique station number.

Returns None
Remarks This function must be called before the Mci_Init( ) function with an unique station
number on the LAN.

M CI _S YS _S ET _TASK _I D
Sets the FactoryLink task id for registering in the MCI library.
Syntax void Mci_Sys_Set_Task_Id( MCIDS *dataset, u16 id)

Arguments MCISYSTEM *sys Mci system information.


u16 id FactoryLink task id number.

Returns None
Remarks The id number the fl_init_app( ) returns must be passed with this function. This
function must be called before the Mci_Init( ) function.

508 / FactoryLink Programmer’s Access Kit


Appendix





PAK Conversion
Considerations

This appendix contains information on converting from earlier versions of FactoryLink to the
present version. Some of this information was presented in previous Release Notes, which
should be used only if it still applies to your situation.

C ONVERTING F ACTORY L INK PRE -7.0 PAK TASKS


Two changes have been made to the PAK/EDI-PAK Libraries that affect custom tasks and EDI
drivers. There are also significant modifications to the EDI task and EDI libraries to support
EDI and EDI drivers on multi-processor machines. For FactoryLink versions 6.5.0 and 6.6.0,
this requires all third-party EDI drivers be recompiled with the new EDI-PAK libraries. In
addition, a change to the "fl_get_proc()" function in the PAK Libraries requires that any
custom task making these calls be updated.

While these are the only two changes that are known to require custom tasks and custom EDI
Drivers to be rebuilt, it is recommended that all custom tasks be rebuilt with each new release
of FactoryLink.

A DDING M ULTILINGUAL S UPPORT


Several changes in the international version of FactoryLink affect third-party drivers and PAK
tasks created with FactoryLink pre-6.0.4 versions. Review the changes and follow the
instructions below to set up FLINK and convert your third-party driver or custom PAK tasks to
run with the international FLINK.

Appendix

FactoryLink Programmer’s Access Kit / 509


• PAK CONVERSION CONSIDERATIONS
• Adding Multilingual Support


The following table shows the changes from previous FactoryLink versions to the current
version. Directories for the supported languages, English, French, and German display as \EN,
\FR, and \DE, respectively.

Old Directory New Directory Comments

n/a (new dir) \dll\xx\ Contains language-specific


(xx represents the DLL files. May contain files
languages, EN, FR, or other than DLLs. Only a
DE) directory that matches the
installed languages displays as a
subdirectory

\msg\english \help\xx\ Contains *.HLP files.Only a


(xx represents the directory that matches the
languages, EN, FR, or installed languages displays as a
DE) subdirectory.

n/a (new subdir) \key\ Contains directories for each


language installed.

n/a (new subdirs) \key\en\ Contain *.KEY files for each


\key\fr\ language installed.
\key\de\

n/a (new dir) \mps\ Contains directories for each


language installed.

n/a (new subdirs) \mps\en\ Contain *.MPS files for each


\mps\fr\ language installed.
\mps\de\

\msg\ \msg\en\ Contain *.TXT files. Only a


\msg\fr\ directory that matches the
installed languages displays as a
\msg\de\ subdirectory.

510 / FactoryLink Programmer’s Access Kit


PAK CONVERSION CONSIDERATIONS
Automated Conversion of pre-6.0.4 Driver or PAK Task

A UTOMATED C ONVERSION OF PRE -6.0.4 D RIVER OR PAK TASK


Complete the following procedure to convert third-party drivers or PAK tasks:

1 It is recommended you install FactoryLink 6.6.0 to a clean directory structure. Do not


install over an existing FLINK for versions prior to 6.0.3. Complete the installation
following the FactoryLink installation instructions.

2 Install your third-party driver task or PAK task according to vendor instructions. After
installation, make any associated changes per the task installation instructions.

Note: For conversion from FactoryLink 6.0.4 or earlier, it is possible


that the installation will fail if the previous FLINK directory structure is
expected. This directory would be in the form {FLINK}\msg\<language>
as in {FLINK}\msg\english. If the installation fails, create this directory
manually and reinstall.

3 Run the FactoryLink mv_pak utility. The mv_pak utility copies your driver and/or PAK
files in the correct directory structure and renames the initial *.txt files to *.bkt, *.hlp files
to *.bkh, and *.key files to *.bkk.

4 If an English subdirectory was created in Step 2, delete it now.

Appendix

FactoryLink Programmer’s Access Kit / 511


• PAK CONVERSION CONSIDERATIONS
• Converting IMX RAPD PAK Drivers to MCI3


C ONVERTING IMX RAPD PAK D RIVERS TO MCI3
Prior to FactoryLink 7.5, RAPD drivers used IMX libraries. The user must manually update
drivers written for the IMX RAPD PAK in order to compile with the MCI RAPD PAK. The
steps to convert a RAPD driver are:

1 Change all references to header files “imx.h”, “imx_fmt.h”, and “imx_int.h” to “mci3.h”,
“mci3_fmt.h”, and “mci3_int.h”.

2 Change all references to RAPD PAK functions that include the string “imx” to “mci”. Be sure
to preserve the case of the string. For example, “IMX” becomes “MCI”, and “Imx” becomes
“Mci”.

3 Update all calls to Mci_Send(), Mci_Send_Error(), and Mci_Recv() to include the new
MCISYSTEM* argument. Use the MCISYSTEM pointer returned by the driver's call to
Mci_Init().

4 Add support for command line argument "-LS#", where '#' is the logical station number. This
is required in order for the user's driver to support mailbox marshalling. Initialize the RAPD
PAK with this logical station number via function Mci_Sys_Set_Station_Id(), which must be
executed prior to call Mci_Init(). If the logical station is not set on the command line, initialize
the logical station to 0.

5 Change the driver linkage from “imx.lib” to “mci3.lib”.

6 Compile all modules using the /MD flag, which generates code using the multithreaded DLL
run-time library.

Once the above steps have been completed, the driver should compile and run without error.

512 / FactoryLink Programmer’s Access Kit






Index

A CDB (configuration database) 337

Index
AC files 339 CDBLIST utility 88, 89
comments in 65 CDE codes 463
created 59, 64 block data commands 463
described 39, 59, 64 data header direction 463
example 83 exception data commands 463
example (external editor program) 85 CDE operation codes 445, 459
format 65 CFGPAK (Configuration PAK) 327
format (external editor program) 85 change-read call 34
with CONFIG PAK 329 change-status bits 32, 127
accessing CDBs 339 change-wait call 34
acctmgr -c -d utility 337 changing name of tag definition 368
adding tag definitions 366 common functions in interface library 452
analog data type 31, 53 compiling
Application Editor 329 BASIC PAK 18
archive (CT) 104 RAPD 439
arrayed tags compiling and executing Skeleton Task 23
described 47 CONFIG PAK
examples 49 error messages 371
arrays 46 message box type requests 372
attribute catalog return codes/error messages 370
See AC files storage entities 328
attribute catalogs validation error reporting 373
with CONFIG PAK 337 configuration architecture
BASIC PAK 45
CONFIG PAK 328
B configuration database (CDB) 337
binary CT generation utility 111 configuration database API 341
block read function 452 configuration database tables 52
block write function 455 configuration environment 59
design database tables 59
C setting up 62, 103
calling and return conventions 131 testing 61, 88

FactoryLink Programmer’s Access Kit / 513


• INDEX



Configuration PAK (CFGPAK) 327 database table
configuration panels 45 configured 52
configuration sessions 329 contents 59
constructing a task 57 converting to CTs 61
control panels 46, 63 defined 66
conversion process design 59, 63
debugging 112 format 54
conversion script task-specific 54, 63
described 105 Dataset Definition table 449, 450
format 105 dataset registration 466
sample 110 datasets 449
converting IMX messages 465 passing and processing 450
cross-reference (XREF) database table 54 dBASE
CT access 135 compatible database library 76
CT archive 104 compatible database manager 88
header 104 deleting a tag definition 369
index 105 designing panels 63
record 104 designing task-specific database tables 63
CT files digital data type 31, 53
converting database tables 61 direct tag processing 140
created 111 actions
described 39 loading 143
CTG files processing 145
created 104 records 143
described 104 removing 146
example 109 data structures 141
tag constant fields 109 exit codes 147
CTG script instance 141
format 105 instantiating 141
CTGEN utility 61, 105, 111 library services 140
CTLIST utility 111 directions of data 462
domain
D and task-specific tables 63
data directions 462 driver communication 471
data structure hierarchy with CONFIG PAK 331
data transfer E
examples 36 editor program execution from CM 85
data types 53 environment variables 18
database access services 126 error code 454, 457, 461

514 / FactoryLink Programmer’s Access Kit


INDEX

error numbers 132 library functions 475


exception processing 34 messages
exception writes 458 converting 465
encoded 459 specifications 441
normal 458 information panels 46, 63
testing 459 informing FactoryLink about new task 87
exit the calling process 119 initialize

Index
external configuration 329 calling process 115
installation
F BASIC PAK 18
FactoryLink CONFIG PAK 327
API 26 RAPD 437
Kernel 27 interface library
operation 25 common functions 452
failure scenarios with CONFIG PAK 330 inter-process communication (IPC) 125, 130
field handles 342 IOX driver communications 471
FL_LOCK
relationship to FL_UNLOCK 217 K
FLAPP Kernel 27
directory files 55, 56 Kernel and library services
with CONFIG PAK 329 database access 121
FLINK KEY files
directory 437 created 39, 60, 86
directory files 42 described 60, 86
with CONFIG PAK 329 example 87
floating point data type 31, 53 missing 88
flow of code 467
forced-write call 33, 40 L
functions LANS communication and IMX 466
block read 452 layout of panels 63
block write 455 library functions
exception writes 458 BASIC PAK
unsolicited receive 460 CT Access 135
Direct Tag Processing 140
I Kernel Interface 122
I/O functionality 452 Message Translation 159
IMX Normalized Tag Reference 148
interface library 441 Object CT Access 137
LANS communication 466 Path Manipulation 153

FactoryLink Programmer’s Access Kit / 515


• INDEX



CONFIG PAK 333 N
Domain Field API 342 normalized tag reference services 148
Exception Handling API 370
Field (configuration data) API 344
Object Configuration Database API 362
O
Select Field API 343 Object CT access 137
Sequence Field API 343 OBJECT database table 54
Tag Definition API 363 and task-specific tables 63
data manipulation functions 478 open architecture 17
IMX dataset functions 477 operation codes
IMX system functions 476 CDE 445
RAPD
API functions 479 P
general IMX functions 475 panels
IMX header functions 476 control 46, 63
IMX message functions 477 designing 63
library services information 46, 63
configuration session API 334 layout 63
interface services 122 parameters
locking the database 128 error code 454
long analog (longana) data type 31, 53 mm_msg 443
mm_type 447
M mm_user1 448
mailbox communications 442 mm_user2 448
mailbox data type 31, 54 passing a dataset 450
mailbox message data structure (MBXMSG) 442 path manipulation 153
mailbox message datasets 449 allocating/destroying path 155
mailbox services 125 building and representation 153
message data type 31, 54 converting to/from 155
message translation services 159 environment variables 154
loading files 160 files
managing multiple trees 161 creating/deleting 156
translating files 161 getting information 158
mm_msg parameter 443 searching for 157
mm_type parameter 447 modifying 156
mm_user1 parameter 448 path names
mm_user2 parameter 448 components 153
multi-user access to CDB 358 predefined data types 31
predefined tags. See tag name

516 / FactoryLink Programmer’s Access Kit


INDEX

primary key 329 procedure 22


printing tag definitions 365 verifying 22
processing a dataset 450 software design model
Programmer’s Access Kit (PAK) flowchart 58
described 17 station identification number 466
installation 18 steps in reading configuration data in CDB 347
software requirements 18 syntax samples 47

Index
protocol driver default message buffer 469 System Configuration Table 26
protocol driver design example 467
protocol message 453 T
tag definitions
R adding 366
RAPD changing name 368
principle with IOX 438 deleting 369
RAPD principle illustrated 438 printing 365
read calls 33 reading 364
reading configuration from CDB 347 updating 367
reading tag definitions 364 writing 365
Real-Time Database tag modification routines 329
described 31 tag name
locking 128 assignment 46
structure of tags 32 structure 47
Run-Time Manager 26, 113, 119 tag names 46
and CT files 39 tag number 128
interaction with other tasks 26 tags
run-time requirements 113 described 52
run-time task name storage 52
writing 61 predefined 52
structure 32
S task
selection criteria 347 constructing 57
setting up configuration environment 62, 103 task construction flowchart 62
setup script 18 task/Kernel session management 122
Skeleton Task attaching/detaching from Kernel 122
compiling and executing 23 database access 126
CONFIG PAK 333 error reporting 131
converting script 22 mailbox 130
described 21 miscellaneous session services 125
integrating 22 obtaining environment access 124

FactoryLink Programmer’s Access Kit / 517


• INDEX



Real-Time Database access 127 writing a RAPD driver 467
signals 125 writing configuration to CDB 350
VAL union structure 128 deleting row from CDB 356
tasks inserting row 350
data transfer methods updating row in CDB 353
examples 36 writing tag definitions 365
described 25, 35 writing the run-time task 61
task-specific database tables 54
design 63 X
task-specific tables XREF database table 54
and domain 63
and OBJECT tables 63
termination flag
check status 118
testing
configuration environment 61, 88
TITLES file 61, 87
with CONFIG PAK 330
triggers 40
and forced writing 40
TYPE database table 53

U
unlocking the database 128
unsolicited receive function 460
updating a tag definition 367
utilities
acctmgr -c -d 337
CDBLIST 88, 89
CTGEN 61, 105, 111
CTLIST 111

V
VAL union structure 128

W
wait bits 34, 127
write calls 33

518 / FactoryLink Programmer’s Access Kit

You might also like