1. Terms of Use
Because of the variety of uses of the information described in this manual, the users of, and those responsible for applying this information must satisfy themselves as to the acceptability of each application and use of the information. In no event will SoftPLC Corporation be responsible or liable for its use, nor for any infringements of patents or other rights of third parties which may result from its use.
SOFTPLC CORPORATION MAKES NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE CONTENTS HEREOF AND SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE.
SoftPLC Corporation reserves the right to change product specifications at any time without notice. No part of this document may be reproduced by any means, nor translated, nor transmitted to any magnetic medium without the written consent of SoftPLC Corporation.
SoftPLC, TOPDOC, and TOPDOC NexGen are registered trademarks of SoftPLC Corporation.
© Copyright 2005 SoftPLC Corporation ALL RIGHTS RESERVED
First Printing: July, 2005
Latest Printing: August, 2026
SoftPLC Corporation
25603 Red Brangus Drive
Spicewood, Texas 78669
USA Telephone: 1-800-SoftPLC
URL: http://softplc.com
Email: support@softplc.com
2. Overview
2.1. Introduction
This document describes the installation, usage, and functionality of the SoftPLC 5.x C++ Toolkit for SoftPLC version 5.x.
2.2. Host System Requirements
| Requirement | Specification |
|---|---|
Operating System |
|
Processor Architecture |
NOTE: Apple Silicon and ARM64 hosts can run this image via built-in Docker emulation, but compilation performance will be significantly degraded. |
Container Engine |
Docker Engine (Linux) or Docker Desktop (macOS / Windows) installed and active. |
System Memory (RAM) |
4 GB minimum allocated to the Docker daemon. 8 GB or more is recommended for parallelized multi-core ( |
Disk Space |
10 GB of free space minimum to accommodate the SoftPLC Toolkit docker image which contains cross-compiler toolchains. Space is also required for your source code and build artifacts. |
2.3. Definitions
- TLM
-
A TOPDOC Loadable Module that you write in C++. It can implement a driver and/or one or more custom ladder instructions. It is executable within SoftPLC only, so it must be downloaded to a runtime CPU.
- TLI
-
A TOPDOC Loadable Instruction is a custom ladder instruction written in C++ that resides in a TLM.
3. Usage
The SoftPLC C++ Toolkit builds TLMs (Topdoc Loadable Modules) for the SoftPLC runtime. The toolkit is a freely downloadable self-contained Docker image that carries the cross compilers, the toolkit headers and libraries, the CMake build system, and this documentation. You do not install a compiler toolchain on your workstation — you run the toolkit’s docker image and allow it to access one or more working directories on your development computer. This keeps your development computer free from installations that you may not need to use all the time.
This is a C++ toolkit, meaning a C++ compiler is used for compiling the main source file of the TLM. However if you have C code that you want to link into the TLM this is possible using either of two methods. 1) you may compile your C code using the C++ compiler, and this is sometimes quite easy, just rename the files to have a .cc extension or .cpp extension. 2) you may compile your C code with the included C compiler and simply link those outputs into the TLM. You will not be able to use APIs in the runtime from C however, but you can include complete C libraries that don’t look upwards into the runtime. CMake is the supported build tool. To compile a C file, simply make sure its file extension is '.c' and CMake will automatically know to use the C compiler on that file. Again, the main file must be C++. CMake is a wonderfully powerful build system.
3.1. What you need
-
Docker — Docker Desktop on macOS or Windows, or Docker Engine on Linux.
-
Either the
standup-toolkit.shscript (command-line workflow) or VS Code with the Dev Containers extension (GUI workflow). Either way, the toolkit image is pulled from Docker Hub automatically by Docker the first time you try to use the toolkit image.
3.2. Two directories: source and build
Every TLM build uses at least two directory trees, which are mounted into the container:
| Host role | In container | Contents |
|---|---|---|
source |
|
your TLM’s source tree — the |
build |
|
an initially empty directory that receives all build output; keep it separate from source and delete it any time |
A common layout keeps one build directory per target architecture:
mytlm/ <- source tree (mounted at /source within the container) CMakeLists.txt mytlm.cc build-arm64/ <- build directory (mounted at /build within the container)
3.3. Starting the toolkit
3.3.1. Option A — command line (standup-toolkit.sh)
From your build directory, run the script with the path to your source tree as the only command line argument.
Your current directory becomes /build; the argument becomes /source:
$ cd ~/tlms/mytlm/build-arm64 # ~/tlms/mytlm/build-arm64 becomes /build
$ standup-toolkit.sh ~/tlms/mytlm # ~/tlms/mytlm becomes /source
You land in a shell inside the container, already in /build.
3.3.2. Option B — VS Code Dev Containers (friendlier)
This option runs the whole toolkit inside VS Code — you edit your source, build,
and get a terminal that is already inside the container, all in one window and with
no docker commands to type. It takes a one-time setup, after which starting the
toolkit is just a click or two.
-
Install Docker (see What you need above) and Visual Studio Code from https://code.visualstudio.com.
-
Start VS Code and install Microsoft’s Dev Containers extension: click the Extensions icon in the left tool bar (or press
Ctrl+Shift+X, orCmd+Shift+Xon macOS), typeDev Containersin the search box, and press Install on the extension published by Microsoft.
-
In the top folder of your TLM project, create a subfolder named
.devcontainer, and inside it a file nameddevcontainer.jsoncontaining exactly this:{ "name": "SoftPLC Toolkit 5", "image": "softplc/toolkit:trixie_latest", // Your TLM source is mounted at /source; builds go in /build (created on the // host first so the bind mount is not root-owned). "workspaceMount": "source=${localWorkspaceFolder},target=/source,type=bind", "workspaceFolder": "/source", "initializeCommand": "mkdir -p ${localWorkspaceFolder}/build-arm64", "mounts": [ "source=${localWorkspaceFolder}/build-arm64,target=/build,type=bind" ], // Run as the image's non-root "builder" user so build outputs are owned by you, // not root. On Linux, updateRemoteUserUID makes VS Code rewrite builder's // uid/gid to match your host user automatically -- nothing to hard-code. (On // macOS/Windows Docker Desktop maps ownership for you, so this is a no-op there.) "remoteUser": "builder", "updateRemoteUserUID": true, "customizations": { "vscode": { "extensions": ["ms-vscode.cpptools", "ms-vscode.cmake-tools"] } } } -
In VS Code, choose File > Open Folder… and open your TLM project’s top folder (the one that now contains the
.devcontainersubfolder). -
Reopen that folder inside the container, either way:
-
Click Reopen in Container in the pop-up notification VS Code shows at the lower-right, or
-
Open the Command Palette — press
F1(orCtrl+Shift+P, orCmd+Shift+Pon macOS) — typeDev Containers: Reopen in Container, and press Enter.
The first time, VS Code downloads the toolkit image and starts the container, which can take a few minutes; later starts are quick. When it finishes, the whole VS Code window is running inside the toolkit.
-
-
Open a terminal with Terminal > New Terminal. It opens in
/source; typecd /buildto reach the build directory, then follow Building a TLM below. -
Optional — build with one keystroke. If you would rather press a key than type
cd /build && make, create a second subfolder named.vscodebeside.devcontainer, and in it a file namedtasks.jsoncontaining this:{ "version": "2.0.0", "tasks": [ { "label": "Build TLM", "type": "shell", "command": "make", // The task runs inside the container, so this is the container's /build. "options": { "cwd": "/build" }, // Makes this the default build task, so Ctrl+Shift+B runs it. "group": { "kind": "build", "isDefault": true }, // Turns compiler messages into clickable entries in the Problems panel. "problemMatcher": "$gcc" } ] }Now Terminal > Run Build Task — or just
Ctrl+Shift+B(Cmd+Shift+Bon macOS) — runsmakein/build, and any compiler error becomes a clickable link that opens the offending line in the editor. You still runmakemake.shby hand the first time (see Building a TLM); if you build for one architecture all day, you can add it as a second task the same way.
To return to normal (non-container) VS Code, run Dev Containers: Reopen Folder
Locally from the Command Palette, or just close the window.
See Leaving the container for what becomes of the container itself.
3.4. Building a TLM
Inside the container, from /build, configure with makemake.sh, then build
with make:
$ /opt/softplc/c++-toolkit-5/bin/makemake.sh ARCH /source
$ make
makemake.sh runs CMake for you. Its first argument is the target
architecture (ARCH) which is the CPU type you are building for. Pick from here:
| ARCH | Target |
|---|---|
|
64-bit ARM |
|
64-bit x86 |
|
Think of the first argument as the architecture, not a specific board. The
rare case of two different CPU boards that share one architecture can be handled
inside the TLM’s own |
The second argument is always /source.
make produces your TLM as a shared object named <name>.tlm.so in the build
directory.
3.5. Deploying to the SoftPLC
There are two ways to get your TLM onto the target, depending on where you are in development.
3.5.1. Quick dev-test loop
While iterating, copy the freshly built <name>.tlm.so straight into the running
SoftPLC’s /SoftPLC/tlm/ directory:
$ scp <name>.tlm.so root@<target-ip>:/SoftPLC/tlm/
Fast to iterate, but it drops an unmanaged file onto the target.
3.5.2. Release install (recommended)
For the final form of a TLM, ship it as a Debian package so it is version-tracked
and cleanly removable by the target’s package manager. Build the package with
make package, then install it in two commands — copy it to the target’s /tmp,
and dpkg -i it there over SSH:
$ make package # builds tlm-<name>_<version>_<arch>.deb
$ scp tlm-<name>_<version>_<arch>.deb root@<target-ip>:/tmp/
$ ssh root@<target-ip> dpkg -i /tmp/tlm-<name>_<version>_<arch>.deb
The package installs the same <name>.tlm.so into /SoftPLC/tlm/ and records its
dependency on softplc-runtime.
3.6. Your TLM’s CMakeLists.txt
Each TLM is an ordinary CMake project with its own CMakeLists.txt. The toolkit
supplies the cross toolchain, compiler flags, and runtime libraries through a
single include( tlm ); your file names the TLM and its sources. A minimal
example:
set( TLM mytlm )
project( ${TLM} )
cmake_minimum_required( VERSION 3.10 )
include( tlm ) # toolkit flags, libraries, toolchain
set( SOURCES mytlm.cc )
add_library( ${TLM} SHARED ${SOURCES} )
set_target_properties( ${TLM} PROPERTIES PREFIX "" SUFFIX ".tlm.so" )
target_link_libraries( ${TLM}
${LIBSTATE_LOGIC_LIBRARY}
rt
)
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${TLM}.tlm.so
DESTINATION /SoftPLC/tlm/ )
include( CPack ) # enables `make package` (the .deb)
3.6.1. Libraries you can link
Add any of these to your TLM’s target_link_libraries() call. The first two are
mandatory for every TLM; link the rest only if you use them. This list is a
starting point and will grow.
| Link with | Mandatory | Description |
|---|---|---|
|
Yes |
TLM entry point and FSM state-logic support; required by every TLM. |
|
Yes |
POSIX real-time library (timers, high-resolution clocks, shared memory). |
|
No |
Serial / communications I/O support (backs the comio API). |
|
No |
S-expression parsing and serialization (used by the DSN lexer). |
|
No |
Datatable (td) access library. |
|
No |
POCO C++ libraries from |
|
No |
Boost C++ libraries from |
3.6.2. Other cases
CMakeLists.txt is also where you handle the less common needs:
-
Third-party C library from source — add its sources or targets with the usual CMake commands; the C++ compiler builds well-formed C without complaint.
-
Board-specific ("machine") variation within one architecture — define the board symbol here (for example with
target_compile_definitions), so that architecture selection (makemake.sh) and board selection (CMakeLists.txt) stay separate concerns.
3.7. Rebuilding
Edit your sources in your usual editor — outside the container, or in the VS
Code Dev Container — then, in the container’s /build, just run make again.
You only re-run makemake.sh when you change CMakeLists.txt or switch
architecture.
3.8. Leaving the container
How you leave depends on how you started, but either way the build output in your host’s build directory remains — it lives on the host, not in the container.
3.8.1. From the command line (Option A)
Type exit. The container stops and is removed, because standup-toolkit.sh
starts it with --rm. Nothing of the container survives, so anything you
installed inside it with apt is gone; next time you get a clean container.
3.8.2. From VS Code (Option B)
Run Dev Containers: Reopen Folder Locally from the Command Palette, or simply
close the VS Code window. VS Code manages the container’s life for you.
Unlike Option A, the container is not started with --rm: VS Code keeps it (and
a small derived image it builds for your project) so that reopening the folder is
fast. You can therefore find it later with:
$ docker ps -a
If you want it gone — to reclaim disk space, or to start from a clean container — stop and remove it by the name shown there:
$ docker rm -f <name>
Reopening the folder in VS Code simply builds a fresh one.
4. C/C++ Function Categories
The code you write and the code that you use for a TLM can be categorized as below:
| Purpose | Description |
|---|---|
How to code a TLM. These are C++ constructs that comprize or make a body of C++ into a TLM. For example, a TLM must declare a TLM class instance in a specific way. |
|
Functions that live in the SoftPLC runtime that are callable by a TLM. The TLM when calling these functions actually enters the SoftPLC runtime for services such as reading the datatable, changing operating mode, etc. They are named with an Hlp prefix and for that reason are called Helper functions. Helper functions return quickly back into the calling TLM. |
|
The toolkit headers live in opt/softplc/c++-toolkit/h. So this is everything the toolkit headers declare. This includes functions not included in the two rows above, plus the two rows above. |
|
Undocumented C/C++ Support |
The toolkit Docker image as also includes libraries and headers that are not documented in this document, but are none-the-less very useful and are well documented on the web. These include but are not limited to libxml2, libpoco-dev, libboost-dev and several other standard linux C and C++ libraries. |
5. TLMs
TLM is an acronym for TOPDOC Loadable Module. A TLM is written in C or C++ and can be used to extend SoftPLC. TLMs can implement I/O drivers and/or new Ladder instructions (TLIs).
The following section is for developers familiar with previous versions of the SoftPLC toolkit. If this is your first experience with the toolkit, you may skip past the next section.
5.1. Differences from Version 3.x Toolkit
Read this section only if you are familiar with writing TLMs for version 3.x. There are only a handful of changes in version 4.x from version 3.x:
-
struct requestuses an anonymous union, dropping the "a" member. This means that constructs likereq→a.cmdcodebecomereq→cmdcode. -
LMENTRY dispatch( void* reqp, void* datap );becomes
ERRCODE dispatch( request* reqp );
This means thatdatapis no longer used. The only place where this was previously used was in the command line arguments to the TLM. Those are now available throughreqp→init.cmdLine -
FUNCTION_TABLE does not need to be public. Instead, you must supply your function table array to the
TLM_MAIN_ENTRY( aFunctionTable )macro exactly one time. SeetlmExample.c. -
Interrupts are not supported as part of the Helper Function API. You must write a linux kernel driver to support interrupts.
-
There are new thread Helpers, see threads.
-
There are additional dispatch command codes, but you do not need to concern yourself with these. They are only used for loading and unloading.
-
There are new library load and unload Helpers, see here.
-
HlpPrintf() or printf() statements should not start with a '\n' character but should now end with a '\n' character instead. Unless you follow this your output will look odd and unconventional, and may even not print when you think it should.
-
In version 3.x, unless you defined
NOHELPERSon the compiler command line, thesplcstdc.hfile would remap stdio functions to helpers. So previously the absence of theNOHELPERSdefine would cause remapping. Now, you must defineREMAP_STDIOon the compiler command line to get remapping. This is done for you in the templatebuild.xmlfile. -
Instead of using
WORDandfloatto represent PLC datatable types, use PLCINT and PLCFLOAT respectively. PLCINT replaces WORD, but PLCINT is signed whereas WORD was not. This is now consistent with the interpretation of SoftPLC’s 16 bit integer type, but could lead to sign extension problems that were not present before this change. -
Makefiles are no longer the standard build environment. We have switched to Ant. You can continue to use your own Makefile, but do not ask us to support you on this. Note that
Makefileson linux require true 'tab' characters for the indents, spaces will not work, so check your text editor for this capability.
5.2. TLM File Type
A TLM is a file that contains executable code and data. It gets loaded at
startup time by SoftPLC. The format of a TLM is that of a linux "shared object"
file. TLMs have the file extension of .tlm.so. So a valid TLM
filename would be tealware.tlm.so. On Linux filenames are case
sensitive.
| TLMs on SoftPLC version 4.x always use all lower case filenames. |
A TLM is made known to SoftPLC by a line entry in the MODULE.LST
file. This file lists all the SoftPLC TLMs. Each entry in the
MODULE.LST file has to start with either the keyword
DRIVER or the keyword MODULE. The format of
MODULE.LST is discussed in detail in the upcoming section on MODULE.LST.
5.3. Dispatch Function
All TLMs must define a special C function with the following name and prototype:
| TLM Entry Point Function |
|---|
Function dispatch() is a TLM’s main entry point which is called by SoftPLC. There is no main() function in a TLM; dispatch() acts as a main() function for TLMs. However, whereas a main() function within a normal program is called only once by the operating system when a C/C++ program is first started, the dispatch() function will be called many times by SoftPLC at runtime. In turn, dispatch() can call other functions within the TLM to carry out the various activities.
Function dispatch() gets a single argument, a pointer to a
RequestPacket union. The request
packet itself resides within SoftPLC. It is filled in by SoftPLC just before
calling a TLM’s dispatch() function. The first field in the request packet is a
command code, int cmdcode that tells the TLM what action is to be
performed. Command specific data will follow the command code; the layout of
each variant is given in the RequestPacket union.
The dispatch() function returns an ERRCODE type, and should return a value of SUCCESS to indicate the TLM successfully handled the dispatch, or something other than this to indicate failure.
Each TLM must be written to return from dispatch() as quickly as possible, because the call to dispatch() is made on the same thread as the main ladder thread within SoftPLC.
| When servicing the command codes, it is necessary that your TLM return to SoftPLC as quickly as it can. No TLM should hog the CPU or sit in a loop wasting time or waiting for something. |
The only exception to the above rule is in the FNC_INIT handler.
This command code is the first one sent, and it is sent only once and it is
before SoftPLC is fully operational. It is allowable to wait for hardware to be
initialized, or to open and read from disk files in this command code
handler.
From within dispatch(), a switch() is used to branch out to the various
command functions based on command code: reqp→cmdcode. This way
each command code handler may be implemented by a separate C function. Of course
this is not the only choice. You can service the various
command codes in line within the
dispatch() function’s switch() statement.
ERRCODE dispatch( request* reqp )
{
ERRCODE ec=SUCCESS;
int cmdcode = reqp->cmdcode;
switch( cmdcode )
{
case FNC_INIT:
// add init code here
break;
case FNC_DEINSTALL:
// add de-install code here
break;
case FNC_UNLOAD:
// add unload code here
break;
case FNC_SCAN:
// add scan code here
break;
case FNC_SETMODE:
// add setmode code here
break;
case FNC_CHECKPOINT:
// add checkpoint code here
break;
case FNC_BXFER_SUBMIT:
// add bxfer code here
break;
default:
ec = ERROR_CMDCODE_NOT_HANDLED;
}
return ec;
}
5.3.1. Command Codes
With few exceptions, whenever SoftPLC needs to send a command code to the
dispatch() function of a TLM, it sends the same command code to all interested
TLMs in the same order or sequence as determined by the order the TLMs appear
in the MODULE.LST file. This sequential calling of all the TLMs is
called a dispatch loop. Below are the command codes and their
purpose.
| Command Code | Purpose |
|---|---|
FNC_INIT |
FNC_INIT is dispatched only once at startup time. This dispatch loop happens just as the TLMs are loaded. At this point, the TLMs have a chance to check and initialize the I/O hardware, install interrupt vectors, decide whether FNC_CHECKPOINT handling is needed (by setting bit 0 of DrvCapability), decide whether FNC_BXFER_SUBMIT handling is needed (by setting bit 1 of DrvCapability), and report errors indicating whether the system should be started up or not. If any TLM returns other than SUCCESS, the system will not start up. |
FNC_SCAN |
FNC_SCAN is dispatched repeatedly when SoftPLC is in RUN mode. This is where SoftPLC and the TLMs execute all the control logic for the application. During this dispatch loop each TLM that is defined as a DRIVER in the MODULE.LST file is called with the FNC_SCAN command code. Those TLMs that are defined as MODULEs rather than DRIVERs are not called with this command code. If a TLM is implementing Ladder Instructions (TLIs) and not intending to be an I/O driver, then it may be declared as a MODULE in MODULE.LST rather than as a DRIVER. |
FNC_CHECKPOINT |
FNC_CHECKPOINT may be sent several times during a program scan depending on the size of the ladder program that SoftPLC is executing. During this dispatch loop, TLMs capable of servicing FNC_CHECKPOINT requests are called. A FNC_CHECKPOINT request is sent to the interested TLMs only if SoftPLC is in one of RUN, REM_RUN, TEST, or REM_TEST modes that perform ladder program execution. Generally it is like the FNC_SCAN dispatch loop, but rather than occurring only once per scan, it can occur several times per scan. It is a way for an I/O driver to get control more frequently if it needs to check hardware that often. |
FNC_SETMODE |
FNC_SETMODE is dispatched whenever SoftPLC detects a change in operating mode. A TLM should record the new mode and change its operating conditions accordingly. Most importantly, OUTPUTS should be turned off in this command code handler if the new mode is not OPM_RUN or OPM_REM_RUN. |
FNC_BXFER_SUBMIT |
FNC_BXFER_SUBMIT is dispatched when SoftPLC executes a Block Transfer ladder instruction. During this dispatch loop, TLMs capable of handling block transfers are called with the FNC_BXFER_SUBMIT request. Currently block transfer is only supported by the AB KTx driver. |
FNC_DEINSTALL |
FNC_DEINSTALL is dispatched whenever SoftPLC wishes to unload a TLM. The TLM is to release any resources it owns, such as open files, interrupt vectors, dynamically allocated memory, etc. The TLM will not be used after this dispatch loop and may be unloaded. |
5.4. Helper Functions
Helper Functions reside within SoftPLC itself, and are callable from within
TLMs. Each Helper Function has its function prototype in the include file
tlm.h.
| Every TLM will include the header file tlm.h. |
TLMs may use the Helper Functions listed
here. If you prefer, you can remap
certain C functions into Helper Functions. For example the include file
splcstdc.h has lines like this:
#define malloc HlpMemAlloc
so your source code can use malloc(), yet the compiled code will actually be using HlpMemAlloc().
The C preprocessor replaces all occurrences of malloc() with HlpMemAlloc() so you are actually calling HlpMemAlloc() instead of malloc(). This mechanism is not mandatory, but is available to you by doing this:
-
including
tlm.h, which includessplcstdc.hand -
defining REMAP_STDIO on the compiler command line, something which
build.xmldoes as a default
Note that if REMAP_STDIO is not defined and your source code uses the stdio functions, then the remapping is not performed and you end up using the genuine C runtime library versions of the stdio functions.
5.4.1. printf() Redirection
The implementation of printf() within SoftPLC is special. Actually, this refers to the helper function HlpPrintf(), not printf(). You will be using HlpPrintf() only if you have explicitly coded to HlpPrintf(), or you have coded to printf() and the REMAP_STDIO feature is enabled. HlpPrintf() switches between two modes depending on whether SoftPLC is running as a daemon or from the command line. When running as a daemon, the output of HlpPrintf() is directed to the syslog. When running from the command line, SoftPLC’s HlpPrintf() will show up on the console.
You can view the most recent syslog contents by running the following command from a SoftPLC console:
# logread
The genuine C runtime library implementation of printf() does not have this syslog output capability, only HlpPrintf() does.
5.5. TLIs
TLI is an acronym for TOPDOC Loadable Instruction. You can add your own instructions to the SoftPLC control program instruction set. A TLM can contain one or more TLIs and even additional code for a driver. TLIs are called by SoftPLC through a mechanism similar to the dispatch loop. Each TLI is like its own little dispatch loop. To call your TLIs, SoftPLC needs to know the names and locations of each TLI in every module.
5.5.1. FUNCDEF
As we have seen, all modules require the presence of the function
dispatch(). Similarly, for any TLM implementing a TLI, there is a
second mandatory structure that you declare with the macro
FUNCDEF.
The FUNCDEF lists the names, descriptions, entry point addresses, number and types of arguments for each TLI in the TLM. Given this FUNCDEF, SoftPLC has everything it needs to know about TLIs and can call them directly at run time. TOPDOC also consults the FUNCDEF to display TLIs with correct function names, descriptions, number and name of arguments.
For TLIs, execution does not pass through the dispatch() function, but rather goes directly from SoftPLC to the TLI being called from the ladder program. The ladder program contains the function name of the TLI. SoftPLC searches through the TLMs listed in the MODULE.LST file once at start up time. After that SoftPLC can call TLIs with virtually no scantime overhead.
The data type of the FUNCDEF is found in the header file
tlm.h. It is an array of type funcdef and is
reproduced below:
/// TLI definition
typedef struct funcdef {
char fnc_name[MAXFNCNAMELEN+1]; ///< 0 Function name
char fnc_desc[MAXDESCLEN+1]; ///< 16 Function description
TLIPTR fnc_ptr; ///< 48 Pointer to function
UBYTE fnc_numoptionalargs; ///< 52 Number of optional args
UBYTE fnc_type; ///< 53 Output or permissive
USHORT fnc_numargs; ///< 54 Number of arguments
PARMDEF p[MAXPARMNUM]; ///< 56 Array of parameters
} funcdef; ///< 172 = 56 + 9 x 16
#define FUNCDEF funcdef __attribute__ ((section ("TLMDEF")))
- fnc_name
-
Contains the name of the function. It has to be all upper-case with NO embedded spaces. Maximum length is MAXFNCNAMELEN characters, plus a terminating 0.
- fnc_desc
-
Contains a description of the function. It can be mixed case. Maximum length is MAXDESCLEN characters, plus a terminating 0.
- fnc_ptr
-
Contains the address of the TLI which will be called from SoftPLC when the ladder diagram execution triggers it.
- fnc_numoptionalargs
-
Contains any optional args. This number indicates how many of the parameters, indicated by
fnc_numargs, may be omitted when entering the instruction with TOPDOC. The omitted parameters may be omitted from the end of the parameter list at time of instruction entry. A value of zero means there are no optional parameters, all are mandatory. - fnc_type
-
Is ignored by SoftPLC. This field is used only by TOPDOC to decipher the type of instruction as TLI_OUTPUT or TLI_PERMISSIVE. This determines how to display the instruction in the ladder editor. fnc_type can take one or the other of the following values:
Value Meaning TLI_OUTPUT
Indicates that the TLI is an output instruction. This means that the instruction can not change the rung state. Output Energize (OTE) is an example of a built-in output instruction for SoftPLC.
TLI_PERMISSIVE
Indicates that the TLI is a permissive instruction. This means that the instruction can change the rung state. If the return value of a permissive TLI is non-zero, the instruction evaluates to TRUE condition. As a result the execution is passed to the instructions to the right of it on the rung. Examine Input Closed (XIC) is an example of a permissive instruction. If the return value is zero (FALSE), then the rung power flow is cut off at this instruction.
- fnc_numargs
-
Contains the number of parameters that the instruction uses, 0 - 9. If
fnc_numoptionalargsis not zero, thenfnc_numargsrepresents the maximum number of parameters that the instruction may take.maximum number of parameters = fnc_numargs minimum number of parameters = fnc_numargs - fnc_numoptionalargs
5.5.2. PARMDEF
The nature of each parameter passed to a TLI at runtime is determined ahead of time by a corresponding PARMDEF structure. All the PARMDEF structures for a given TLI are provided as an array within the FUNCDEF, seen above. A single PARMDEF structure is defined below:
/// TLI function parameter
typedef struct parm {
char prm_name[MAXPARMNAMELEN+1]; ///< 0 Argument name
USHORT prm_argtype; ///< 12 Argument type
USHORT prm_len; ///< 14 Argument length
} PARMDEF; ///< 16
- prm_name
-
Can be up to MAXPARMNAMELEN characters in length plus a terminating 0.
prm_nameis used by TOPDOC to display a meaningful name for each parameter of the TLI. - prm_argtype
-
Allows you to tell SoftPLC how to pass data to the TLI and the direction of the data flow. Data for any given parameter may be passed as an integer value, a floating-point value, a timer, a counter, a string, a control, or an array (which we call block). This field also tells TOPDOC what to allow at time of instruction editing/entry. This field takes bits from the following two categories ORed together:
-
Data Types Flags
-
Directional Flags
Data Type Flags Meaning TLI_ARG_INT
Integer argument
TLI_ARG_FLT
Float argument
TLI_ARG_BLOCK
Indicates an array, and must be combined with either TLI_ARG_INT, TLI_ARG_FLOAT, or TLI_ARG_STRING. Same as TLI_ARG_FILE, which is now deprecated.
TLI_ARG_TIMER
Timer structure
TLI_ARG_COUNTER
Counter structure
TLI_ARG_CONTROL
Control structure
TLI_ARG_STRING
String element
Directional Flags Meaning TLI_ARG_IN
Associated parameter is for reading
TLI_ARG_OUT
Associated parameter is for writing
One or both of the Directional Flags should be OR’ed with one or more of the Data Type Flags and placed into
prm_argtypeto indicate the type of each parameter to both SoftPLC and TOPDOC. A parameter can be an input to your TLI, an output of your TLI, or bidirectional. Bidirectional means that a value can be passed from the ladder program to the TLI and the TLI returns a value in the same parameter location back to the ladder program.For example, if you want to make one of the parameters to a TLI an input word that can take only integer values, then the
prm_argtypeshould be set toTLI_ARG_IN | TLI_ARG_INT // input param that is an integer value
Similarly, if one of the parameters of a TLI is an output of that TLI and it is a pointer to the start of an array of floating-point locations in SoftPLC’s datatable, the
prm_argtypefor that parameter should be set toTLI_ARG_OUT | TLI_ARG_FLT | TLI_ARG_BLOCK // output param of float array
-
- prm_len
-
Is the number of elements that will be accessed within the datatable starting at the address entered with the instruction into the ladder program. Set this to 1 except when you have a TLI_ARG_BLOCK Data Type Flag ORed into the
prm_argtype, in which case you can set it from 1-10000. TOPDOC uses this field to create datatable memory at time of instruction entry or modification. With TLI_ARG_BLOCK, set it to the largest, i.e. worst case size, array that you will be needing, otherwise you cannot be sure all the required datatable memory will exist at runtime.
5.5.3. TLI Function Arguments
At first glance, 9 parameters may not seem to be enough to implement certain functions. However, any of these parameters can be the start of a data block. Your software can then use a number of consecutive item locations within the data block starting at the supplied parameter. In effect, a TLI can work with hundreds of parameters.
The calling convention of TLIs is slightly different than that of the dispatch() function. It is very similar to the convention used to call the main() function in a C program, which uses the well known argc and argv arguments.
All TLIs will have an identical function prototype as shown below:
/// function type for defining a TLI ladder instruction
typedef BOOL (SPLCUSR * TLIPTR)( int rungState, int argc, TLIPARAM* argv );
- rungState
-
Tells the TLI whether the rung logic preceding the TLI evaluated to TRUE or FALSE. You can take different action in your C function for the TLI based on the rung state.
- argc
-
Gives the number of parameters passed, 0 - 9. This should agree with the value you placed into the funcdef’s
fnc_numargsfield. It is present as a safety precaution to confirm that SoftPLC’s understanding of the function agrees with its implementation. - argv
-
Is an array of TLIPARAM elements where each points to datatable items within SoftPLC’s datatable which are interpreted as function parameters. SoftPLC can pass parameters to the TLI either by value or by reference. Below is the definition of TLIPARAM structure that is filled for each parameter by SoftPLC before calling a TLI.
struct TLIPARAM
{
union {
PLCINT wd; ///< Word value
float fl; ///< Float value
ULONG hls; ///< LS part of handle
} val;
union {
PLCINT* wptr; ///< Word pointer
float* fptr; ///< Float pointer
TIMER* ptmr; ///< Timer block
COUNTER* pcnt; ///< Counter block
CONTROL* pctl; ///< Control block
ULONG hms; ///< MS part of handle
} ptr;
BOOL isfloat; ///< TRUE if the parameter is float, FALSE if PLCINT
};
The union named val is used if SoftPLC is passing a parameter to
the TLI by value. This is useful for cases where numeric
constants such as 3.14159 or single word parameters with a Directional Flag
of only TLI_ARG_IN are being passed to the TLI.
The other way a parameter can be passed to a TLI is by
pointer. When this happens the union named ptr is used and
the corresponding pointer field within the ptr union will point to
the parameter within the datatable. This allows the TLI to access multiple
values by doing pointer arithmetic on a single pointer. A parameter is
passed by pointer when either of these two criteria are met:
-
If SoftPLC is passing a parameter whose
PARMDEF prm_argtypeflags include any Data Type Flag other than TLI_INT or TLI_FLOAT. That is, all but simple INT or FLOAT values are passed by pointer. -
If any parameter’s Directional Flags include TLI_ARG_OUT. That is, anything that must be modified in the datatable must be passed by pointer.
5.5.4. TLI Return Value
If the TLI wants to pass logically TRUE rung power flow to the rest of the ladder rung following itself, it should return TRUE, else FALSE.
5.5.5. Example TLIs
Below is sample source fragment for 2 TLIs, named CIRCLEAREA and ARRAY_AVERAGE. The CIRCLEAREA TLI takes 1 input parameter which is the radius of a circle (as either an INT or FLOAT) and 1 output parameter which is set to the area of the circle as a FLOAT when the TLI is executed. The ARRAY_AVERAGE TLI takes a block of FLOAT or INT values and averages them. The length of the block is variable up to 100 elements max, although this could be extended to 10000.
#include <tlm.h>
#include <math.h> // defines "PI" as M_PI
// forward function declarations
BOOL SPLCUSR CircleArea( int rungState, int argc, TLIPARAM* params );
BOOL SPLCUSR ArrayAve( int rungState, int argc, TLIPARAM* params );
FUNCDEF function_table [] = {
{ "CIRCLEAREA", // Function name
"Calculate area of circle", // Description
CircleArea, // Pointer to function
0, // no. optional params.
TLI_OUTPUT,
2, // 2 params: "Radius" and "Area"
// Parameter array
{ {
"Radius:",
TLI_ARG_IN | TLI_ARG_FLT | TLI_ARG_INT,
1, // prm_len
},
{
"Area:",
TLI_ARG_OUT | TLI_ARG_FLT,
1,
},
}
},
#define MAX_ARRAY_SIZE 100
{ "ARRAY_AVERAGE",
"Average array, up to 100 words",
ArrayAve,
0, // no. optional params
TLI_OUTPUT,
3,
{ {
"Array:",
// handle either INT or FLOAT arrays:
TLI_ARG_IN | TLI_ARG_FILE | TLI_ARG_INT | TLI_ARG_BLOCK,
MAX_ARRAY_SIZE, // worst case allowed size
},
{
"Count:",
TLI_ARG_IN | TLI_ARG_INT,
1,
},
{
"Ave:",
TLI_ARG_OUT | TLI_ARG_FLT,
1,
},
}
},
{ 0 }, // *Required* end-of-table indicator
}; // FUNCDEF end
BOOL SPLCUSR CircleArea( int rungState, int argc, TLIPARAM* params )
{
// Only calculate if Rung is true.
if( rungState )
{
float radius;
/* get float radius by value from parameter 0. Since we allowed either
INT or FLOAT for this parameter, we have to expect either:
*/
if( params[0].isfloat )
radius = params[0].val.fl;
else
radius = params[0].val.wd;
// output the area of the circle in parameter 1
*params[1].ptr.fptr = M_PI * radius * radius;
}
return TRUE;
}
/* Calculate the average of the array */
BOOL SPLCUSR ArrayAve( int rungState, int argc, TLIPARAM* params )
{
// Only calculate if Rung is true.
if( rungState )
{
// the CPU works best with natural (32 bit) "int" type, so grab the
// "Count:" param into an int, not into a PLCINT:
int elemCount = params[1].val.wd; // assuredly an INT, see prm_argtype above
if( elemCount <= 0 )
{
*params[2].ptr.fptr = 0.0;
return FALSE; // stop powerflow to indicate failure
}
if( elemCount > MAX_ARRAY_SIZE )
elemCount = MAX_ARRAY_SIZE;
double total = 0.0; // use double as intermediate, not float
/* Since we allowed either INT or FLOAT for Array: parameter,
we have to expect either:
*/
if( params[0].isfloat )
{
int i;
for( i=0; i<elemCount; ++i )
total += params[0].ptr.fptr[i];
}
else
{
int i;
for( i=0; i<elemCount; ++i )
total += params[0].ptr.wptr[i];
}
// divide the total by the number of elements, save to param 2's float
*params[2].ptr.fptr = (PLCFLOAT) (total / elemCount);
}
return TRUE;
}
5.6. Debugging
To debug your TLM add printf() statements that are conditionally compiled in. Once the TLM code is debugged, remove the extraneous printf() statements.
5.7. Building the Template TLM
In this section we go through the steps to build the template TLM. You should have first read and understood the material under Toolkit Basics.
Here are the steps to create a new project for this example:
1 C:>cd \splcwork 2 C:>md mytlm 3 C:>cd mytlm 4 C:>\SoftPLCToolkit\setenv 5 C:>copy \SoftPLCToolkit\templates\build.* . 6 C:>edit build.properties 7 C:>ant tlm
In step 6 we set the TLM.ROOT.NAME to mytlm. In step 7 the
template code is compiled, linked, and downloaded to the TARGET.IP SoftPLC. In a
real project, you would edit the tlm.c before performing step 7
above.
5.8. Adding a TLM to MODULE.LST
Within your SoftPLC, you may edit /SoftPLC/tlm/MODULE.LST in either
of two ways:
-
By using the
editcommand from a SoftPLC console. -
By using TOPDOC NexGen’s PLC | Modules editor. In order to get this option to work the first time you have to tell TOPDOC about your TLM by cloning one of the files in your TOPDOC installation on your development system found here:
\SoftPLC\plc\SAMPLE.DEF. Copy this file to a new name with extension ".DEF", in the same directory\SoftPLC\plc\and then edit it according to the comments in the file. Then restart TOPDOC. Then go back into TOPDOC PLC | Modules and you should see your TLM listed, select its Use column. Then Send and then Save.
Each time after downloading a revision of your TLM, you will have to restart SoftPLC. This is most easily done using PUTTY.EXE from your Windows box.
SoftPLC does a remapping of the text found in
/SoftPLC/tlm/MODULE.LST. It does this so it can support either a
version 3.x or 4.x system with the same MODULE.LST file. The remapping is as
follows. If the system is a 4.x SoftPLC, then any TLM name ending in TLM and
consisting of all upper case characters, is converted to lowercase and its
extension is changed from ".tlm" to ".tlm.so".So on version 4.x, if you have the following line: MODULE=/SoftPLC/tlm/SOMETHING.TLMthen according to the remapping algorithm, this is equivalent to listing: MODULE=/SoftPLC/tlm/something.tlm.soAs you make your edits to your cloned \SoftPLC\plc\SAMPLE.DEF file you should use
the uppercase shorter synonym, not the longer all lowercase name that is
required of all 4.x TLMs as they actually exist on disk. Eventually
this remapping business will fade away as the version 3.x systems get replaced with
4.x systems.
|
6. SoftPLC Toolkit API Reference
6.1. The Modern TLM C++ Entrypoint Interface: Class TLM
Topdoc Loadable Modules (TLMs) must be callable from the SoftPLC runtime, and modern TLMs make this happen by declaring and implementing an instance of class TLM.
The declaration is done by using macro DECLARE_TLM() once at the top of the main source file. The implementation is done by coding a few class member functions.
| Name | Type | Description |
|---|---|---|
|
This is a global ptr to the TLM instance in each TLM. It is automatically declared as part of the macro DECLARE_TLM(). |
6.1.1. DECLARE_TLM()
#define DECLARE_TLM(aClassName, aName, aFunctionTable) aClassName M___( aName, aFunctionTable ); TLM* const TLM___ = &M___; HLPEnv* SoftPLC___; ERRCODE DLLEXPORT SPLCUSR mainEntry4( request* req ) { return M___.Dispatch( req ); }
Macro DECLARE_TLM is used to establish the entrypoint into a C++ TLM.
It is placed once at the top of your main source file for each TLM.
Parameters |
|---|
6.1.2. TLM
#include <tlm.h>
class TLM
Class TLM presents the C++ interface of a Topdoc Loadable Module (TLM or module).
It is the doorway into the TLM that the runtime uses to call it and ask it do do things. Most of the functions are intended as entry point functions that the runtime will call as it goes through its various states. But there are a few informational functions that the TLM itself can call that are helpful in producing messages or changes in behavior. What makes it easy to use is that you do not have to implement all the functions in this interface, only the ones that you feel should operate in a non-default manor. If you do not implement a function, then a default one will come in from the ${STATELOGIC_LIBRARY}. If there is additional instance data that you want to include, then that may be a reason to derive an extended C++ class from this one, but this is often not necessary. If the runtime loads a module as MODULE= from the MODULE.LST file, it will never call the Scan() function below. If the runtime loads a module as DRIVER= from the MODULE.LST file, it will call the Scan() function below.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Methods |
|
Members
TLM
TLM(const char * aName,
funcdef * aFunctionTable = NULL)
Parameters |
|
|---|
~TLM
~TLM()
Init
void Init(req_init * req)
Function Init() is called right after the driver is loaded.
If you don’t provide this function a default will be provided for you. This is where you should read configuration files from disk and verify that the runtime environment is ready for your usage of it such as opening any communications ports.
You can throw an ERROR exception if want to indicate an error condition. When formulating the text of the ERROR, you need not supply the name of the TLM, as that will be provided by the dispatcher, and you need not supply a terminating \n. For example:
throw ERROR( E_MYTLM_OPEN_COMM_PORT,
"%s while opening port %d",
open_result.c_str(), com_port
);
The SoftPLC runtime treats ERRORs thrown from any driver’s TLM::Init() as "reboot required". The normal way to recover from this state is with a reboot.
However with the "double clutching" capability of most drivers, which is a transition from OPM_REM_PROG to OPM_REM_PROG initiated by NexGen, most drivers can recover from a configuration file error by reloading a modified file. This assumes a user takes the time to edit the config file and send it before initiating the double clutching. The philosophy of each driver’s implementation is potentially variable with respect to its desire to avoid the "reboot required" state. Note that a driver avoids it by never throwing ERROR from TLM::Init(). However in a situation where double clutching is not performed and we have returned success from TLM::Init() as a lie, it is necessary to remember within each driver whether TLM::Init() actually succeeded since the driver would have reported success even if it failed. By remembering, we can then use a driver local TLM::Init() failed status to deny a transition to a run mode later in TLM::ModeChange(). If a double clutch is performed with NexGen and bugs in a newly loaded configuration file go away, the driver local StartUpError should then be cleared so as to allow a transition to a run mode later.
Parameters |
|
|---|---|
Throws |
|
Scan
void Scan()
Function Scan() is called only if the module is loaded as a result of DRIVER= in the MODULE.LST file.
If instead the module is loaded as a result of MODULE= in the MODULE.LST file, then neither this function nor FirstScan() will be called at all. In the former caes, the runtime will call Scan() when it is in a RUN mode (i.e. when Mode() >= OPM_TEST) for each scan of the main thread (except the first RUN mode scan where FirstScan() is called instead of Scan()). This function is not called when the runtime is in OPM_FAULTED, OPM_PROG, or OPM_REM_PROG modes.
Throws |
|
|---|
FirstScan
void FirstScan()
Function FirstScan() is called once for each transition to a RUN mode from a non-RUN mode and only if the module was loaded as DRIVER= in MODULE.LST.
You may throw an ERROR in here, and if so this will cause SoftPLC to enter OPM_FAULT mode exiting OPM_REM_RUN mode and a ModeChange() will be issued during that transition.
If you don’t provide this function a default will be provided for you.
Throws |
|
|---|
Idle
void Idle()
All the DT_OBJECT's are not guaranteed to be Resolved at the time this function is called. Segfaults can arise if you don’t resolve them before using them. It should be possible to bleed off comports in these two modes however.
Throws |
|
|---|
ModeChange
void ModeChange(int aNewMode,
PLCINT * stsFile)
Function ModeChange() is called from the runtime engine on every mode change.
You may deny a requested mode change to OPM_REM_RUN or OPM_RUN by throwing an ERROR.
If you do not supply this function, a default implementation is provided for you by the state_logic.a library.
Parameters |
|
|---|---|
Throws |
DeInstall
void DeInstall()
Function DeInstall is called exactly once, just before the runtime process exits.
In this function you would close any open ports and de-install interrupt handlers.
If you do not supply this function, a default implementation will come from the state_logic.a library.
CheckPoint
void CheckPoint(PLCINT * stsFile)
Function CheckPoint() is called every 400 rungs or so, and at the end of ladder program, but only if you register that this is wanted.
That registration can be made in Init() by setting a bit in Init()'s req_init structure. If you do not register this wish, then this function will never be called within a particular TLM.
|
See
|
Parameters |
|
|---|
BlockTransfer
void BlockTransfer(req_bxfer * req)
Function BlockTransfer() should process a BTW or BTR ladder instruction.
This is only called if you register as wanting it called in Init(). This is used by the RIO master TLM to implement BTW and BTR.
|
See
|
Parameters |
|
|---|
Name
const char * Name() const
Function Name returns the name of the TLM padded up to 8 characters for printing into the SoftPLC log or on screen.
Returns |
|
|---|
CmdLine
const char * CmdLine() const
Function CmdLine returns the command line which was passed into req_init::cmdLine.
Returns |
|
|---|
TlmPathAndName
const char * TlmPathAndName() const
Function TlmPathAndName returns a string like like argv[0] in a C program, it contains the full path of this *.tlm.so name.
For example /SoftPLC/tlm/tealware.tlm.so
Returns |
|
|---|
MakeFilename
std::string MakeFilename(const char * aBaseFilename) const
Function MakeFilename returns a full path and filename which is created by combining the path that this TLM was loaded from, along with aBaseFilename.
Parameters |
|
|---|---|
Returns |
|
MaxRacks
int MaxRacks() const
Function MaxRacks returns the maximum Input or Output capacity of the host SoftPLC as determined by its copy protection device, where the maximum capacity is expressed in (max allowed I or O file size in words)/8, note that the maximum size may be greater than the current size.
Returns |
|
|---|
ShowRegistry
void ShowRegistry() const
Function ShowRegistry dumps the DT_OBJECTs that have been instantiated in this TLM with their types and specs.
ResolveAndVerify
int ResolveAndVerify()
Function ResolveAndVerify resolves (sets the pointer to datatable memory inside of each DT_OBJECT) and verifies that that DT_OBJECT specific region of datatable memory is sufficiently sized to meet its needs.
By default, this function is called before entering a RUN mode and not before that. Therefore it is not legal typically to read or write to DT_OBJECTs until you are in a RUN mode. In a RUN mode, datatable memory may not be moved or resized. In a PROGRAM or FAULTED mode, Topdoc NexGen may be resizing or moving datatable memory. So if you must access a DT_OBJECT in a PROGRAM or FAULTED mode, then you should call this function just before accessing any DT_OBJECT. Sometimes it is useful to do this in the TLM::Init() function, which is always called with the system in a non-running mode. If you are not going to access DT_OBJECT variables in a non RUN mode, then there is no reason to ever call this function from within your TLM. Calls to this function will be automatically done for you as needed (except for the case where you must access a DT_OBJECT in PROGRAM mode.)
Returns |
|
|---|
6.2. Datatable Types
These are some of the types found in SoftPLC datatable files.
6.2.1. enum DT_T
Enum DT_T is the set of datatable file types, and is used in helper HlpDtReadFileTypeSize()'s section argument.
| Value | Init | Description |
|---|---|---|
`` |
0 |
|
`` |
1 |
|
`` |
2 |
|
`` |
3 |
|
`` |
4 |
|
`` |
5 |
|
`` |
6 |
|
`` |
7 |
|
`` |
8 |
|
`` |
9 |
|
`` |
10 |
|
`` |
11 |
|
`` |
12 |
|
`` |
13 |
|
`` |
14 |
|
`` |
15 |
|
|
||
|
||
|
||
|
||
|
| Name | Definition | Description |
|---|---|---|
|
16 bit signed integer |
|
|
32 bit ieee float |
|
|
pointer to PLCINT |
| Name | Value | Description |
|---|---|---|
|
SoftPLC mode indicator bits in status file (S2), word 1. |
|
|
test or remote test mode |
|
|
program or remote program mode |
|
|
operating mode is a BACKUP version of REM_RUN or REM_TEST |
|
|
remote keyswitch position |
|
|
true only during first scan after entering run mode |
|
|
6.2.2. COUNTER
#include <tlm.h>
struct COUNTER
struct COUNTER is the data storage format for a SoftPLC counter instruction
Use with type TLI_ARG_COUNTER
Public Variables |
|---|
6.2.3. TIMER
#include <tlm.h>
struct TIMER
struct TIMER is the data storage format for a SoftPLC timer instruction
Use with type TLI_ARG_TIMER
Public Variables |
|---|
6.2.4. CONTROL
#include <tlm.h>
struct CONTROL
struct CONTROL is the data storage format for a SoftPLC control object
Use with type TLI_ARG_CONTROL
Public Variables |
|---|
6.3. SoftPLC Operating Modes
These defines represent each operating mode that SoftPLC can be in at any given moment.
When SoftPLC changes mode, due to a request by TOPDOC NexGen or by a TLM, then SoftPLC will inform each TLM of the requested mode change by calling its entrypoint and passing in the requested new mode.
| Name | Value | Description |
|---|---|---|
|
fault mode |
|
|
remote program mode, keyswitch in REMOTE |
|
|
program mode, keyswitch not in REMOTE |
|
|
test mode, keyswitch not in REMOTE |
|
|
remote test mode, keyswitch in REMOTE |
|
|
run mode, keyswitch not in REMOTE |
|
|
remote run mode, keyswitch in REMOTE |
|
|
remote test mode, except informed TLMs do not read inputs |
|
|
remote run mode, except informed TLMs do not control I/O |
6.4. TLI Support
Some structures used in implementing TLIs (TOPDOC Loadable Instructions), which are customer ladder instructions for SoftPLC.
| Name | Definition | Description |
|---|---|---|
|
pointer to function type for defining a TLI ladder instruction |
| Name | Value | Description |
|---|---|---|
|
Max function name length. |
|
|
Max param name length. |
|
|
Max number of params. |
|
|
Max description length. |
|
|
INput parameter: value not changed. |
|
|
OUTput parameter: value can change. |
|
|
INTeger argument. |
|
|
FLoaTing point argument. |
|
|
BLOCK address. |
|
|
deprecated use TLI_ARG_BLOCK instead |
|
|
arg may be TIMER |
|
|
arg may be COUNTER |
|
|
arg may be CONTROL |
|
|
arg may be STRING |
|
|
TLI is an output instruction. |
|
|
TLI is a permissive instruction. |
|
|
TLI is in Java ⇒ use handles where pointers would otherwise be used. |
|
`` |
prefix for a funcdef so that the whole structure gets put into a special elf section. |
6.4.1. PARMDEF
#include <tlm.h>
struct PARMDEF
Struct PARMDEF is a TLI function parameter.
There will be several of these per TLI.
|
See
|
Public Variables |
|
|---|
Members
char prm_name
Argument name.
uint16_t prm_argtype
Argument type.
uint16_t prm_len
Argument length.
6.4.2. funcdef
#include <tlm.h>
struct funcdef
Struct funcdef provides the definition and expected arguments to a Topdoc Loadable Instruction, a.k.a.
TLI. An array of these can be given to DECLARE_TLM or TLM_MAIN_ENTRY macros. Use the FUNCDEF macro when declaring the array so that the array is put into the proper section of the link image. Make sure the array is zero terminated with a trailing NULL sentinel.
Public Variables |
|
|---|
Members
char fnc_name
Function name.
char fnc_desc
Function description.
TLIPTR fnc_ptr
Pointer to function.
uint8_t fnc_numoptionalargs
Number of optional args.
uint8_t fnc_type
Output or permissive.
uint16_t fnc_numargs
Number of arguments.
PARMDEF p
Array of parameters.
6.4.3. TLIPARAM
#include <tlm.h>
struct TLIPARAM
A TLI parameter, an array of these are passed to a TLI each time it is invoked.
Public Variables |
|
|---|
Members
PLCINT wd
Word value.
float fl
Float value.
uint32_t hls
LS part of handle.
union TLIPARAM val
used when TLI is passed an argument by value
PLCINT * wptr
Word pointer.
float * fptr
Float pointer.
TIMER * ptmr
Timer block.
COUNTER * pcnt
Counter block.
CONTROL * pctl
Control block.
STRING * pstr
string element
uint32_t hms
MS part of handle.
union TLIPARAM ptr
used when TLI is passed an argument by value
bool isfloat
true if the parameter is float, false if PLCINT
6.5. Old School dispatch() Function Support
The dispatch() function is the main point of entry into the TLM from SoftPLC (except for ladder instructions, each of which defines its own point of entry).
Modern TLMs should use the C++ TLM class instead of this interface which was originally crafted in C.
6.5.1. dispatch()
ERRCODE dispatch(request *reqp)
Function dispatch should be declared and implemented in your TLM.
It is called repeatedly by SoftPLC at various points in execution for various purposes. The specific meaning of each call is given by a pointer to a Request Packets union reqp, which contains a command code (cmdcode) and the corresponding parameters.
Returns: ERRCODE - SUCCESS if successful
Parameters |
|
|---|
| Name | Value | Description |
|---|---|---|
|
returned by dispatch when dispatched command code is not suppored |
6.5.2. TLM_MAIN_ENTRY()
#define TLM_MAIN_ENTRY(aFunctionTable) HLPEnv* SoftPLC___; ERRCODE DLLEXPORT SPLCUSR mainEntry4( request* req ) { if( req->cmdcode < FNC_INIT ) { if( req->cmdcode == FNC_LOAD ) SoftPLC___ = req->load.callback; else req->pre_init.functionTable = aFunctionTable; } return dispatch( req ); }
establishes the main entry point to the TLM and sets up the call back mechanism to the helpers and registers the FUNCTION TABLE.
Use it only once and only in your main source file.
Parameters |
|
|---|
6.5.3. Dispatch Command Codes
Function codes used within the request packets for the dispatch() function.
| Name | Value | Description |
|---|---|---|
|
see req_load |
|
|
see req_pre_init |
|
|
see req_init |
|
|
see req_deinstall |
|
|
see req_unload |
|
|
see req_scan |
|
|
see req_setmode |
|
|
see req_checkpoint |
|
|
see req_bxfer |
6.5.4. Request Packets
There is one unique type of request packet for each command code.
SoftPLC fills a request packet with its desired _ command code _ and corresponding parameters and then calls the dispatch( request* reqp ) function in your TLM.
| Name | Value | Description |
|---|---|---|
|
returned from FNC_SETMODE by backup aware TLM. |
|
|
returned by all but the lowest recursion level in the case of recursive setmode calls |
req_load
#include <tlm.h>
struct req_load
Request Packet req_load is the very first dispatch() made to a TLM.
It happens only once, immediately after the TLM is loaded. It establishes the helper function availability.
Public Variables |
|---|
Members
int cmdcode
FNC_LOAD.
HLPEnv * callback
Helper Table address.
req_pre_init
#include <tlm.h>
struct req_pre_init
Request Packet req_pre_init is the 2nd dispatch() made to a TLM.
It happens only once, immediately after the req_load dispatch. It allows the TLM to register TLIs merely by using the TLM_MAIN_ENTRY() macro.
Public Variables |
|
|---|
Members
int cmdcode
FNC_PRE_INIT.
funcdef * functionTable
TLM's must set this during FNC_PRE_INIT to their FUNCTION_TABLE[], but this is done automatically by macro TLM_MAIN_ENTRY()
req_init
#include <tlm.h>
struct req_init
Request Packet req_init is dispatch()ed exactly once, after the req_pre_init.
Load any configuration files that you may have in here. Initialize and verify your I/O hardware. SoftPLC is not scanning yet. (Program mode is still in effect.) In the event of some hardware or configuration error, you may return non-SUCCESS to prevent SoftPLC from entering RUN mode.
Public Variables |
|
|---|
Members
int cmdcode
FNC_INIT.
int splc_revision
revision of SoftPLC, as = version*10+revision
int splc_caps
capability Info, all set by SoftPLC not TLM's
-
Bit 0 - SET means SoftPLC is passing in the tlmPathAndName
-
Bit 2 - stsFile is present in req_init
int modNdx
int DrvCapability
DrvCapability Info.
-
Bit 0 - SET this if TLM wants req_checkpoint
-
Bit 1 - SET this if TLM supports A-B Block Xfer
int DrvUsage
This WORD is READ-ONLY for TLMS!
-
Bit 0 - SET if TLM is being loaded into TOPDOC, RESET if into SoftPLC
-
Bit 1 - Internal to SoftPLC
int maxRacks
This is the maximum Input or Output capacity of the host SoftPLC as determined by its copy protection device, where the maximum capacity is expressed in (max allowed I or O file size in words)/8, note that the maximum size may be greater than the current size.
const char * tlmPathAndName
like argv[0] in a C program, contains full path of *.tlm.so name.
For example /SoftPLC/tlm/tealware.tlm.so
PLCINT * stsFile
S2 file in datatable.
const char * cmdLine
Contains the command line options string.
For example, if MODULE.LST had a line like DRIVER=/SoftPLC/tlm/tealware.tlm.so WDOG=8 then this string would be "WDOG=8"
req_scan
#include <tlm.h>
struct req_scan
Request Packet req_scan is dispatch()ed repeatedly in any of the SoftPLC Operating Modes.
Any TLM must keep track of the operating mode and act accordingly when being called with this request packet req_scan.
|
See
|
Public Variables |
|---|
Members
int cmdcode
FNC_SCAN.
PLCINT * stsFile
pointer to S2 file in datatable
int numracks
momentary size of I or O datatable file in words/8
req_deinstall
#include <tlm.h>
struct req_deinstall
Request Packet req_deinstall is dispatch()ed only once just as SoftPLC is exiting to the operating system, and just before req_unload.
Use this opportunity to deactivate your I/O hardware and possibly save any retentative information to disk.
Public Variables |
|---|
req_unload
#include <tlm.h>
struct req_unload
Request Packet req_unload is dispatch()ed only once just before the TLM is unloaded.
Public Variables |
|
|---|
Members
int cmdcode
FNC_UNLOAD.
req_setmode
#include <tlm.h>
struct req_setmode
Request Packet req_setmode is dispatch()ed any time there is a change in operating mode.
On power up, the very first mode is OPM_REM_PROG. If the STARTUP.LST file calls for a different operating mode on startup, then just after req_init, there will be a single req_setmode sent with a mode value corresponding to the STARTUP.LST value. Thereafter, you should expect this dispatch() whenever TOPDOC or the keyswitch (if any) initiates a mode change, or if the SoftPLC faults out into OPM_FAULT mode. Save the mode value into a global so you can act accordingly in req_scan.
Public Variables |
|---|
Members
int cmdcode
FNC_SETMODE.
PLCINT * stsFile
S2 file in datatable.
int mode
one of: OPM_PROG, OPM_RUN, OPM_REM_RUN, etc.
req_checkpoint
#include <tlm.h>
struct req_checkpoint
Request Packet req_checkpoint is optionally dispatch()ed to a TLM in RUN mode several times per scan.
This dispatch() is only performed if it was requested in req_init by setting bit 0 of DvrCapability. You can do polling of I/O in here.
Public Variables |
|---|
Members
int cmdcode
FNC_CHECKPOINT.
PLCINT * stsFile
S2 file in datatable.
req_bxfer
#include <tlm.h>
struct req_bxfer
Request Packet req_bxfer is used only by the Allen-Bradley driver to implement block transfer.
used with FNC_BXFER_SUBMIT command code
Public Variables |
|
|---|
Members
int cmdcode
FNC_BXFER_SUBMIT.
PLCINT * stsFile
S2 file in datatable.
void * pDatatab
BTR control block in the datatable.
int rungstate
the "true-ness" of the rung power flow
bool isOldPlatform
false if BT dt section, else true if N dt section
request
#include <tlm.h>
struct request
A generic request packet which is a union of all the command code specific request packets.
Public Variables |
|---|
Members
int cmdcode
req_load load
req_pre_init pre_init
req_init init
req_scan scan
req_deinstall deinstall
req_setmode setmode
req_checkpoint checkpoint
req_bxfer bxfer
req_unload unload
union request request
6.6. Helper Functions for C++
These are the C++ callable helper functions for SoftPLC version 5.x.
A TLM may call these to enter back into SoftPLC for specific services.
6.6.1. enum DTTYPE
Enum DTTYPE is the set of all types returned in BINADDR given to HlpAddressParse().
| Value | Init | Description |
|---|---|---|
|
a bit datatable type |
|
|
a PLCINT or PLCFLOAT datatable type (scaler) |
|
|
a contiguous sequence of elements |
|
|
a TIMER struct |
|
|
a COUNTER struct |
|
|
a CONTROL struct |
|
|
a PID struct |
|
|
a MSG struct |
|
|
a STRING struct |
|
|
a BT struct |
|
|
an SFC struct |
| Name | Type | Description |
|---|---|---|
|
internal for helper functions |
6.6.2. BINADDR
#include <tlm.h>
struct BINADDR
Type for HlpAddressParse()
Public Variables |
|
|---|
Members
int data_type
DTTYPE_BIT, DTTYPE_WORD, DTTYPE_TIMER, DTTYPE_PID, etc.
enum DT_T section
datatable file type
int file
datatable file number
int element
datatable element number
int word
word within element, 0 normally
int bit
bit within word
6.6.3. Datatable Access Functions
Functions that access the datatable.
HlpAddressParse()
int HlpAddressParse(const char **strAddr, BINADDR *binAddr)
Function HlpAddressParse takes a pointer to a pointer to a nul terminated byte string and parses that string as a SoftPLC datatable address, and then advances the caller’s pointer to the string past the address.
Returns: int - a minus 1 (-1) means success. A number > -1 is the character index into the address string where the first error occurred. In the event of an error, the binAddr information is not valid, and the caller’s string pointer is not advanced.
Parameters |
|
|---|
HlpAddressFormat()
std::string HlpAddressFormat(const BINADDR &binAddr)
Function HlpAddressFormat formats a BINADDR into an ASCII string.
Returns: std:string - the output string.
Parameters |
|
|---|
HlpAddressNormalize()
int HlpAddressNormalize(char *output, const char *input)
Function HlpAddressNormalize takes a C string datatable address and re-formats it with spelling consistent with the addresses used in the descriptor table.
This will typically have a full set of leading zeros and all fields will be a standard width.
Returns: int - a minus 1 (-1) means success. A number > -1 is the character index into the address string where the first error occurred.
Parameters |
|
|---|
HlpDtElemSize()
int HlpDtElemSize(enum DT_T aFileType)
Function HlpDtElemSize returns the size of a full datatable element of a given fileType.
Returns: int - The size of the element in PLCINT’s, or 1 if an invalid input argument is provided.
Parameters |
|---|
HlpInputsPut()
int HlpInputsPut(int startWord, int num, const PLCINT *myWords)
Function HlpInputsPut puts a number of process data words into the input image table portion of the datatable (at datatable file number 1).
Input forcing may affect the transfer. TOPDOC NexGen controls whether input forcing is in effect.
Returns: int - the number of words successfully put, so anything less than num is an error.
Parameters |
|
|---|
HlpOutputsGet()
int HlpOutputsGet(int startWord, int num, PLCINT *myWords)
Function HlpOutputsGet gets a number of output image table datatable words from datatable file 0.
Output forcing may affect the transfer. TOPDOC NexGen controls whether output forcing is in effect.
Returns: int - the number of words successfully read, so anything less than num is an error.
Parameters |
|
|---|
HlpDtWordPtr()
void * HlpDtWordPtr(int file, int elem, int word)
Function HlpDtWordPtr returns a pointer to a datatable word or NULL if the requested word does not exist.
You normally cast the return value to the type of datatable object that you are refering to, either a PLCINT*, PLCFLOAT*, COUNTER*, TIMER*, CONTROL*, etc. Because datatable files can be moved to new memory locations while in PROGRAM mode, the returned pointer is valid only until the next transition from OPM_[REM_]PROGRAM to OPM_[REM_]RUN mode. It should be requested again each time you see a FNC_SET_MODE with a mode of OPM_[REM_]RUN or OPM_[REM_]TEST.
Returns: void* - a pointer to the requested datatable word or NULL if that word does not exist.
Parameters |
|
|---|
HlpDtReadFileTypeSize()
ERRCODE HlpDtReadFileTypeSize(int file, int *nwordsp, int *nelemsp, enum DT_T *sectionp)
Function HlpDtReadFileTypeSize gets information about the size and type of a datatable file.
Returns: ERRCODE - SUCCESS if the file exists, else a non-zero (non-SUCCESS) error code
Parameters |
|
|---|
HlpWordsGet()
int HlpWordsGet(int file, int elem, int word, int num, PLCINT *myWords)
Function HlpWordsGet retrieves a block of words from the datatable.
No I/O forcing is used, and if the requested block resides within a FLOAT file, then all the PLCFLOAT values are converted to PLCINTs as they are fetched. Otherwise the requested words are copied as PLCINTs without conversion.
Returns: int - howmany were retrieved. If the file does not exist or if the request is too close to the end of the file for the requested num words, then the return value will be less than num and possibly zero. If only some of the words can be read, then that will be done.
Parameters |
|
|---|
HlpWordsPut()
int HlpWordsPut(int file, int elem, int word, int num, const PLCINT *myWords)
Function HlpWordsPut copies a block of words into the datatable.
No I/O forcing is used, and if the target block resides within a FLOAT file, then all the supplied PLCINT values are converted to PLCFLOATs as they are copied. Otherwise the requested words are copied as PLCINTs without conversion.
Returns: int - howmany were copied. If the file does not exist or if the request is too close to the end of the file for the requested num words, then the return value will be less than num and possibly zero. If only some of the words can be put without running off the end of the file, then that will be done.
Parameters |
|
|---|
6.6.4. Memory Management Functions
Functions used to manage memory.
HlpMemAlloc()
void * HlpMemAlloc(unsigned nbytes)
Function HlpMemAlloc allocates a number of bytes of RAM in application space.
Return NULL if no more memory is available.
Returns: void* - a pointer to the allocated memory or NULL if none.
Parameters |
|
|---|
HlpMemReAlloc()
void * HlpMemReAlloc(void *ptr, unsigned size)
Function HlpMemReAlloc changes the size of the memory block pointed to by ptr to size bytes.
The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the call is equivalent to HlpMemAlloc(size); if size is equal to zero, the call is equivalent to HlpMemFree(ptr). Unless ptr is NULL, it must have been returned by an earlier call to HlpMemAlloc(), HlpMemReAlloc(). Returns NULL if no more memory is available and preserve the original block.
Returns: void* - a pointer to the allocated memory or NULL if none.
Parameters |
|
|---|
HlpMemFree()
void HlpMemFree(void *ptr)
Function HlpMemFree frees the memory block pointed to by ptr, which must have been returned by a previous call to HlpMemAlloc() or HlpMemReAlloc().
Otherwise, or if HlpMemFree(ptr) has already been called before, undefined behavour occurs. If ptr is NULL, no operation is performed.
Parameters |
|
|---|
HlpMapPhysical()
char * HlpMapPhysical(uintptr_t physical, unsigned length)
Function HlpMapPhysical is used to map a physical memory address that may be associated with a piece of hardware into the process address space.
The returned pointer may then be assumed to point to the memory space on the hardware. You should call this only once per physical block of hardware for the entire life of the TLM. Save the return value in a global.
Returns: char* - a pointer that can be used to address the hardware directly. You can cast this to a struct* of a particular type. The return value may be NULL and that indicates that the request failed for some reason.
Parameters |
|
|---|
6.6.5. File (stdio like) Helper Functions
Functions that manipulate files.
They are like their stdio.h equivalents.
HlpPrintf()
void HlpPrintf(const char *fmt,...)
Function HlpPrintf is used like printf(), but its output may be directed to the syslogger, depending on how SoftPLC is started.
Returns: int - The number of characters that were output
Parameters |
|
|---|
HlpFopen()
FILE * HlpFopen(const char *name, const char *mode)
Parameters |
|
|---|
HlpFread()
int HlpFread(void *buf, unsigned elemz, unsigned nelems, FILE *fp)
Parameters |
|
|---|
HlpFgetc()
int HlpFgetc(FILE *fp)
Parameters |
|
|---|
HlpFputc()
int HlpFputc(int cc, FILE *fp)
Parameters |
|
|---|
HlpFwrite()
int HlpFwrite(void *buf, unsigned elemz, unsigned nelems, FILE *fp)
Parameters |
|
|---|
HlpFclose()
int HlpFclose(FILE *fp)
Parameters |
|
|---|
HlpFgets()
char * HlpFgets(char *buf, int len, FILE *fp)
Parameters |
|
|---|
HlpFputs()
int HlpFputs(char *buf, FILE *fp)
Parameters |
|
|---|
HlpFtell()
long HlpFtell(FILE *fp)
Parameters |
|
|---|
HlpFseek()
int HlpFseek(FILE *fp, long spot, int mode)
Parameters |
|
|---|
HlpFprintf()
int HlpFprintf(FILE *fp, const char *fmt,...)
Parameters |
|
|---|
HlpSprintf()
int HlpSprintf(char *out, const char *fmt,...)
Parameters |
|
|---|
6.6.6. Timing Functions
Functions used for timing.
| Name | Definition | Description |
|---|---|---|
|
A function pointer argument used by HlpTimerInstall(). |
HlpTimerInstall()
ERRCODE HlpTimerInstall(TIMERFUNC func, int modNdx, unsigned milliSecsDelta)
Function HlpTimerInstall will install a func that will be called at regular time based intervals.
Never cast the func argument to fit the requirements of this call, instead always define a function whose prototype matches TIMERFUNC exactly. Make sure your func returns as quicly as possible. It is called in PROGRAM, TEST, RUN, or FAULT modes, so keep track of the mode in req_setmode.
Returns: ERRCODE - SUCCESS or error code
See also: HlpTimerDeinstall
Parameters |
|---|
HlpTimerDeinstall()
ERRCODE HlpTimerDeinstall(TIMERFUNC func)
Function HlpTimerDeinstall will de-install an interval function.
After calling this, the func will no longer be called at regular intervals.
Returns: ERRCODE - SUCCESS or error code
See also: HlpTimerInstall
Parameters |
|---|
HlpPtimerSet()
uint32_t HlpPtimerSet(uint32_t msecsDelay)
Function HlpPtimerSet is used in concert with HlpPtimerPoll() to perform low overhead timing.
First call this function with some maximum delay value in msecs (msecsDelay). This function always returns immediately with a future time value, which is computed as the sum of the given msecsDelay plus an internal relative monotonically ascending clock value. After returning, start watching for your hardware device or activity to complete. While you are waiting, you repeatedly call HlpPtimerPoll() with the value you got back from HlpPtimerSet(). When your timing interval is expired, HlpPtimerPoll() returns a value ⇐ 0, otherwise it returns a positive number.
Returns: uint32_t - the relative time of some point in the future at which time the desired timing interval will be complete.
See also: HlpPtimerPoll()
Parameters |
|
|---|
HlpPtimerPoll()
int32_t HlpPtimerPoll(uint32_t futureTime)
Function HlpPtimerPoll is used in concert with HlpPtimerSet() to perform low overhead timing.
The strategy is to first call HlpPtimerSet() with some maximum delay value. You immediately get control back and you start watching for your device or activity to complete. While you are waiting, you repeatedly call HlpPtimerPoll() with the value you got back from HlpPtimerSet(). When your timing interval is expired, HlpPtimerPoll() returns a value ⇐ 0, otherwise it returns a positive number.
Attention: You should not hog the CPU in any dispatch() call other than req_init. Otherwise, you should perform the HlpPtimerPoll test over a number of separate dispatch() calls.
Returns: int32_t - ⇐0 means timed out, >0 means still timing.
See also: HlpPtimerSet()
Parameters |
|
|---|
6.6.7. Debugging Functions
Functions used for debugging.
dprint()
unsigned dprint(const char *fmt,...)
Function dprint provides a printf() like function that accepts the same format string followed by arguments.
It is intended for single-line debug print statements, and automatically includes a newline in the printed string. Additionally, it prepends time information to the front of the string in two six-digit numbers (both in microseconds). The second tracks the time delta between dprint() calls. The first tracks the total relative time, or the sum of the deltas.
Attention: The relative microsecond timer will roll over every second.
Parameters |
|
|---|
6.6.8. PCI Bus Configuration Functions
A few functions that make it possible to query PCI card configuration data from user space.
HlpPciBiosFindDevice()
ERRCODE HlpPciBiosFindDevice(int vendor, int device_id, int index, uint8_t *bus, uint8_t *device_fn)
Function HlpPciBiosFindDevice searches the PCI bus(es) for a card with the given vendor and device_id and returns PCIBIOS_SUCCESSFUL if found.
The index argument is used to find a specific instance number of a type of card. For the first instance always use index = 0, for the second card use index = 1, etc.
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if found, PCIBIOS_DEVICE_NOT_FOUND if not.
Parameters |
|
|---|
HlpPciBiosFindClass()
ERRCODE HlpPciBiosFindClass(int class_code, int index, uint8_t *bus, uint8_t *device_fn)
Function HlpPciBiosFindClass searches the PCI bus(es) for a card with the given class_code and returns PCIBIOS_SUCCESSFUL if found.
The index argument is used to find a specific instance number of a type of card. For the first instance always use index = 0, for the second card use index = 1, etc.
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if found, PCIBIOS_DEVICE_NOT_FOUND if not.
Parameters |
|
|---|
HlpPciBiosReadConfigByte()
ERRCODE HlpPciBiosReadConfigByte(uint8_t bus, uint8_t device_fn, uint8_t where, uint8_t *val)
Function HlpPciBiosReadConfigByte reads a val from the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
HlpPciBiosReadConfigWord()
ERRCODE HlpPciBiosReadConfigWord(uint8_t bus, uint8_t device_fn, uint8_t where, uint16_t *val)
Function HlpPciBiosReadConfigWord reads a val from the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
HlpPciBiosReadConfigDword()
ERRCODE HlpPciBiosReadConfigDword(uint8_t bus, uint8_t device_fn, uint8_t where, uint32_t *val)
Function HlpPciBiosReadConfigDword reads a val from the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
HlpPciBiosWriteConfigByte()
ERRCODE HlpPciBiosWriteConfigByte(uint8_t bus, uint8_t device_fn, uint8_t where, uint8_t val)
Function HlpPciBiosWriteConfigByte writes a val to the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
HlpPciBiosWriteConfigWord()
ERRCODE HlpPciBiosWriteConfigWord(uint8_t bus, uint8_t device_fn, uint8_t where, uint16_t val)
Function HlpPciBiosWriteConfigWord writes a val to the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
HlpPciBiosWriteConfigDword()
ERRCODE HlpPciBiosWriteConfigDword(uint8_t bus, uint8_t device_fn, uint8_t where, uint32_t val)
Function HlpPciBiosWriteConfigDword writes a val to the configuration space of a card located at the bus and device_fn (obtained from HlpPciBiosFindDevice() or HlpPciBiosFindClass()).
Returns: ERRCODE - PCIBIOS_SUCCESSFUL if successful.
Parameters |
|
|---|
| Name | Value | Description |
|---|---|---|
|
worked ok |
|
|
function is not supported |
|
|
vendor id is bad |
|
|
device was not found |
|
|
out of range index |
|
|
unable to write |
|
|
buffer to small |
PCI_DEVFN()
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
Make a "device_fn" combo slot and function value.
Parameters |
|
|---|
PCI_SLOT()
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
Isolate a "slot" from a "device_fn".
Parameters |
|
|---|
PCI_FUNC()
#define PCI_FUNC(devfn) ((devfn) & 0x07)
Isolate a "function" from a "device_fn".
Parameters |
|
|---|
6.6.9. Thread Support
Functions and enums that make it possible to create threads and control their execution priorities.
enum THREAD_PRIORITY
Allowable thread priorities for HlpThreadStart() and HlpThreadSetPriority()
| Value | Init | Description |
|---|---|---|
|
The lowest SoftPLC priority. |
|
|
One priority lower than PRIORITY_MIDDLE. |
|
|
SoftPLC’s main control thread runs at this priority. |
|
|
ONE’s transmit and receive threads run at this priority. |
|
|
One priority higher than PRIORITY_HIGH. |
| Name | Definition | Description |
|---|---|---|
|
handle of a SoftPLC thread |
|
|
Function argument used by HlpThreadStart() |
HlpThreadStart()
THREADID HlpThreadStart(THREADFUNC threadBegin, const char *threadName, void *data, enum THREAD_PRIORITY priority, unsigned stackSize)
Function HlpThreadStart creates a new thread.
There is some overhead to this, so normally it is best to create threads while processing req_init where it safe to hog the CPU for some time. A thread runs until it returns from its threadBegin function.
Returns: THREADID which can be used in other thread functions.
Parameters |
|
|---|
HlpThreadCurrentHandle()
THREADID HlpThreadCurrentHandle()
Function HlpThreadCurrentHandle returns the THREADID for the calling thread.
HlpThreadJoin()
ERRCODE HlpThreadJoin(THREADID threadHandle)
Function HlpThreadJoin will block until the thread identified by threadHandle terminates by returning from its threadBegin function.
Parameters |
|
|---|
HlpThreadSetPriority()
ERRCODE HlpThreadSetPriority(THREADID threadHandle, enum THREAD_PRIORITY priority)
Function HlpThreadSetPriority sets the priority of any thread for which you have a THREADID threadHandle.
Returns: ERRCODE - SUCCESS or error code
Parameters |
|
|---|
HlpThreadGetPriority()
enum THREAD_PRIORITY HlpThreadGetPriority(THREADID threadHandle)
Function HlpThreadGetPriority returns the THREAD_PRIORITY for the thread given by threadHandle.
Parameters |
|
|---|
HlpThreadSleep()
void HlpThreadSleep(unsigned microSecs)
Function HlpThreadSleep will suspend the execution of the calling thread for a number of microseconds given by microSecs.
One thousand microseconds equals one millisecond.
Parameters |
|
|---|
HlpThreadName()
const char * HlpThreadName(THREADID threadHandle)
Function HlpThreadName returns the name of the thread given by threadHandle.
Returns: const char* - the name of the thread used in HlpThreadStart()
Parameters |
|
|---|
HlpThreadKill()
ERRCODE HlpThreadKill(THREADID threadHandle, int signo)
Function HlpThreadKill sends a signal to a given thread.
Parameters |
|
|---|
6.6.10. Shared Library (DLL) Loading and Unloading Functions
Functions that allow loading and unloading of shared libraries and/or TLMs, and one to get the address of symbols within a shared library.
| Name | Definition | Description |
|---|---|---|
|
handle of a loadable module |
HlpLibraryLoad()
ERRCODE HlpLibraryLoad(const char *path, bool dispatch_LOAD, HLIBRARY *pHandle, char errMsg[ERRMSGLEN])
Function HlpLibraryLoad loads a shared library that may be specially built to use Helper Functions.
Returns: ERRCODE - SUCCESS or error code
Parameters |
|
|---|
HlpLibraryUnload()
void HlpLibraryUnload(HLIBRARY handle, bool dispatch_UNLOAD)
Function HlpUnLibraryLoad unloads a library that was previously loaded with HlpLibraryLoad() and is identified by the handle returned by that function.
Calling dispatch() is optional and is controlled by the dispatch_UNLOAD argument.
Parameters |
|
|---|
HlpSymbolAddress()
void * HlpSymbolAddress(HLIBRARY libraryHandle, const char *symbolName)
Function HlpSymbolAddress returns the address of a symbol (function or data variable) within a shared library.
Returns: void* - The address or 0 if not found.
Parameters |
|
|---|
6.6.11. Descriptor Functions
Functions that operate on the Descriptor Table.
HlpDescFindByAddr()
bool HlpDescFindByAddr(const char *aFindAddress, char *aAddress, int aAddressSize, char *aTag, int aTagSize, char *aDescription, int aDescriptionSize)
Function HlpDescFindByAddr finds a descriptor from a given address.
Returns: bool - true if the descriptor was found, else false. If not found, all receive buffers are set to the empty string.
Parameters |
|
|---|
HlpDescFindNextByAddr()
bool HlpDescFindNextByAddr(const char *aFindAddress, char *aAddress, int aAddressSize, char *aTag, int aTagSize, char *aDescription, int aDescriptionSize)
Function HlpDescFindNextByAddress finds a descriptor from a given address, then advances one address alphabetically and returns that descriptor.
You can use this function to walk through all descriptors if you start with an address of "", and upon each call use aAddress returned as aFindAddr in your next call.
Returns: bool - true if the descriptor was found, else false. If not found, all receive buffers are set to the empty string.
Parameters |
|
|---|
HlpDescFindByTag()
bool HlpDescFindByTag(const char *aFindTag, char *aAddress, int aAddressSize, char *aTag, int aTagSize, char *aDescription, int aDescriptionSize)
Function HlpDescFindByTag finds a descriptor from a given tag.
Returns: bool - true if the descriptor was found, else false. If not found, all receive buffers are set to the empty string.
Parameters |
|
|---|
HlpDescFindNextByTag()
bool HlpDescFindNextByTag(const char *aFindTag, char *aAddress, int aAddressSize, char *aTag, int aTagSize, char *aDescription, int aDescriptionSize)
Function HlpDescFindNextByTag finds a descriptor from a given tag, then advances one tag alphabetically and returns that descriptor.
You can use this function to walk through all descriptors that have tags, if you start with a tag of "", and upon each call use aTag returned, in your next call to this function as the aFindTag parameter.
Returns: bool - true if the descriptor was found, else false. If not found, all receive buffers are set to the empty string.
Parameters |
|
|---|
HlpDescDeleteByAddress()
bool HlpDescDeleteByAddress(const char *aAddressToDelete)
Function HlpDescDeleteByAddress deletes the descriptor associated with the given address.
Returns: bool - true if the address was found and the descriptor could be deleted.
Parameters |
|
|---|
HlpDescDeleteByTag()
bool HlpDescDeleteByTag(const char *aTagToDelete)
Function HlpDescDeleteByTag deletes the descriptor associated with the given tag.
Returns: bool - true if the tag was found and the descriptor could be deleted.
Parameters |
|
|---|
HlpDescInsert()
ERRCODE HlpDescInsert(char *aAddress, const char *aTag, const char *aDescription, bool overwriteExisting)
Function HlpDescInsert inserts a desciptor into the descriptor table.
Address formatting (spelling) can vary with regard to the number of leading zeros on file, element or word components. However, since NexGen assumes a specific type of spelling for each address that it needs to display, (called normalized form) it is mandatory that any address that finds its way into the descriptor table be formatted in exactly this normalized form. For this reason, the normalized formatted address will be * returned * to the caller.
Returns: ERRCODE - one of: * SUCCESS * E_DESC_TAGTOOBIG * E_DESC_RECORDTOOBIG * E_DESC_TAGEXISTS * E_DESC_ADDRESSEXISTS * E_DESC_ILLEGALTAG * E_DESC_ILLEGALADDRESS
Parameters |
|
|---|
| Name | Value | Description |
|---|---|---|
|
the tag exceeded a maximum length of 20 |
|
|
the combination of address, plus tag, plus description exceed a maximum of 248 |
|
|
the tag already exists and your overwriteExisting was false |
|
|
the address already exists and your overwriteExisting was false |
|
|
there was one or more illegal characters in your aTag |
|
|
there is something wrong with your address |
6.6.12. Property Functions
Functions that operate on the Property Tables.
HlpPropFindByName()
bool HlpPropFindByName(int aFileNum, const char *aFindName, char *aName, int aNameSize, char *aValue, int aValueSize)
Function HlpPropFindByName finds a property pair from a given property name.
Returns: bool - true if the property was found, else false. If not found, the receive buffers are set to the empty string.
Parameters |
|
|---|
HlpPropFindNextByName()
bool HlpPropFindNextByName(int aFileNum, const char *aFindName, char *aName, int aNameSize, char *aValue, int aValueSize)
Function HlpPropFindNextByName finds a property pair from a given property name, then advances one name alphabetically and returns that property name/value pair.
You can use this function to walk through all properties if you start with a name of "", and upon each call use aName returned in your next call to this function. as aFindAddr in your next call.
Returns: bool - true if the property was found, else false. If not found, the receive buffers are set to the empty string.
Parameters |
|
|---|
HlpPropDelete()
ERRCODE HlpPropDelete(int aFileNum, const char *aName)
Function HlpPropDelete deletes a name/value pair, i.e.
a property given by aName, from a property table given by aFileNum.
Returns: ERRCODE - one of: * SUCCESS * E_PROP_FILEDOESNOTEXIST * E_PROP_NAMENOTFOUND
Parameters |
|
|---|
HlpPropInsert()
ERRCODE HlpPropInsert(int aFileNum, const char *aName, const char *aValue, bool overwriteExisting)
Function HlpPropInsert inserts a new property into a property table, or can be used to replace an existing property with the same name key as aName.
Returns: ERRCODE - one of: * SUCCESS * E_PROP_RECORDTOOBIG * E_PROP_PROPEXISTS * E_PROP_FILEDOESNOTEXIST
Parameters |
|
|---|
| Name | Value | Description |
|---|---|---|
|
the property file aFileNum does not exist, use HlpFileCreate() first. |
|
|
aName is not in property file aFileNum |
|
|
the combination of name plus value exceeded a maximum of 248. |
|
|
the property name already exists and your overwriteExisting was false. |
6.6.13. Miscellaneous Helpers
Helper Functions that don’t fit another category.
HlpFileCreate()
ERRCODE HlpFileCreate(int aArea, int aFile, enum DT_T aType)
Function HlpFileCreate creates a file within the SoftPLC runtime APP image.
The file may be a datatable file or a property file. The runtime must be in a program mode to create or delete files.
0-datatable
4-properties
Returns: ERRCODE - SUCCESS or some non-zero error code.
Parameters |
|
|---|
HlpFileDelete()
ERRCODE HlpFileDelete(int aArea, int aFile)
Function HlpFileDelete deletes a file within the SoftPLC runtime APP image.
The file may be a datatable file or a property file. The runtime must be in a program mode to create or delete files.
0-datatable
4-properties
Returns: ERRCODE - SUCCESS or some non-zero error code.
Parameters |
|
|---|
HlpCRC16()
uint16_t HlpCRC16(uint16_t crc, uint8_t cc)
Function HlpCRC16 calculates a CRC16 checksum from a running total and a new byte.
Call this in a loop starting with an initial value for crc and for each byte in a datastream. On each call except for the first, pass the value returned from this function as the new crc argument. The final call yields the CRC16 for all bytes in the loop.
Returns: uint16_t - the CRC16 for a string of bytes.
Parameters |
|
|---|
HlpGetAPIVersion()
int HlpGetAPIVersion()
Function HlpGetAPIVersion returns the version of the Helper API.
This can be used to verify that helpers your TLM needs are actually present.
Returns: int - what ever is current.
HlpSetMode()
ERRCODE HlpSetMode(int mode)
Function HlpSetMode will change the operating mode of SoftPLC to one of the OPM_* defines.
If neither SoftPLC itself nor any TLMs deny this mode change, then the change will occur. TLMs can deny the mode change by returning other than SUCCESS from dispatch() on the FNC_SETMODE command code. Note that calling this helper will result in a recursive call to the calling TLM on the dispatch() function using the FNC_SETMODE command code.
See also: SoftPLC Operating Modes
Returns: ERRCODE - SUCCESS if mode change occurred.
Parameters |
|
|---|
HlpShowMode()
const char * HlpShowMode(int aMode)
Function HlpShowMode will convert a mode integer to string and return it.
Only present in GetAPIVersion() >= 6.
See also: SoftPLC Operating Modes
Returns: const char* - textual mode name.
Parameters |
|
|---|
HlpGetAuthor()
int HlpGetAuthor(int auth, int mVers)
Function HlpGetAuthor returns authorization status of the given @ auth code.
Returns: int - 0 if not found, 1 if found, 2 if demo.
Parameters |
|
|---|
| Name | Value | Description |
|---|---|---|
|
Macro SUCCESS is used as a return value from helpers indicating successful operation. |
6.7. Byte and Bit Functions
These are functions which can be used to assemble byte packets or to read byte packets in a machine independent way.
There are bit vector functions here too.
6.7.1. U16PutLE()
uint8_t * U16PutLE(uint8_t *array, uint16_t val)
Function U16PutLE writes a 16 bit word to a byte array in little endian (lsb then msb, that is, "L"ittle "E"ndian) byte order.
Returns: uint8_t* - the location just after the last placed byte.
Parameters |
|
|---|
6.7.2. U16GetLE()
uint16_t U16GetLE(const uint8_t *array)
Function U16GetLE gets a 16 bit word from a byte array in little endian (lsb then msb, that is, "L"ittle "E"ndian) byte order.
Returns: uint16_t - The 16 bit word
Parameters |
|
|---|
6.7.3. U16PutBE()
uint8_t * U16PutBE(uint8_t *array, uint16_t val)
Function U16PutBE writes a 16 bit word in big endian fashion.
Returns: uint8_t* - the location just after the last placed byte.
Parameters |
|
|---|
6.7.4. U16GetBE()
uint16_t U16GetBE(const uint8_t *array)
Function U16GetBE gets a 16 bit word from a byte array in big endian byte order.
Returns: uint16_t - The 16 bit word
Parameters |
|
|---|
6.7.5. U32GetLE()
uint32_t U32GetLE(const uint8_t *array)
Function U32GetLE gets a 32 bit word from a byte array in little endian (lsb then msb, that is, "L"ittle "E"ndian) byte order.
Returns: uint32_t - The 32 bit word
Parameters |
|
|---|
6.7.6. U32PutLE()
uint8_t * U32PutLE(uint8_t *array, uint32_t val)
Function U32PutLE writes a 32 bit word to a byte array in little endian (lsb then msb, that is, "L"ittle "E"ndian) byte order.
Returns: uint8_t* - the location just after the last placed byte.
Parameters |
|
|---|
6.7.7. U32GetBE()
uint32_t U32GetBE(const uint8_t *array)
Function U32GetBE gets a 32 bit word from a byte array in big endian (msb then lsb, that is, "B"ig "E"ndian) byte order.
Returns: uint32_t - The 32 bit word
Parameters |
|
|---|
6.7.8. U32PutBE()
uint8_t * U32PutBE(uint8_t *array, uint32_t val)
Function U32PutLE writes a 32 bit word to a byte array in big endian (msb then lsb, that is, "B"ig "E"ndian) byte order.
Returns: uint8_t* - the location just after the last placed byte.
Parameters |
|
|---|
6.7.9. FloatGetLE()
PLCFLOAT FloatGetLE(const uint8_t *array)
Function FloatGetLE de-serializes a 32 bit IEEE floating point value from a little endian format in a byte array.
Parameters |
|
|---|
6.7.10. FloatPutLE()
uint8_t * FloatPutLE(uint8_t *array, PLCFLOAT val)
Function FloatPut serializes a 32 bit IEEE floating point value in little endian format into a byte array.
Returns: uint8_t* - the location just after the last placed byte.
Parameters |
|
|---|
6.7.11. BitTest()
bool BitTest(const uint8_t *array, int bitNum)
Function BitTest tests a bit in a uint8_t array.
Returns: bool - true if bit is set, else false.
Parameters |
|
|---|
6.7.12. BitSet()
void BitSet(uint8_t *array, int bitNum, bool value)
Function BitSet sets or clears a bit in a uint8_t array.
Parameters |
|
|---|
6.7.13. ByteBuf
#include <byte_bufs.h>
class ByteBuf
Class ByteBuf delimits the starting point, ending point, and size of a byte array.
It does not take ownership of such memory, merely points to it. There are no setters among the accessors because it is simple enough to use the assignment operator and overwrite this object with a newly constructed one.
Public Constructors |
|
|---|---|
Public Methods |
|
Protected Variables |
Members
ByteBuf
ByteBuf(uint8_t * aStart,
size_t aSize)
Parameters |
|
|---|
data
uint8_t * data() const
Returns |
|
|---|
end
uint8_t * end() const
Returns |
|
|---|
size
ssize_t size() const
Returns |
|
|---|
uint8_t * start
uint8_t * limit
6.7.14. BufWriter
#include <byte_bufs.h>
class BufWriter
Class BufWriter outlines a writable byte buffer with little endian putters.
It protects from buffer overruns by throwing std::overflow_error. It is useful when serializing data into a byte memory buffer.
Public Constructors |
|
|---|---|
Public Operators |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
Members
BufWriter
BufWriter(uint8_t * aStart,
size_t aCount)
Constructor BufWriter( uint8_t* aStart, size_t aCount )
Parameters |
|
|---|
BufWriter
BufWriter()
operator+=
BufWriter & operator+=(size_t advance)
Advance the start of the buffer by the specified number of bytes and trim the capacity().
Parameters |
|
|---|---|
Returns |
operator+
BufWriter operator+(size_t n)
Construct a new BufWriter from this one but advance its start by n bytes.
Parameters |
|
|---|---|
Returns |
operator*
uint8_t & operator*()
Returns |
|
|---|
data
uint8_t * data() const
Returns |
|
|---|
end
uint8_t * end() const
Returns |
|
|---|
capacity
ssize_t capacity() const
Return the unused size of the buffer, the remaining capacity which is empty. A negative value would indicate an overrun, but that also indicates a bug in in this class because protections are everywhere to prevent overruns.
Returns |
|
|---|
put16
BufWriter & put16(uint16_t aValue)
Write a 16 bit integer little endian.
Parameters |
|
|---|---|
Returns |
put32
BufWriter & put32(uint32_t aValue)
Write a 32 bit integer little endian.
Parameters |
|
|---|---|
Returns |
put64
BufWriter & put64(uint64_t aValue)
Write a 64 bit integer little endian.
Parameters |
|
|---|---|
Returns |
put_float
BufWriter & put_float(float aValue)
Write a 32 bit float little endian.
Parameters |
|
|---|---|
Returns |
put_double
BufWriter & put_double(double aValue)
Write a 64 bit double little endian.
Parameters |
|
|---|---|
Returns |
put_SHORT_STRING
BufWriter & put_SHORT_STRING(const std::string & aString,
bool doEvenByteCountPadding)
Serialize a CIP SHORT_STRING.
Parameters |
|
|---|---|
Returns |
put_STRING
BufWriter & put_STRING(const std::string & aString,
bool doEvenByteCountPadding)
Serialize a CIP STRING.
Parameters |
|
|---|---|
Returns |
put_STRING2
BufWriter & put_STRING2(const std::string & aString)
Serialize a CIP STRING2.
Parameters |
|
|---|---|
Returns |
put16BE
BufWriter & put16BE(uint16_t aValue)
Write a 16 bit integer Big Endian.
Parameters |
|
|---|---|
Returns |
put32BE
BufWriter & put32BE(uint32_t aValue)
Write a 32 bit integer Big Endian.
Parameters |
|
|---|---|
Returns |
append
BufWriter & append(const uint8_t * aStart,
size_t aCount)
Write a byte array.
Parameters |
|
|---|---|
Returns |
fill
BufWriter & fill(size_t aCount,
uint8_t aValue = 0)
Write aValue byte to the buffer aCount times.
Parameters |
|
|---|---|
Returns |
uint8_t * start
uint8_t * limit
overrun
void overrun() const
6.7.15. BufReader
#include <byte_bufs.h>
class BufReader
Class BufReader outlines a read only byte buffer with little endian getters.
It protects from buffer overruns by throwing std::range_error.
Public Constructors |
|
|---|---|
Public Operators |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
Members
BufReader
BufReader()
BufReader
BufReader(const uint8_t * aStart,
size_t aCount)
Parameters |
|
|---|
operator+=
BufReader & operator+=(size_t advance)
Advance the start of the buffer by the specified number of bytes and trim the size().
Parameters |
|
|---|---|
Returns |
operator+
BufReader operator+(size_t n)
Construct a new BufReader from this one but advance its start by n bytes.
Parameters |
|
|---|---|
Returns |
operator*
uint8_t operator*() const
Returns |
|
|---|
operator[]
uint8_t operator[](int aIndex) const
Parameters |
|
|---|---|
Returns |
|
data
const uint8_t * data() const
Returns |
|
|---|
end
const uint8_t * end() const
Returns |
|
|---|
size
ssize_t size() const
Return the un-consumed size of the buffer, the count of bytes remaining in the buffer. A negative value would indicate an overrun, but that also indicates a bug in in this class because protections are everywhere to prevent overruns.
Returns |
|
|---|
get8
uint8_t get8()
Read a byte and return it as unsigned.
Returns |
|
|---|
get16
uint16_t get16()
Read a 16 bit integer little endian first and return it as unsigned.
Returns |
|
|---|
get32
uint32_t get32()
Read a 32 bit integer little endian first and return it as unsigned.
Returns |
|
|---|
get64
uint64_t get64()
Read a 64 bit integer little endian first and return it as unsigned.
Returns |
|
|---|
get_float
float get_float()
Read a 32 bit float little endian first.
Returns |
|
|---|
get_double
double get_double()
Read a 64 bit double little endian first.
Returns |
|
|---|
get_SHORT_STRING
std::string get_SHORT_STRING(bool ExpectPossiblePaddingToEvenByteCount)
Deserialize a CIP SHORT_STRING.
Parameters |
|
|---|---|
Returns |
|
get_STRING
std::string get_STRING(bool ExpectPossiblePaddingToEvenByteCount)
Deserialize a CIP STRING.
Parameters |
|
|---|---|
Returns |
|
get_STRING2
std::string get_STRING2()
Deserialize a CIP STRING2 and encode the result as UTF8 within a std::string.
Returns |
|
|---|
get16BE
uint16_t get16BE()
Get a 16 bit integer as Big Endian.
Returns |
|
|---|
get32BE
uint32_t get32BE()
Get a 32 bit integer as Big Endian.
Returns |
|
|---|
const uint8_t * start
const uint8_t * limit
overrun
void overrun() const
6.8. Miscellaneous Functions
Non-Helper Functions that don’t fit another category.
| Name | Definition | Description |
|---|---|---|
|
Typedef USECS is an unsigned integer earmarked to hold microseconds. |
|
|
Typedef MSECS is an unsigned integer earmarked to hold milliseconds. |
6.8.1. MicroSecsNow()
USECS MicroSecsNow()
Function MicroSecsNow returns current relative time in microseconds.
6.8.2. MilliSecsNow()
MSECS MilliSecsNow()
Function MicroSecsNow returns current relative time in milliseconds.
6.8.3. NanoSecsNow()
uint64_t NanoSecsNow()
Function NanoSecsNow returns current relative time in nanoseconds.
6.8.4. StrPrintf()
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a character array.
Returns: int - the count of bytes appended to the result string, no terminating nul is included.
Parameters |
|
|---|
6.8.5. StrPrintf()
std::string StrPrintf(const char *format,...)
Function StrPrintf is like sprintf() but the output is returned in a std::string instead of being sent to a character array.
Returns: std::string - the result of the sprintf().
Parameters |
|
|---|
6.8.6. STcpy()
void STcpy(STRING *aDatatableString, const char *aSourceString)
Function STcpy copies into a aDatatableString from aSourceString assuming 1 byte = 1 character.
Parameters |
|---|
6.8.7. fromST()
std::string fromST(const STRING *aDatatableString)
Function fromST copies from aDatatableString into a std::string and returns that.
Parameters |
|
|---|
6.8.8. LookupTagAndAddress()
void LookupTagAndAddress(const char *aTagOrAddress, std::string *aTag, std::string *aAddress, BINADDR *aBinAddr)
Function LookupTagAndAddress looks up aTagOrAddress and outputs 3 results.
Throws: ERROR — if no sense can be made of aTagOrAddress because it cannot be parsed as an address and cannot be found as a tag.
Parameters |
|
|---|
6.9. Datatable Objects for C++
These are classes and defines that:
-
make C++ access to the datatable extremely easy.
-
make writing a TLM in C++ extremely easy.
6.9.1. ENABLE_DT_PTR()
#define ENABLE_DT_PTR(A) template<> struct TypeName<A> { static const char *Name() { return #A; } };
Use this once for each DT_PTR type. It provides a TypeName specialization for each kind of DT_PTR you intend to use.
Parameters |
|
|---|
6.9.2. DT_OBJECT
#include <dt_objects.h>
class DT_OBJECT
Class DT_OBJECT is an abstract base class which defines some interface functions for all derived datatable access objects.
It provides foundational support for high speed direct memory access to datatable objects in RUN or TEST modes only (not PROGRAM mode).
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Destructors |
|
Public Static Methods |
|
Public Methods |
|
Protected Constructors |
|
Protected Operators |
|
Protected Variables |
|
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_OBJECT::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
show classname |
|
show constructor’s aTagOrAddress |
|
show tag |
|
show address |
Members
DT_OBJECT
DT_OBJECT(const char * aTagOrAddress,
TLM * aTLM)
Parameters |
|
|---|
~DT_OBJECT
~DT_OBJECT()
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
operator=
Parameters |
|
|---|---|
Returns |
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.3. DT_INT16
#include <dt_objects.h>
class DT_INT16
Class DT_INT16 allows testing and setting of a specific datatable PLCINT.
Usage Example
#include "dt_objects.h"
// DT_INT16's are used simplest as globals.
// Here one is constructed by tag, the other by address.
DT_INT16 FlowRate( "FlowRate" ); // tag must exist in descriptor table
DT_INT16 Pressure( "N77:44" ); // fixed address
int Example()
{
// Access the DT_INT16's like they were simple PLCINT's. Understand
// that this is C++ magic accessing live and current datatable values.
return FlowRate * Pressure;
}
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_INT16::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_INT16
DT_INT16(const char * aTagOrAddress,
TLM * aTLM)
Constructor that creates a DT_INT16 from aTagOrAddress.
Parameters |
|
|---|
operator PLCINT &
PLCINT & operator PLCINT &() const
Function operator PLCINT& () const provides a casting operator so that this object can be used directly in C++ expressions where a PLCINT could be used.
Note that any such C++ expression should only be executed while SoftPLC is in a RUN mode, because before entering a RUN mode, the ResolveAndVerify() function will have been called to update the pointer.
Returns |
|
|---|
operator=
PLCINT operator=(int aValue)
Function operator=( int aValue ) overrides the assignment operator allowing normal C++ syntax be used to assign to a PLCINT in the datatable.
Parameters |
|
|---|---|
Returns |
|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.4. DT_BIT
#include <dt_objects.h>
class DT_BIT
Class DT_BIT allows testing and setting of a specific datatable bit.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_BIT::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_BIT
DT_BIT(const char * aTagOrAddress,
TLM * aTLM)
Constructor DT_BIT( const char* aTagOrAddress ) creates a DT_BIT and registers it.
Parameters |
|
|---|
operator bool
bool operator bool() const
Function operator bool provides a cast operator so that this object can be used directly in C++ expressions where a bool could be used.
Note that any such C++ expression should only be executed while SoftPLC is in a RUN mode, because before entering a RUN mode, the ResolveAndVerify() function will have been called to update the pointer.
Returns |
|
|---|
operator=
DT_BIT & operator=(bool rval)
Operator = ( DT_BIT ) assignment overload assigns a value to the datatable memory referenced by this object.
Parameters |
|
|---|---|
Returns |
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
PLCINT mask
a bit test mask with a single bit turned on
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.5. DT_FLOAT32
#include <dt_objects.h>
class DT_FLOAT32
Class DT_FLOAT32 allows testing and setting of a specific datatable float within SoftPLC.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_FLOAT32::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_FLOAT32
DT_FLOAT32(const char * aTagOrAddress,
TLM * aTLM)
Constructor DT_FLOAT32( const char* aAddress ) creates a DT_FLOAT32, initializes the binAddr, and notifies the master object repository for this TLM about this object’s existence.
Parameters |
|
|---|
operator PLCFLOAT &
PLCFLOAT & operator PLCFLOAT &() const
Function operator PLCFLOAT provides a cast operator so that this object can be used directly in C++ expressions where a PLCFLOAT could be used.
Note that any such C++ expression should only be executed while SoftPLC is in a RUN mode, because before entering a RUN mode, the ResolveAndVerify() function will have been called to update the pointer.
Returns |
|
|---|
operator=
PLCFLOAT operator=(double aValue)
Function operator=( double aValue ) is an assignment override that enables normal C++ language syntax to set the value of a PLCFLOAT residing in the datatable.
Parameters |
|
|---|---|
Returns |
|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.6. DT_ARRAY
#include <dt_objects.h>
class DT_ARRAY
Class DT_ARRAY is base class that provides a window into the datatable for a block of PLCINTs or PLCFLOATs.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
ELEM_TYPE
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_ARRAY::ELEM_TYPE
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_ARRAY::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_ARRAY
DT_ARRAY(const char * aTagOrAddress,
unsigned aElementCount,
TLM * aTLM)
Parameters |
|
|---|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the count of elements in this array.
This will always be whatever aElementCount was in the constructor.
Returns |
|
|---|
Data
void * Data() const
ByteCount
unsigned ByteCount() const
Returns |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
unsigned count
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.7. DT_INT16_ARRAY
#include <dt_objects.h>
class DT_INT16_ARRAY
Class DT_INT16_ARRAY is used to reference a block of consecutive PLCINTSs in a single datatable file.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
ELEM_TYPE
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_INT16_ARRAY::ELEM_TYPE
ELEM_INT16 |
|
|---|---|
ELEM_FLOAT32 |
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_INT16_ARRAY::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_INT16_ARRAY
DT_INT16_ARRAY(const char * aTagOrAddress,
unsigned aElementCount,
TLM * aTLM)
Constructor.
Parameters |
|
|---|
operator[]
const PLCINT & operator[](unsigned aIndex) const
Function operator[]( unsigned aIndex ) returns a reference to a PLCINT datatable word iff aIndex is within range.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
operator[]
PLCINT & operator[](unsigned aIndex)
Parameters |
|
|---|---|
Returns |
|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
ByteCount
unsigned ByteCount() const
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the count of elements in this array.
This will always be whatever aElementCount was in the constructor.
Returns |
|
|---|
Data
void * Data() const
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
unsigned count
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.8. DT_FLOAT32_ARRAY
#include <dt_objects.h>
class DT_FLOAT32_ARRAY
Class DT_FLOAT32_ARRAY is used to reference a block of consecutive PLCFLOATSs in a single datatable file.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
ELEM_TYPE
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_FLOAT32_ARRAY::ELEM_TYPE
ELEM_INT16 |
|
|---|---|
ELEM_FLOAT32 |
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_FLOAT32_ARRAY::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_FLOAT32_ARRAY
DT_FLOAT32_ARRAY(const char * aTagOrAddress,
unsigned aElementCount,
TLM * aTLM)
Constructor.
Parameters |
|
|---|
operator[]
const PLCFLOAT & operator[](unsigned aIndex) const
Function operator[]( unsigned aIndex ) returns a reference to a PLCFLOAT datatable word iff aIndex is within range.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
operator[]
PLCFLOAT & operator[](unsigned aIndex)
Parameters |
|
|---|---|
Returns |
|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
ByteCount
unsigned ByteCount() const
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the count of elements in this array.
This will always be whatever aElementCount was in the constructor.
Returns |
|
|---|
Data
void * Data() const
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
unsigned count
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.9.9. DT_STRUCT
#include <dt_objects.h>
class DT_STRUCT
Class DT_STRUCT is a base class used by the template class DT_PTR in order to map any kind of structure onto a SoftPLC datatable file.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_STRUCT::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_STRUCT
DT_STRUCT(const char * aTagOrAddress,
TLM * aTLM)
Constructor used by template DT_PTR to make an arbitrary structure on a range of datatable words.
Parameters |
|
|---|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
size_of
size_t size_of() const
Returns |
|
|---|
6.9.10. TypeName
#include <dt_objects.h>
template<typename T>
struct TypeName
TypeName is for ENABLE_DT_PTR macro only.
Template Parameters |
|
|---|---|
Public Static Methods |
Members
Name
static const char * Name()
Returns |
|
|---|
6.9.11. DT_PTR
#include <dt_objects.h>
template<typename T>
class DT_PTR
Template DT_PTR allows construction of any kind of datatable structure pointer, including user defined structs.
For example:
struct DT_STRING {
PLCINT length;
PLCINT s[82];
};
DT_PTR<DT_STRING> st1( "Tag" );
Template Parameters |
|
|---|---|
Public Enclosed Types |
|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum DT_PTR::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
DT_PTR
DT_PTR(const char * aTagOrAddress,
TLM * aTLM)
Constructor DT_PTR.
Parameters |
|
|---|
operator→
T * operator->() const
Returns |
|
|---|
operator*
T * operator*() const
Returns |
|
|---|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
size_of
size_t size_of() const
Returns |
|
|---|
6.9.12. DT_OBJECTS
#include <dt_objects.h>
class DT_OBJECTS
Class DT_OBJECTS is a container class for a list of DT_OBJECTs.
It can be used with DT_OBJECT::Make() for dynamic construction of DT_OBJECTS.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Operators |
Members
DT_OBJECTS
DT_OBJECTS()
~DT_OBJECTS
~DT_OBJECTS()
6.10. Finite State Machines for C++
| Name | Definition | Description |
|---|---|---|
|
Typedef SHOW_STATE_FUNC refers to a FSM function which translates a state number to a state name C string. |
6.10.1. FSM
#include <softplc_toolkit.h>
class FSM
Class FSM.
is for coding finite state machines. It manages a current state (kept in a datatable word (PLCINT), and provides a state dwell timer feature which tells how long an instance has been in a particular state. You may derive from this class to inherit baseline functionality into your state machines.
This class extends from DT_INT16 as a means of getting a datatable PLCINT that is the current state. Since it is in the datatable, it is visible from the realtime DataTable viewing tools.
Public Enclosed Types |
|
|---|---|
Public Constructors |
|
Public Operators |
|
Public Static Methods |
|
Public Methods |
|
Protected Variables |
|
FMT_CTL
#include <opt/softplc/c++-toolkit-5/h/dt_objects.h>
enum FSM::FMT_CTL
Enum FMT_CTL is a set of bits that can be OR-ed together and passed to Format() to control that function’s output.
TYPE = (1<<0) |
show classname |
|---|---|
SPEC = (1<<1) |
show constructor’s aTagOrAddress |
TAG = (1<<2) |
show tag |
ADDR = (1<<3) |
show address |
Members
FSM
FSM(const char * aStateTagOrAddress,
SHOW_STATE_FUNC * aShowFunc = NULL,
bool doStateTracking = false,
TLM * aTLM)
Constructor.
Parameters |
|
|---|
operator PLCINT &
PLCINT & operator PLCINT &() const
Function operator PLCINT& () const provides a casting operator so that this object can be used directly in C++ expressions where a PLCINT could be used.
Note that any such C++ expression should only be executed while SoftPLC is in a RUN mode, because before entering a RUN mode, the ResolveAndVerify() function will have been called to update the pointer.
Returns |
|
|---|
Make
Function Make is a factory method that creates the proper derived class based on aTagOrAddress.
Parameters |
|
|---|---|
Returns |
ShowState
const char * ShowState(int aState)
Function ShowState returns the current state in a textual representation, so long as this FSM was constructed with aShowFunc.
Parameters |
|
|---|---|
Returns |
|
State
int State() const
Function State returns the current state number.
Returns |
|
|---|
SetState
void SetState(int aState)
Function SetState changes the current state number, resets the dwell timer to 0 and optionally HlpPrintf()'s the change if state tracking is on.
Parameters |
|
|---|
SetTracking
void SetTracking(bool doTracking)
Function SetTracking controls whether state tracking is on or off.
Parameters |
|
|---|
Dwell
bool Dwell(USECS aTimeout,
USECS now)
Function Dwell returns true if this FSM has been in its current state for aTimeout usecs or longer.
Parameters |
|
|---|---|
Returns |
|
DwellTime
USECS DwellTime(USECS now)
Function DwellTime.
returns the number of usecs that this FSM has been in the current state.
Parameters |
|
|---|---|
Returns |
|
ClassName
const char * ClassName() const
Function ClassName returns the name of this class.
Returns |
|
|---|
ResolveAndVerify
void ResolveAndVerify()
Function ResolveAndVerify checks the existence of the datatable memory for this object and updates the pointer field.
Throws |
|
|---|
Address
const std::string & Address() const
Function Address returns the plc memory address of this object.
Returns |
|
|---|
Tag
const std::string & Tag() const
Function Tag returns the tag of this object.
Returns |
|
|---|
Spec
const std::string & Spec() const
Function Spec returns the specification given as aTagOrAddress to the constructor.
Returns |
|
|---|
Name
const std::string & Name() const
Function Name returns the tag if known, else the address if known, else the spec.
Returns |
|
|---|
Format
std::string Format(int aCtl = FMT_DEFAULT) const
Function Format prints information characterizing this object into a std::string and returns that string.
Parameters |
|
|---|---|
Returns |
|
USECS timeAtStateEntry
bool tracking
SHOW_STATE_FUNC * show_state
TLM & tlm
Function GetFloat returns a double, its a polymorphic way to get a value out of a DT_OBJECT.
void * pointer
to implementation or datatable memory
std::string spec
a copy of aTagOrAddress from constructor.
std::string address
the SoftPLC memory address of this word.
std::string tag
the SoftPLC tag of this word, if any.
BINADDR binAddr
the SoftPLC address in binary.
6.11. Serial I/O Support
These are functions and defines that are used to talk to the 36 serial ports.
6.11.1. COMsetup()
ERRCODE COMsetup(int comport, int rcvSize, char *rcvBuf, int xmitSize, char *xmitBuf, long baudrate, int parity, int stopbits, int databits)
Function COMsetup will open a given serial port and configure it with the given parameters.
If this calls succeeds, after using the given serial port, then call COMdisable()
Returns: ERRCODE - SUCCESS or one of: * E_COMM_BAD_PORT * E_COMM_ALREADY_OPEN * E_COMM_BAD_BAUDRATE * E_COMM_BAD_PARITY * E_COMM_BAD_DATABITS * E_COMM_BAD_STOPBITS
Parameters |
|
|---|
6.11.2. COMrst()
ERRCODE COMrst(int comport, long baudrate, int parity, int stopbits, int databits)
Function COMrst restarts the given comport, without a close and reopen, to operate at the given configuration parameters.
Returns: ERRCODE - SUCCESS or one of: * E_COMM_BAD_PORT * E_COMM_NOT_OPEN * E_COMM_BAD_BAUDRATE * E_COMM_BAD_PARITY * E_COMM_BAD_DATABITS * E_COMM_BAD_STOPBITS
Parameters |
|
|---|
6.11.3. COMrst_x()
ERRCODE COMrst_x(int comport, long baudrate, int parity, int stopbits, int databits, int rcvFifoIntThreshold)
Function COMrst_x restarts the given comport, without a close and reopen, to operate at the given configuration parameters.
Returns: ERRCODE - SUCCESS or one of: * E_COMM_BAD_PORT * E_COMM_NOT_OPEN * E_COMM_BAD_BAUDRATE * E_COMM_BAD_PARITY * E_COMM_BAD_DATABITS * E_COMM_BAD_STOPBITS
Parameters |
|
|---|
6.11.4. COMdisable()
ERRCODE COMdisable(int comport)
Function COMdisable closes the com port.
Parameters |
|
|---|
6.11.5. COMrcvclear()
void COMrcvclear(int comport)
Function COMrcvclear will empty the receive buffer for the given comport, dropping any received and unread bytes to that point.
Parameters |
|
|---|
6.11.6. COMxmitclear()
void COMxmitclear(int comport)
Function COMxmitclear will empty the transmit buffer, dropping any written yet unsent bytes to that point.
Parameters |
|
|---|
6.11.7. COMgetc()
int COMgetc(int comport)
Function COMgetc gets a byte from the comm buffer iff available, else returns -1 immediately.
Does NOT wait until a byte is available.
Returns: int - the byte in lower 8 bits or -1 if none there.
Parameters |
|
|---|
6.11.8. COMin()
int COMin(int comport)
Function COMin gets a byte from the comm buffer when available, and blocks until one is available.
Waits indefinitely until a byte is available.
Returns: int - the byte in lower 8 bits.
Parameters |
|
|---|
6.11.9. COMin_timeout()
int COMin_timeout(int comport, int usecsTimeout)
Function COMin_timeout gets a byte from the comm buffer when available, and blocks until one is available or the usecsTimeout occurs.
Returns: int - the byte in lower 8 bits, or -1 to indicate a timeout.
Parameters |
|
|---|
6.11.10. COMread()
int COMread(int comport, char *buf, int howmany)
Function COMread reads a number of bytes from the comm buffer.
Reads at least one byte but this may be less than the number requested.
Returns: int - the number actually returned, at least one 1 but up to the number requested, inclusive. The quantity read may be less than the number of available bytes in the receive buffers, so you will have to watch this return value closely.
Parameters |
|
|---|
6.11.11. COMrcvqueue()
int COMrcvqueue(int comport)
Function COMrcvqueue returns the number of bytes in the receive buffer for the given comport.
Returns: int - The number of received but unread bytes in the receive buffer for the given comport.
Parameters |
|
|---|
6.11.12. COMxmitqueue()
int COMxmitqueue(int comport)
Function COMxmitqueue returns the number of bytes in the transmit buffer for the given comport.
The transmit buffers can hold up to COM_MAX_XMITQUEUE bytes at any time. Bytes written beyond that number with either COMputc() or COMwrite() run the risk of blocking the calling thread.
Returns: int - The number of written but un-transmitted bytes in the transmit buffer for the given comport, or -1 if error.
Parameters |
|
|---|
6.11.13. COMwrite()
int COMwrite(int comport, const char *buf, int num)
Function COMwrite writes a number of bytes out the serial port given by comport.
The function will block until all the requested bytes have been transferred to the transmit buffer, then it will return. This may be before the bytes are actually output through the serial interface.
To avoid blocking the calling thread, always make sure there is room in the transmit buffer by checking the following: if( COM_MAX_XMITQUEUE > numToWrite + COMxmitqueue(port) ) COMwrite(.. numToWrite…)
Returns: int - the number actually written, which will generally be either num, or it can be -1 if the comport is invalid or not COMsetup() yet.
Parameters |
|
|---|
6.11.14. COMbreak()
void COMbreak(int comport, bool sts)
Function COMbreak changes the line break output status to TRUE or FALSE.
This function will have to be called twice with a small delay in between, passing in TRUE on the first call and FALSE on the second call.
Parameters |
|
|---|
6.11.15. COMputc()
bool COMputc(int comport, char byteValue)
Function COMputc outputs a single byte to the serial transmit buffer for the given comport.
If you have a buffer of several bytes to output, COMwrite() is more efficient than this function.
To avoid blocking the calling thread, always make sure there is room in the transmit buffer by checking the following: if( COM_MAX_XMITQUEUE > COMxmitqueue(port) ) COMputc(…)
Returns: bool - TRUE if a byte was output, else FALSE which can happen if the serial port has not been COMsetup() or the comport parameter is out of range.
Parameters |
|
|---|
6.11.16. COMgetoverflow()
bool COMgetoverflow(int comport, bool reset)
Function COMgetoverflow gets the overflow status of the receive ring buffer.
Returns: bool - TRUE if the ring buffer has overflowed since last reset, else FALSE.
Parameters |
|
|---|
6.11.17. COMgetlinebreak()
bool COMgetlinebreak(int comport, bool reset)
Function COMgetlinebreak gets an internal bool that indicates whether a line break has been seen since it was last reset.
Returns: bool - TRUE if the line break flag is set since last reset, else FALSE.
Parameters |
|
|---|
6.11.18. COMgeterrflg()
int COMgeterrflg(int comport, bool reset)
Function COMgeterrflg gets an internal bit field that has bits indicating the historical status pertaining to:
Returns: int - which is a bitfield with the above COMMERR_* bits potentially OR’ed in.
Parameters |
|
|---|
6.11.19. COMgetdcd()
bool COMgetdcd(int comport)
Function COMgetdcd gets the current status of the Data Carrier Detect (DCD) line for the given serial port.
Returns: bool - TRUE if the DCD line is TRUE, else FALSE if not or if comport is bad or not COMsetup().
Parameters |
|
|---|
6.11.20. COMgetcts()
bool COMgetcts(int comport)
Function COMgetcts gets the current status of the Clear To Send (CTS) line for the given serial port.
Returns: bool - TRUE if the CTS line is TRUE, else FALSE if not or if comport is bad or not COMsetup().
Parameters |
|
|---|
6.11.21. COMgetring()
bool COMgetring(int comport)
Function COMgetring gets the current status of the Ring Indicator (RI) line for the given serial port.
Returns: bool - TRUE if the RI line is TRUE, else FALSE if not or if comport is bad or not COMsetup().
Parameters |
|
|---|
6.11.22. COMgetdsr()
bool COMgetdsr(int comport)
Function COMgetdsr gets the current status of the Data Set Ready (DSR) line for the given serial port.
Returns: bool - TRUE if the DSR line is TRUE, else FALSE if not or if comport is bad or not COMsetup().
Parameters |
|
|---|
6.11.23. COMgettxempty()
bool COMgettxempty(int comport)
Function COMgettxempty gets the current transmit buffer empty and transmit shift register empty status of the given serial port.
Returns: bool - TRUE if the port’s transmit shift registers are empty, else FALSE.
Parameters |
|
|---|
6.11.24. COMsetrts()
void COMsetrts(int comport, bool state)
Function COMsetrts sets the current status of the Request To Send (RTS) line for the given serial port.
Parameters |
|
|---|
6.11.25. COMsetdtr()
void COMsetdtr(int comport, bool state)
Function COMsetdtr sets the current status of the Data Terminal Request (DTR) line for the given serial port.
Parameters |
|
|---|
6.11.26. COMsetout1()
void COMsetout1(int comport, bool state)
Function COMsetout1 sets the Modem Control Register’s OUT1 line, if it exists, for the given serial port.
Parameters |
|
|---|
6.11.27. COMsetout2()
void COMsetout2(int comport, bool state)
Function COMsetout2 sets the Modem Control Register’s OUT2 line, if it exists, for the given serial port.
Parameters |
|
|---|
6.11.28. COMsetloopback()
void COMsetloopback(int comport, bool state)
Function COMsetloopback sets the Modem Control Register’s LOOPBACK state, if it exists, for the given serial port.
Parameters |
|
|---|
6.11.29. Serial I/O Error Codes
These are #defines that are used by the Serial I/O Support functions.
| Name | Value | Description |
|---|---|---|
|
the maximum number of comports |
|
|
the maximum number of bytes that may be queued in the transmit buffers under Linux as of this writing. |
|
|
A bit within a bitfield returned by COMgeterrflg() that shows if a PARITY error occurred. |
|
|
A bit within a bitfield returned by COMgeterrflg() that shows if a FRAMING ERROR occurred. |
|
|
A bit within a bitfield returned by COMgeterrflg() that shows if a chip level FIFO overrun occurred. |
|
`` |
The given comport is out of range. |
|
`` |
Returned by COMsetup() when the given comport is already open. |
|
`` |
The given baudrate is unsupported. |
|
`` |
The given parity is not one of 'N', 'O', 'E', 'S', or 'M'. |
|
`` |
Returned by any COM function called before COMsetup() was made. |
|
`` |
The given databits is not one of 5,6,7 or 8. |
|
`` |
The given databits is not one of 5,6,7 or 8. |
|
`` |
Unable to set low latency flag during COMsetup() |
E_COMM()
#define E_COMM(x) ((unsigned)(x)+5000u)
A macro used internally to generate the other E_COMM_* #defines it is equal to ((unsigned)(x)+5000u)
Parameters |
|
|---|
6.12. S-Expression Parsing Support
Class DSNLEXER along with a supplied CMake script make it fairly simple to implement a recursive descent s-expression parser for your TLM’s configuration file reader, should you decide to use s-expression format for your configuration file(s).
6.12.1. enum DSN_SYNTAX_T
Enum DSN_SYNTAX_T lists all the DSN lexer’s tokens that are supported in lexing.
| Value | Init | Description |
|---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
6.12.2. DSNLEXER
#include <dsnlexer.h>
class DSNLEXER
Class DSNLEXER implements a lexical analyzer for the S-EXPRESSION file format.
It reads lexical tokens from the current LINE_READER through the NextTok() function.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Static Methods |
|
Public Methods |
|
Protected Enclosed Types |
|
Protected Variables |
|
Protected Methods |
|
READER_STACK
typedef std::vector<LINE_READER *> READER_STACK
Members
DSNLEXER
DSNLEXER(const KEYWORD * aKeywordTable,
unsigned aKeywordCount,
FILE * aFile,
const std::string & aFileName)
Constructor ( FILE*, const std::string& ) intializes a DSN lexer and prepares to read from aFile which is already open and has aFilename.
Parameters |
|
|---|
DSNLEXER
DSNLEXER(const KEYWORD * aKeywordTable,
unsigned aKeywordCount,
const std::string & aSExpression,
const std::string & aSource = "")
Constructor ( const KEYWORD*, unsigned, const std::string&, const std::string& ) intializes a DSN lexer and prepares to read from aSExpression.
Parameters |
|
|---|
DSNLEXER
DSNLEXER(const std::string & aSExpression,
const std::string & aSource = "")
Constructor ( const std::string&, const std::string& ) intializes a DSN lexer and prepares to read from aSExpression.
Use this one without a keyword table with the DOM parser in ptree.h.
Parameters |
|
|---|
DSNLEXER
DSNLEXER(const KEYWORD * aKeywordTable,
unsigned aKeywordCount,
LINE_READER * aLineReader = NULL)
Constructor ( LINE_READER* ) intializes a DSN lexer and prepares to read from aLineReader which is already open, and may be in use by other DSNLEXERs also.
No ownership is taken of aLineReader. This enables it to be used by other DSNLEXERs also.
Parameters |
|
|---|
~DSNLEXER
~DSNLEXER()
IsSymbol
static bool IsSymbol(int aTok)
Function IsSymbol tests a token to see if it is a symbol.
This means it cannot be a special delimiter character such as DSN_LEFT, DSN_RIGHT, DSN_QUOTE, etc. It may however, coincidentally match a keyword and still be a symbol.
Parameters |
|
|---|---|
Returns |
|
Syntax
static const char * Syntax(int aTok)
Parameters |
|
|---|---|
Returns |
|
SyncLineReaderWith
bool SyncLineReaderWith(DSNLEXER & aLexer)
Useable only for DSN lexers which share the same LINE_READER Synchronizes the pointers handling the data read by the LINE_READER Allows 2 DNSLEXER to share the same current line, when switching from a DNSLEXER to another DNSLEXER.
Parameters |
|
|---|---|
Returns |
|
PushReader
void PushReader(LINE_READER * aLineReader)
Function PushReader manages a stack of LINE_READERs in order to handle nested file inclusion.
This function pushes aLineReader onto the top of a stack of LINE_READERs and makes it the current LINE_READER with its own GetSource(), line number and line text. A grammar must be designed such that the "include" token (whatever its various names), and any of its parameters are not followed by anything on that same line, because PopReader always starts reading from a new line upon returning to the original LINE_READER.
Parameters |
|
|---|
PopReader
LINE_READER * PopReader()
Function PopReader deletes the top most LINE_READER from an internal stack of LINE_READERs and in the case of FILE_LINE_READER this means the associated FILE is closed.
The most recently used former LINE_READER on the stack becomes the current LINE_READER and its previous position in its input stream and the its latest line number should pertain. PopReader always starts reading from a new line upon returning to the previous LINE_READER. A pop is only possible if there are at least 2 LINE_READERs on the stack, since popping the last one is not supported.
Returns |
|
|---|
NextTok
int NextTok()
Function NextTok returns the next token found in the input file or DSN_EOF when reaching the end of file.
Users should wrap this function to return an enum to aid in grammar debugging while running under a debugger, but leave this lower level function returning an int (so the enum does not collide with another usage).
Returns |
|
|---|---|
Throws |
|
NeedSYMBOL
int NeedSYMBOL()
Function NeedSYMBOL calls NextTok() and then verifies that the token read in satisfies bool IsSymbol().
If not, an IO_ERROR is thrown.
Returns |
|
|---|---|
Throws |
|
NeedSYMBOLorNUMBER
int NeedSYMBOLorNUMBER()
Function NeedSYMBOLorNUMBER calls NextTok() and then verifies that the token read in satisfies bool IsSymbol() or tok==DSN_NUMBER.
If not, an IO_ERROR is thrown.
Returns |
|
|---|---|
Throws |
|
NeedNUMBER
int NeedNUMBER(const char * aExpectation)
Function NeedNUMBER calls NextTok() and then verifies that the token read is type DSN_NUMBER.
If not, and IO_ERROR is thrown using text from aExpectation.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
CurTok
int CurTok()
Function CurTok returns whatever NextTok() returned the last time it was called.
Returns |
|
|---|
PrevTok
int PrevTok()
Function PrevTok returns whatever NextTok() returned the 2nd to last time it was called.
Returns |
|
|---|
SetStringDelimiter
char SetStringDelimiter(char aStringDelimiter)
Function SetStringDelimiter changes the string delimiter from the default " to some other character and returns the old value.
Parameters |
|
|---|---|
Returns |
|
SetSpaceInQuotedTokens
bool SetSpaceInQuotedTokens(bool val)
Function SetSpaceInQuotedTokens changes the setting controlling whether a space in a quoted string is a terminator.
Parameters |
|
|---|---|
Returns |
|
SetCommentsAreTokens
bool SetCommentsAreTokens(bool val)
Function SetCommentsAreTokens changes the handling of comments.
If set true, comments are returns as single line strings with a terminating newline, else they are consumed by the lexer and not returned.
Parameters |
|
|---|---|
Returns |
|
ReadCommentLines
std::vector<std::string> ReadCommentLines()
Function ReadCommentLines checks the next sequence of tokens and reads them into a wxArrayString if they are comments.
Reading continues until a non-comment token is encountered, and such last read token remains as CurTok() and as CurText(). No push back or "un get" mechanism is used for this support. Upon return you simply avoid calling NextTok() for the next token, but rather CurTok().
Returns |
|
|---|
Expecting
void Expecting(int aTok)
Function Expecting throws an IO_ERROR exception with an input file specific error message.
Parameters |
|
|---|---|
Throws |
|
Expecting
void Expecting(const char * aTokenList)
Function Expecting throws an IO_ERROR exception with an input file specific error message.
Parameters |
|
|---|---|
Throws |
|
Unexpected
void Unexpected(int aTok)
Function Unexpected throws an IO_ERROR exception with an input file specific error message.
Parameters |
|
|---|---|
Throws |
|
Unexpected
void Unexpected(const char * aToken)
Function Unexpected throws an IO_ERROR exception with an input file specific error message.
Parameters |
|
|---|---|
Throws |
|
Duplicate
void Duplicate(int aTok)
Function Duplicate throws an IO_ERROR exception with a message saying specifically that aTok is a duplicate of one already seen in current context.
Parameters |
|
|---|---|
Throws |
|
NeedLEFT
void NeedLEFT()
Function NeedLEFT calls NextTok() and then verifies that the token read in is a DSN_LEFT.
If it is not, an IO_ERROR is thrown.
Throws |
|
|---|
NeedRIGHT
void NeedRIGHT()
Function NeedRIGHT calls NextTok() and then verifies that the token read in is a DSN_RIGHT.
If it is not, an IO_ERROR is thrown.
Throws |
|
|---|
GetTokenText
const char * GetTokenText(int aTok)
Function GetTokenText returns the C string representation of a DSN_T value.
Parameters |
|
|---|---|
Returns |
|
GetTokenString
std::string GetTokenString(int aTok)
Function GetTokenString returns a quote wrapped string representation of a token value.
Parameters |
|
|---|---|
Returns |
|
CurText
const char * CurText()
Function CurText returns a pointer to the current token’s text.
Returns |
|
|---|
CurStr
const std::string & CurStr()
Function CurStr returns a reference to current token in std::string form.
Returns |
|
|---|
CurLineNumber
int CurLineNumber()
Function FromUTF8 returns the current token text as a wxString, assuming that the input byte stream is UTF8 encoded.
wxString FromUTF8() { return wxString::FromUTF8( curText.c_str() ); } Function CurLineNumber returns the current line number within my LINE_READER
Returns |
|
|---|
CurLine
const char * CurLine()
Function CurLine returns the current line of text, from which the CurText() would return its token.
Returns |
|
|---|
CurSource
const std::string & CurSource()
Function CurFilename returns the current LINE_READER source.
Returns |
|
|---|
CurOffset
int CurOffset()
Function CurOffset returns the byte offset within the current line, using a 1 based index.
Returns |
|
|---|
bool iOwnReaders
on readerStack, should I delete them?
const char * start
const char * next
const char * limit
char dummy
when there is no reader.
READER_STACK readerStack
all the LINE_READERs by pointer.
LINE_READER * reader
no ownership. ownership is via readerStack, maybe, if iOwnReaders
bool specctraMode
if true, then: 1) stringDelimiter can be changed 2) Kicad quoting protocol is not in effect 3) space_in_quoted_tokens is functional else not.
char stringDelimiter
bool space_in_quoted_tokens
blank spaces within quoted strings
bool commentsAreTokens
true if should return comments as tokens
int prevTok
curTok from previous NextTok() call.
int curOffset
offset within current line of the current token
int curTok
the current token obtained on last NextTok()
std::string curText
the text of the current token
const KEYWORD * keywords
table sorted by CMake for bsearch()
unsigned keywordCount
count of keywords table
KEYWORD_MAP keyword_hash
fast, specialized "C string" hashtable
init
void init()
readLine
int readLine()
Returns |
|
|---|
findToken
int findToken(const std::string & aToken)
Function findToken takes aToken string and looks up the string in the keywords table.
Parameters |
|
|---|---|
Returns |
|
isStringTerminator
bool isStringTerminator(char cc)
Parameters |
|
|---|---|
Returns |
|
6.13. Reader and Formatter Classes
These classes can be used to output text to various destination types and read text lines from various sources.
Class DSNLEXER uses a LINE_READER to read input lines. But that is an abstract class whose contract is fulfilled by FILE_LINE_READER in actual practice. A LINE_READER is capable of telling you the current line number and byte offset of the input stream.
| Name | Value | Description |
|---|---|---|
|
default buffer size for any OUTPUT_FORMATTER |
6.13.1. LINE_READER
#include <richio.h>
class LINE_READER
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived to read single lines of text and manage a line number counter.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Operators |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
|
Members
LINE_READER
LINE_READER(unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX)
Constructor LINE_READER builds a line reader and fixes the length of the maximum supported line length to aMaxLineLength.
Parameters |
|
|---|
~LINE_READER
~LINE_READER()
operator char *
char * operator char *() const
Operator char* is a casting operator that returns a char* pointer to the start of the line buffer.
Returns |
|
|---|
ReadLine
char * ReadLine()
Function ReadLine reads a line of text into the buffer and increments the line number counter.
If the line is larger than aMaxLineLength passed to the constructor, then an exception is thrown. The line is nul terminated.
Returns |
|
|---|---|
Throws |
|
GetSource
const std::string & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
This may be a file or it may be the clipboard or any other source of lines of text. The returned string is useful for reporting error messages.
Returns |
|
|---|
Line
char * Line() const
Function Line returns a pointer to the last line that was read in.
Returns |
|
|---|
LineNumber
unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Lines start from 1.
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Returns |
|
|---|
unsigned m_length
no. bytes in line before trailing nul.
unsigned m_lineNum
char * m_line
the read line of UTF8 text
unsigned m_capacity
no. bytes allocated for line.
unsigned m_maxLineLength
maximum allowed capacity using resizing.
std::string m_source
origin of text lines, e.g. filename or "clipboard"
expandCapacity
void expandCapacity(unsigned aNewsize)
Function expandCapacity will expand the capacity of line up to maxLineLength but not greater, so be careful about making assumptions of capacity after calling this.
Parameters |
|
|---|
6.13.2. FILE_LINE_READER
#include <richio.h>
class FILE_LINE_READER
Class FILE_LINE_READER is a LINE_READER that reads from an open file.
File must be already open so that this class can exist without any UI policy.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Operators |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
|
Members
FILE_LINE_READER
FILE_LINE_READER(const std::string & aFileName,
unsigned aStartingLineNumber = 0,
unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX)
Constructor FILE_LINE_READER takes aFileName and the size of the desired line buffer and opens the file and assumes the obligation to close it.
Parameters |
|
|---|---|
Throws |
|
FILE_LINE_READER
FILE_LINE_READER(FILE * aFile,
const std::string & aFileName,
bool doOwn = true,
unsigned aStartingLineNumber = 0,
unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX)
Constructor FILE_LINE_READER takes an open FILE and the size of the desired line buffer and takes ownership of the open file, i.e.
assumes the obligation to close it.
Parameters |
|
|---|
~FILE_LINE_READER
~FILE_LINE_READER()
Destructor may or may not close the open file, depending on doOwn in constructor.
operator char *
char * operator char *() const
Operator char* is a casting operator that returns a char* pointer to the start of the line buffer.
Returns |
|
|---|
ReadLine
char * ReadLine()
Function ReadLine reads a line of text into the buffer and increments the line number counter.
If the line is larger than aMaxLineLength passed to the constructor, then an exception is thrown. The line is nul terminated.
Returns |
|
|---|---|
Throws |
|
Rewind
void Rewind()
Function Rewind rewinds the file and resets the line number back to zero.
Line number will go to 1 on first ReadLine().
GetSource
const std::string & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
This may be a file or it may be the clipboard or any other source of lines of text. The returned string is useful for reporting error messages.
Returns |
|
|---|
Line
char * Line() const
Function Line returns a pointer to the last line that was read in.
Returns |
|
|---|
LineNumber
unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Lines start from 1.
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Returns |
|
|---|
bool m_iOwn
if I own the file, I’ll promise to close it, else not.
FILE * m_fp
I may own this file, but might not.
unsigned m_length
no. bytes in line before trailing nul.
unsigned m_lineNum
char * m_line
the read line of UTF8 text
unsigned m_capacity
no. bytes allocated for line.
unsigned m_maxLineLength
maximum allowed capacity using resizing.
std::string m_source
origin of text lines, e.g. filename or "clipboard"
expandCapacity
void expandCapacity(unsigned aNewsize)
Function expandCapacity will expand the capacity of line up to maxLineLength but not greater, so be careful about making assumptions of capacity after calling this.
Parameters |
|
|---|
6.13.3. STRING_LINE_READER
#include <richio.h>
class STRING_LINE_READER
Class STRING_LINE_READER is a LINE_READER that reads from a multiline 8 bit wide std::string.
Public Constructors |
|
|---|---|
Public Operators |
|
Public Methods |
|
Protected Variables |
|
Protected Methods |
|
Members
STRING_LINE_READER
STRING_LINE_READER(const std::string & aString,
const std::string & aSource)
Parameters |
|
|---|
STRING_LINE_READER
STRING_LINE_READER(const STRING_LINE_READER & aStartingPoint)
Constructor STRING_LINE_READER( const STRING_LINE_READER& ) allows for a continuation of the reading of a stream started by another STRING_LINE_READER.
Any stream offset and source name are used from aStartingPoint.
Parameters |
|
|---|
operator char *
char * operator char *() const
Operator char* is a casting operator that returns a char* pointer to the start of the line buffer.
Returns |
|
|---|
ReadLine
char * ReadLine()
Function ReadLine reads a line of text into the buffer and increments the line number counter.
If the line is larger than aMaxLineLength passed to the constructor, then an exception is thrown. The line is nul terminated.
Returns |
|
|---|---|
Throws |
|
GetSource
const std::string & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
This may be a file or it may be the clipboard or any other source of lines of text. The returned string is useful for reporting error messages.
Returns |
|
|---|
Line
char * Line() const
Function Line returns a pointer to the last line that was read in.
Returns |
|
|---|
LineNumber
unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Lines start from 1.
Returns |
|
|---|
Length
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Returns |
|
|---|
std::string m_lines
size_t m_ndx
unsigned m_length
no. bytes in line before trailing nul.
unsigned m_lineNum
char * m_line
the read line of UTF8 text
unsigned m_capacity
no. bytes allocated for line.
unsigned m_maxLineLength
maximum allowed capacity using resizing.
std::string m_source
origin of text lines, e.g. filename or "clipboard"
expandCapacity
void expandCapacity(unsigned aNewsize)
Function expandCapacity will expand the capacity of line up to maxLineLength but not greater, so be careful about making assumptions of capacity after calling this.
Parameters |
|
|---|
6.13.4. OUTPUTFORMATTER
#include <richio.h>
class OUTPUTFORMATTER
Class OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a convenient way.
The primary interface is "printf() - like" but with support for indentation control. The destination of the 8 bit wide text is up to the implementer.
The implementer only has to implement the write() function, but can also optionally re-implement GetQuoteChar().
If you want to output a std::string, then use TO_UTF8() on it before passing it as an argument to Print().
Since this is an abstract interface, only classes derived from this one may actually be used.
Public Methods |
|
|---|---|
Protected Constructors |
|
Protected Destructors |
|
Protected Static Methods |
|
Protected Methods |
|
Members
int PRINTF_FUNC Print(int nestLevel,
const char * fmt,
...)
Function Print formats and writes text to the output stream.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
GetQuoteChar
const char * GetQuoteChar(const char * wrapee)
Function GetQuoteChar performs quote character need determination.
It returns the quote character as a single character string for a given input wrapee string. If the wrappee does not need to be quoted, the return value is "" (the null string), such as when there are no delimiters in the input wrapee string. If you want the quote_char to be assuredly not "", then pass in "(" as the wrappee.
Implementations are free to override the default behavior, which is to call the static function of the same name.
Parameters |
|
|---|---|
Returns |
|
Quotes
std::string Quotes(const std::string & aWrapee)
Function Quotes checks aWrapee input string for a need to be quoted (e.g.
contains a ')' character or a space), and for " double quotes within the string that need to be escaped such that the DSNLEXER will correctly parse the string from a file later.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
Quotew
std::string Quotew(const std::string & aWrapee)
Parameters |
|
|---|---|
Returns |
|
OUTPUTFORMATTER
OUTPUTFORMATTER(int aReserve,
char aQuoteChar = '"')
Parameters |
|
|---|
~OUTPUTFORMATTER
~OUTPUTFORMATTER()
GetQuoteChar
static const char * GetQuoteChar(const char * wrapee,
const char * quote_char)
Function GetQuoteChar performs quote character need determination according to the Specctra DSN specification.
Parameters |
|
|---|---|
Returns |
|
write
void write(const char * aOutBuf,
int aCount)
Function write should be coded in the interface implementation (derived) classes.
Parameters |
|
|---|---|
Throws |
|
6.13.5. STRING_FORMATTER
#include <richio.h>
class STRING_FORMATTER
Class STRING_FORMATTER implements OUTPUTFORMATTER to a memory buffer.
After Print()ing the string is available through GetString()
Public Constructors |
|
|---|---|
Public Methods |
|
Protected Static Methods |
|
Protected Methods |
|
Members
STRING_FORMATTER
STRING_FORMATTER(int aReserve,
char aQuoteChar = '"')
Constructor STRING_FORMATTER reserves space in the buffer.
Parameters |
|
|---|
Clear
void Clear()
Function Clear clears the buffer and empties the internal string.
StripUseless
void StripUseless()
Function StripUseless removes whitespace, '(', and ')' from the mystring.
GetString
const std::string & GetString()
Returns |
|
|---|
GetQuoteChar
const char * GetQuoteChar(const char * wrapee)
Function GetQuoteChar performs quote character need determination.
It returns the quote character as a single character string for a given input wrapee string. If the wrappee does not need to be quoted, the return value is "" (the null string), such as when there are no delimiters in the input wrapee string. If you want the quote_char to be assuredly not "", then pass in "(" as the wrappee.
Implementations are free to override the default behavior, which is to call the static function of the same name.
Parameters |
|
|---|---|
Returns |
|
int PRINTF_FUNC Print(int nestLevel,
const char * fmt,
...)
Function Print formats and writes text to the output stream.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
Quotes
std::string Quotes(const std::string & aWrapee)
Function Quotes checks aWrapee input string for a need to be quoted (e.g.
contains a ')' character or a space), and for " double quotes within the string that need to be escaped such that the DSNLEXER will correctly parse the string from a file later.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
Quotew
std::string Quotew(const std::string & aWrapee)
Parameters |
|
|---|---|
Returns |
|
GetQuoteChar
static const char * GetQuoteChar(const char * wrapee,
const char * quote_char)
Function GetQuoteChar performs quote character need determination according to the Specctra DSN specification.
Parameters |
|
|---|---|
Returns |
|
write
void write(const char * aOutBuf,
int aCount)
Function write should be coded in the interface implementation (derived) classes.
Parameters |
|
|---|---|
Throws |
|
6.13.6. FILE_OUTPUTFORMATTER
#include <richio.h>
class FILE_OUTPUTFORMATTER
Class FILE_OUTPUTFORMATTER may be used for text file output.
It is about 8 times faster than STREAM_OUTPUTFORMATTER for file streams.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Methods |
|
Protected Variables |
|
Protected Static Methods |
|
Protected Methods |
|
Members
FILE_OUTPUTFORMATTER
FILE_OUTPUTFORMATTER(const std::string & aFileName,
const char * aMode = "wt",
char aQuoteChar = '"')
Constructor.
Parameters |
|
|---|---|
Throws |
|
~FILE_OUTPUTFORMATTER
~FILE_OUTPUTFORMATTER()
GetQuoteChar
const char * GetQuoteChar(const char * wrapee)
Function GetQuoteChar performs quote character need determination.
It returns the quote character as a single character string for a given input wrapee string. If the wrappee does not need to be quoted, the return value is "" (the null string), such as when there are no delimiters in the input wrapee string. If you want the quote_char to be assuredly not "", then pass in "(" as the wrappee.
Implementations are free to override the default behavior, which is to call the static function of the same name.
Parameters |
|
|---|---|
Returns |
|
int PRINTF_FUNC Print(int nestLevel,
const char * fmt,
...)
Function Print formats and writes text to the output stream.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
Quotes
std::string Quotes(const std::string & aWrapee)
Function Quotes checks aWrapee input string for a need to be quoted (e.g.
contains a ')' character or a space), and for " double quotes within the string that need to be escaped such that the DSNLEXER will correctly parse the string from a file later.
Parameters |
|
|---|---|
Returns |
|
Throws |
|
Quotew
std::string Quotew(const std::string & aWrapee)
Parameters |
|
|---|---|
Returns |
|
FILE * m_fp
takes ownership
std::string m_filename
GetQuoteChar
static const char * GetQuoteChar(const char * wrapee,
const char * quote_char)
Function GetQuoteChar performs quote character need determination according to the Specctra DSN specification.
Parameters |
|
|---|---|
Returns |
|
write
void write(const char * aOutBuf,
int aCount)
Function write should be coded in the interface implementation (derived) classes.
Parameters |
|
|---|---|
Throws |
|
6.14. SoftPLC Exceptions
These are classes thrown as exceptions.
6.14.1. THROW_IO_ERROR()
#define THROW_IO_ERROR(msg) throw IO_ERROR( msg, __FILE__, __FUNCTION__, __LINE__ )
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
Parameters |
|
|---|
6.14.2. THROW_PARSE_ERROR()
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex) throw PARSE_ERROR( aProblem, __FILE__, __FUNCTION__, __LINE__, aSource, aInputLine, aLineNumber, aByteIndex )
Parameters |
|
|---|
6.14.3. ERROR
#include <exceptions.h>
class ERROR
Class Error is an exception that is thrown to indicate problems in the SoftPLC C++ API usage.
It holds a string that can be obtained with the what() function.
Public Constructors |
|
|---|---|
Public Destructors |
|
Public Methods |
|
Protected Variables |
Members
ERROR
ERROR(int aErrorCode,
const char * aMessage,
...)
Constructor ERROR takes a printf() style format string with a variable number of matching arguments to formulate the text of the exception.
Parameters |
|
|---|
ERROR
ERROR(int aErrorCode)
Parameters |
|
|---|
~ERROR
~ERROR()
what
const char * what() const
Function what implements class std::exception’s contract API.
Returns |
|
|---|
ErrorCode
int ErrorCode() const
Function ErrorCode returns the int value passed as aErrorCode to the constructor.
Returns |
|
|---|
6.14.4. RUNTIME_ERROR
#include <exceptions.h>
class RUNTIME_ERROR
Class RUNTIME_ERROR is used in the SoftPLC runtime for its ability to capture execution context or datatable address context of the ladder logic engine.
It can hold an extended address consisting of file, element_or_rung, and word_or_index.
Public Constructors |
|
|---|---|
Public Methods |
|
Protected Variables |
Members
RUNTIME_ERROR
RUNTIME_ERROR(int aErrorCode,
const char * aFormatString,
...)
Constructor RUNTIME_ERROR( int aErrorCode, const char* aFormatString, …) takes a printf() style format string with a variable number of matching arguments to formulate the text of the exception.
Parameters |
|
|---|
RUNTIME_ERROR
RUNTIME_ERROR(const char * aMessage,
int aErrorCode)
Parameters |
|
|---|
RUNTIME_ERROR
RUNTIME_ERROR(const char * aMessage,
int aErrorCode,
va_list ap)
Parameters |
|
|---|
Problem
std::string Problem() const
Returns |
|
|---|
File
int File() const
Returns |
|
|---|
Rung
int Rung() const
Returns |
|
|---|
InstrIndex
int InstrIndex() const
Returns |
|
|---|
IsCompileError
bool IsCompileError() const
Returns |
|
|---|
what
const char * what() const
Function what implements class std::exception’s contract API.
Returns |
|
|---|
ErrorCode
int ErrorCode() const
Function ErrorCode returns the int value passed as aErrorCode to the constructor.
Returns |
|
|---|
6.14.5. IO_ERROR
#include <exceptions.h>
class IO_ERROR
Class IO_ERROR is a class used to hold an error message and may be used when throwing exceptions containing meaningful error messages.
Author |
Dick Hollenbeck |
|---|---|
Public Constructors |
|
Public Destructors |
|
Public Methods |
|
Protected Variables |
Members
IO_ERROR
IO_ERROR(const std::string & aProblem,
const char * aThrowersFile,
const char * aThrowersFunction,
int aThrowersLineNumber)
Constructor.
THROW_IO_ERROR() to wrap a call to this constructor at the call site.
Parameters |
|
|---|
IO_ERROR
IO_ERROR()
~IO_ERROR
~IO_ERROR()
init
void init(const std::string & aProblem,
const char * aThrowersFile,
const char * aThrowersFunction,
int aThrowersLineNumber)
Parameters |
|
|---|
Problem
const std::string Problem() const
what was the problem?
Returns |
|
|---|
what
const char * what() const
Function what implements class std::exception’s contract API.
Returns |
|
|---|
ErrorCode
int ErrorCode() const
Function ErrorCode returns the int value passed as aErrorCode to the constructor.
Returns |
|
|---|
6.14.6. PARSE_ERROR
#include <exceptions.h>
struct PARSE_ERROR
Struct PARSE_ERROR contains a filename or source description, a problem input line, a line number, a byte offset, and an error message which contains the the caller’s report and his call site information: CPP source file, function, and line number.
Author |
Dick Hollenbeck |
|---|---|
Public Constructors |
|
Public Destructors |
|
Public Variables |
|
Public Methods |
|
Protected Constructors |
|
Protected Variables |
Members
PARSE_ERROR
PARSE_ERROR(const std::string & aProblem,
const char * aThrowersFile,
const char * aThrowersFunction,
int aThrowersLineNumber,
const std::string & aSource,
const char * aInputLine,
int aLineNumber,
int aByteIndex)
Constructor which is normally called via the macro THROW_PARSE_ERROR so that FILE and FUNCTION and LINE can be captured from the call site.
Parameters |
|
|---|
~PARSE_ERROR
~PARSE_ERROR()
int lineNumber
at which line number, 1 based index.
int byteIndex
at which byte offset within the line, 1 based index
std::string inputLine
problem line of input [say, from a LINE_READER]. this is brought up in original byte format rather than std::string form, incase there was a problem with the encoding, in which case converting to std::string is not reliable in this context.
init
void init(const std::string & aProblem,
const char * aThrowersFile,
const char * aThrowersFunction,
int aThrowersLineNumber,
const std::string & aSource,
const char * aInputLine,
int aLineNumber,
int aByteIndex)
Parameters |
|
|---|
init
void init(const std::string & aProblem,
const char * aThrowersFile,
const char * aThrowersFunction,
int aThrowersLineNumber)
Parameters |
|
|---|
Problem
const std::string Problem() const
what was the problem?
Returns |
|
|---|
what
const char * what() const
Function what implements class std::exception’s contract API.
Returns |
|
|---|
ErrorCode
int ErrorCode() const
Function ErrorCode returns the int value passed as aErrorCode to the constructor.
Returns |
|
|---|
PARSE_ERROR
PARSE_ERROR()
std::string problem
std::string where
std::string text
int error_code