Files
Codesys-Library-Atom-Modbus/docs/API-REFERENCE.md
T

1591 lines
66 KiB
Markdown

# atMb API reference
Generated from your working `CmpAtomModbus(1).export`. Documents every code object, including internal methods and property accessors. Runtime implementations, identifiers, declarations and embedded native payloads are preserved in the documented export; additions are comments only.
## atMbCall_cext
External C ABI entry point used by the wrappers. Application code should normally call the function blocks. Do not change parameter order/types or external implementation settings. Pointers are accessed synchronously by C; provide distinct valid data/status buffers and truthful capacities. Client status requires 24 UDINT elements. All calls must be owned by one IEC task.
```iecst
(* Create FUNCTION atMbCall_cext returning UDINT, paste this declaration.
Properties > Build > External implementation must be selected.
Library filename and Project Information title: CmpAtomModbus.
This declaration is the SINGLE external entry point for the C engine. *)
FUNCTION atMbCall_cext : UDINT
VAR_INPUT
command : UDINT;
handle : UDINT;
ipAddress : DWORD;
port : UINT;
unitId : BYTE;
functionCode : BYTE;
startAddress : UINT;
quantity : UINT;
pData : POINTER TO WORD;
dataCapacity : UDINT;
pStatus : POINTER TO UDINT;
statusCapacity : UDINT;
nowMs : ULINT;
connectTimeoutMs : UDINT;
responseTimeoutMs : UDINT;
retryDelayMs : UDINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `command` | VAR_INPUT | `UDINT` | Native command selector. Use wrappers in application code. |
| `handle` | VAR_INPUT | `UDINT` | Generation-checked native context handle; 0 for open. |
| `ipAddress` | VAR_INPUT | `DWORD` | Packed IPv4 for TCP commands; command 20 overloads this field with RTU baud rate. |
| `port` | VAR_INPUT | `UINT` | Slave listening port, default 502, must be nonzero. |
| `unitId` | VAR_INPUT | `BYTE` | Transaction unit ID; command 20 overloads it with serial parity. |
| `functionCode` | VAR_INPUT | `BYTE` | Modbus FC; command 20 uses data bits, server push/pull use table ID. |
| `startAddress` | VAR_INPUT | `UINT` | Protocol start; command 20 uses stop bits. |
| `quantity` | VAR_INPUT | `UINT` | Item count; command 20 uses serial path byte count. |
| `pData` | VAR_INPUT | `POINTER TO WORD` | WORD buffer; client reads/writes, serial ASCII path, or server table staging. |
| `dataCapacity` | VAR_INPUT | `UDINT` | Available WORD elements, not bytes. |
| `pStatus` | VAR_INPUT | `POINTER TO UDINT` | UDINT status buffer; requires at least 24 elements. |
| `statusCapacity` | VAR_INPUT | `UDINT` | Available UDINT elements, not bytes. |
| `nowMs` | VAR_INPUT | `ULINT` | Monotonic time in milliseconds; wrappers use SysTimeGetUs / 1000. |
| `connectTimeoutMs` | VAR_INPUT | `UDINT` | TCP connection timeout; command 20 uses kernel RS485 flag. |
| `responseTimeoutMs` | VAR_INPUT | `UDINT` | Reply deadline in milliseconds. |
| `retryDelayMs` | VAR_INPUT | `UDINT` | Native recovery wait in milliseconds. |
## ModbusMaster.ClientStatus
Aggregate request status used by the RTU monitoring property: noneOk=0, someOk=1, allOk=2. This describes request online flags, not the physical connection. The current toString getter compares onlineCnt with all registered requests and reports allOk for an empty registry.
```iecst
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE ClientStatus :
(
noneOk := 0,
someOk := 1,
allOk := 2
);
END_TYPE
```
## ModbusMaster.Error
IEC error classification. TCP-named socket/timeout members are also used for RTU failures. For the precise native reason inspect out_nativeError/out_lastNativeError; for an OS failure inspect out_socketError.
```iecst
{attribute 'qualified_only'}
TYPE Error : (
OK := 0, RequestParameterError := 1, TcpSocketError := 4,
TcpConnectTimeout := 5, ReplyTimeout := 6, InvalidReply := 8,
RequestException := 9, RequestCancelled := 10, InternalError := 255
);
END_TYPE
```
## ModbusMaster.ExceptionCodes
Modbus exception response values plus local TIMEOUT=-1. A valid Modbus exception proves communication, but the requested operation failed. In current statistics, non-exception errors can also be classified as TIMEOUT; use native diagnostics to distinguish their actual cause.
```iecst
{attribute 'qualified_only'}
TYPE ExceptionCodes :
(
// Local / transport-level (non-Modbus) result
TIMEOUT := -1, // Communication timeout / no response
// Modbus exception codes (returned in exception response PDU)
RESPONSE_SUCCESS := 16#00, // Everything OK (no exception)
ILLEGAL_FUNCTION := 16#01, // Function code not supported by slave
ILLEGAL_DATA_ADDRESS := 16#02, // Data address not valid for slave (out of range / not mapped)
ILLEGAL_DATA_VALUE := 16#03, // Data value not valid (bad length/value/etc.)
SLAVE_DEVICE_FAILURE := 16#04, // Unrecoverable error while performing the requested action
ACKNOWLEDGE := 16#05, // Request accepted; processing started (use to avoid master timeout)
SLAVE_DEVICE_BUSY := 16#06, // Slave busy (e.g. long operation in progress); retry later
MEMORY_PARITY_ERROR := 16#08, // Memory parity error (special case; historically for FC 20/21)
GATEWAY_PATH_UNAVAILABLE := 16#0A, // Gateway problem: path unavailable / misconfigured / overloaded
GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND := 16#0B // Gateway problem: target device did not respond
);
END_TYPE
```
## ModbusMaster.ClientBase
Abstract shared client scheduler and native transport owner. Use ClientTCP or ClientRTU. Holds up to 100 registered requests and runs one transaction at a time. Call the concrete client once per scan, from the same task as its requests.
```iecst
{attribute 'monitoring_display' := 'toString'}
{attribute 'no_assign'}
FUNCTION_BLOCK ABSTRACT ClientBase
VAR_INPUT
{attribute 'symbol' := 'none'}
in_timeout: TIME := T#0MS; // If this is set, this will be used on requests, otherwise it will be calculated from in_dataRate.
{attribute 'symbol' := 'none'}
in_resetStats: BOOL; // Set this bool to true to reset statistics.
END_VAR
VAR_OUTPUT
{attribute 'symbol' := 'none'}
msgLastSecondCnt: UDINT; //Messages in the last second
{attribute 'symbol' := 'none'}
msgLastSecondTime: UDINT; //Total amount of time for all messages sent last second in ms
{attribute 'symbol' := 'none'}
numMsgSent: UDINT;
{attribute 'symbol' := 'none'}
numMsgReply: UDINT;
{attribute 'symbol' := 'none'}
allRequestsOnline: BOOL; //All requests are working
reqStats: ARRAY[0..99] OF POINTER TO RequestStats; // For debugging modbus requests
END_VAR
VAR
dataRate : DINT;
requests : ARRAY[0..99] OF POINTER TO RequestBase;
requestCnt : UINT;
allRequestsOffline : BOOL;
END_VAR
VAR
nativeMode : BOOL;
nativeHandle : UDINT;
nativeIP : DWORD;
nativePort : UINT;
nativeNowMicroseconds : SYSTIME;
nativeNowMilliseconds : ULINT;
nativeStatus : ARRAY[0..23] OF UDINT;
nativeActiveIndex : DINT := -1;
nativeSelected : POINTER TO RequestBase;
nativeResultReady : BOOL;
nativeFinishedIndex : DINT := -1;
nativeWindowStartMilliseconds : ULINT;
nativeWasConnected : BOOL;
nativeEnable : BOOL := TRUE;
nativeConnectTimeoutMilliseconds : UDINT := 2000;
nativeRetryDelayMilliseconds : UDINT := 100;
nativeHoldUncertainWrites : BOOL := FALSE;
END_VAR
VAR_INPUT
{attribute 'symbol' := 'none'}
nativeIO : ARRAY[0..1999] OF WORD;
{attribute 'symbol' := 'none'}
nativeActiveRequest : POINTER TO RequestBase;
{attribute 'symbol' := 'none'}
nativeArgUnit : BYTE;
{attribute 'symbol' := 'none'}
nativeArgFunction : BYTE;
{attribute 'symbol' := 'none'}
nativeArgAddress : UINT;
{attribute 'symbol' := 'none'}
nativeArgQuantity : UINT;
{attribute 'symbol' := 'none'}
nativeArgTimeout : UDINT := 1000;
{attribute 'symbol' := 'none'}
nativeSent : UDINT;
{attribute 'symbol' := 'none'}
nativeReplied : UDINT;
{attribute 'symbol' := 'none'}
nativeWindowCount : UDINT;
{attribute 'symbol' := 'none'}
nativeWindowTime : UDINT;
END_VAR
VAR_OUTPUT
out_connected : BOOL;
out_connectionState : UDINT;
out_lastNativeError : UDINT;
out_socketError : UDINT;
out_reconnectCount : UDINT;
out_registrationFull : BOOL;
END_VAR
VAR CONSTANT
NATIVE_CMD_OPEN : UDINT := 1;
NATIVE_CMD_CLOSE : UDINT := 2;
NATIVE_CMD_ENABLE : UDINT := 3;
NATIVE_CMD_TICK : UDINT := 5;
NATIVE_CMD_SUBMIT : UDINT := 6;
NATIVE_CMD_COPY_READ : UDINT := 7;
NATIVE_CMD_CONFIGURE : UDINT := 9;
NATIVE_CMD_ACKNOWLEDGE : UDINT := 10;
NATIVE_CMD_REQUEST_TIMEOUT : UDINT := 11;
NATIVE_STATE_DISABLED : UDINT := 0;
NATIVE_STATE_READY : UDINT := 3;
NATIVE_STATE_RECEIVING : UDINT := 5;
NATIVE_ERROR_INVALID_HANDLE : UDINT := 256;
NATIVE_ERROR_CANCELLED : UDINT := 10;
NATIVE_STATUS_HANDLE : UDINT := 0;
NATIVE_STATUS_STATE : UDINT := 1;
NATIVE_STATUS_DONE : UDINT := 3;
NATIVE_STATUS_ERROR : UDINT := 4;
NATIVE_STATUS_RESULT : UDINT := 5;
NATIVE_STATUS_LAST_ERROR : UDINT := 6;
NATIVE_STATUS_SOCKET_ERROR : UDINT := 7;
NATIVE_STATUS_EXCEPTION : UDINT := 8;
NATIVE_STATUS_WRITE_UNCERTAIN : UDINT := 9;
NATIVE_STATUS_RECONNECTS : UDINT := 11;
NATIVE_STATUS_FUNCTION : UDINT := 18;
END_VAR
VAR
nativeOpenCommand : UDINT := 1;
nativeDevice : STRING(127);
nativeSerialBaud : UDINT;
nativeSerialParity : BYTE;
nativeSerialBits : BYTE;
nativeSerialStops : BYTE;
nativeSerialRs485 : UDINT;
END_VAR
VAR_INPUT
in_enable : BOOL := TRUE;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in_timeout` | VAR_INPUT | `TIME := T#0MS` | Reply timeout override. ClientBase: TIME; RequestBase: SYSTIME numeric milliseconds (not microseconds). Zero selects inherited/calculated timeout. |
| `in_resetStats` | VAR_INPUT | `BOOL` | Reset request consumed and cleared by nativeCycle. Supplying TRUE on every call resets statistics every scan; pulse once. |
| `msgLastSecondCnt` | VAR_OUTPUT | `UDINT` | Submitted request count in the last completed window of at least 1000 ms, not necessarily an exact sliding second. |
| `msgLastSecondTime` | VAR_OUTPUT | `UDINT` | Sum of successful transaction durations in that completed window (ms); excludes failed durations. |
| `numMsgSent` | VAR_OUTPUT | `UDINT` | IEC accepted submission count since resetStats; not a count of physical packets. |
| `numMsgReply` | VAR_OUTPUT | `UDINT` | IEC successful or Modbus-exception reply count since resetStats. |
| `allRequestsOnline` | VAR_OUTPUT | `BOOL` | TRUE when at least one active request exists and onlineCnt equals activeReqCnt. Online can include exception replies. |
| `reqStats` | VAR_OUTPUT | `ARRAY[0..99] OF POINTER TO RequestStats` | Pointers to registered request statistics by registry index, populated on client scans. Null entries are unused; validate before dereference. |
| `nativeIO` | VAR_INPUT | `ARRAY[0..1999] OF WORD` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeActiveRequest` | VAR_INPUT | `POINTER TO RequestBase` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeArgUnit` | VAR_INPUT | `BYTE` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeArgFunction` | VAR_INPUT | `BYTE` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeArgAddress` | VAR_INPUT | `UINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeArgQuantity` | VAR_INPUT | `UINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeArgTimeout` | VAR_INPUT | `UDINT := 1000` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeSent` | VAR_INPUT | `UDINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeReplied` | VAR_INPUT | `UDINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeWindowCount` | VAR_INPUT | `UDINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `nativeWindowTime` | VAR_INPUT | `UDINT` | Internal wrapper state exposed for compatibility; normally leave under library control. |
| `out_connected` | VAR_OUTPUT | `BOOL` | Transport is in ready/sending/receiving state. Does not prove a request succeeded or data is fresh. |
| `out_connectionState` | VAR_OUTPUT | `UDINT` | 0 disabled, 1 retry wait, 2 TCP connecting, 3 ready, 4 sending, 5 receiving. |
| `out_lastNativeError` | VAR_OUTPUT | `UDINT` | Native last transport error; may persist after recovery. Check current connection and request diagnostics too. |
| `out_socketError` | VAR_OUTPUT | `UDINT` | Native Linux errno snapshot as UDINT; may be historical. Used for both serial and sockets. |
| `out_reconnectCount` | VAR_OUTPUT | `UDINT` | Native successful reconnections after the first connection. Context recreation resets its native lifetime counters. |
| `out_registrationFull` | VAR_OUTPUT | `BOOL` | Sticky request registry overflow indicator; max 100 requests/client. Client reinitialization clears it. |
| `in_enable` | VAR_INPUT | `BOOL := TRUE` | Enable processing; TRUE by default. FALSE releases transport. Continue scanning to refresh state. |
## ModbusMaster.ClientRTU
Modbus RTU client using a Linux serial device. Call every scan. Supports 8 data bits, parity 0 none/1 odd/2 even, and 1 or 2 stop bits. Uses unit IDs 1..247; broadcast 0 is unsupported. Serial-setting changes recreate the context. Automatic recovery proceeds while enabled and scanned.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ClientRTU EXTENDS ClientBase
VAR_INPUT
in_device : STRING(127) := '/dev/ttyUSB0';
in_baudRate : UDINT := 9600;
in_parity : BYTE := 0; // 0 none, 1 odd, 2 even
in_dataBits : BYTE := 8;
in_stopBits : BYTE := 1; // 1 or 2
in_rs485 : BOOL; // Request Linux kernel RS485 direction control.
in_reconnectDelay : TIME := T#100MS;
in_holdUncertainWrites : BOOL := FALSE;
END_VAR
VAR
lastDevice : STRING(127);
lastBaud : UDINT;
lastParity : BYTE;
lastBits : BYTE;
lastStops : BYTE;
lastRs485 : BOOL;
lastRetry : TIME;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in_device` | VAR_INPUT | `STRING(127) := '/dev/ttyUSB0'` | Linux serial device path, default /dev/ttyUSB0, at most 127 ASCII characters. Runtime account needs access. |
| `in_baudRate` | VAR_INPUT | `UDINT := 9600` | Serial baud rate, default 9600. Supplied C source accepts 1200,2400,4800,9600,19200,38400,57600,115200. |
| `in_parity` | VAR_INPUT | `BYTE := 0` | 0 none, 1 odd, 2 even. Must match the slave. |
| `in_dataBits` | VAR_INPUT | `BYTE := 8` | Only 8 supported by supplied native implementation. |
| `in_stopBits` | VAR_INPUT | `BYTE := 1` | 1 or 2; must match the slave. |
| `in_rs485` | VAR_INPUT | `BOOL` | Request Linux kernel RS485 direction control. Leave FALSE for USB adapters handling direction automatically. Requires driver support. |
| `in_reconnectDelay` | VAR_INPUT | `TIME := T#100MS` | Delay before native recovery attempt, default 100 ms; clamped to at least 1 ms. Effective timing also depends on scan interval and failure detection. |
| `in_holdUncertainWrites` | VAR_INPUT | `BOOL := FALSE` | FALSE allows normal retries after uncertain writes. TRUE holds affected write requests until writeNow(); read requests can continue. |
## ModbusMaster.ClientTCP
Modbus TCP client with automatic retry after connection or transaction failure. Call every scan. Endpoint or timeout/retry configuration changes close the current context and reopen it on subsequent scans. Requests share this connection and execute sequentially.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ClientTCP EXTENDS ClientBase
VAR_INPUT
{attribute 'symbol' := 'none'}
in_ipAddress: ARRAY[0..3] OF BYTE; // TCP IP Address
{attribute 'symbol' := 'none'}
in_port: UINT := 502; // TCP port
{attribute 'symbol' := 'none'}
in_baudrate: UINT := 0; // Set this if using RS485 to TCP Converter, used to calculate timeout.
END_VAR
VAR_INPUT
in_connectTimeout : TIME := T#2S;
in_reconnectDelay : TIME := T#100MS; // Delay after a failed TCP connection/transaction.
in_holdUncertainWrites : BOOL := FALSE;
END_VAR
VAR
nativeEndpointIP : DWORD;
nativeEndpointPort : UINT;
nativeConfigConnect : UDINT;
nativeConfigRetry : UDINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in_ipAddress` | VAR_INPUT | `ARRAY[0..3] OF BYTE` | ClientTCP: four IPv4 bytes. Slave: packed numeric DWORD, 0 binds all interfaces; e.g. DWORD#16#C0A8321F for 192.168.50.31. |
| `in_port` | VAR_INPUT | `UINT := 502` | Remote TCP port, default 502. |
| `in_baudrate` | VAR_INPUT | `UINT := 0` | TCP gateway serial baud-rate hint for calculated reply timeout; 0 uses internal dataRate 105200. Does not configure a serial port. |
| `in_connectTimeout` | VAR_INPUT | `TIME := T#2S` | TCP connection-attempt deadline, default 2 s; clamped to at least 1 ms. |
| `in_reconnectDelay` | VAR_INPUT | `TIME := T#100MS` | Delay before native recovery attempt, default 100 ms; clamped to at least 1 ms. Effective timing also depends on scan interval and failure detection. |
| `in_holdUncertainWrites` | VAR_INPUT | `BOOL := FALSE` | FALSE allows normal retries after uncertain writes. TRUE holds affected write requests until writeNow(); read requests can continue. |
## ModbusMaster.ReqReadCoil
Modbus FC 1: read BOOL coils. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 2000. Usable length is clamped to array capacity. Only a successful validated reply updates the destination slice. Old values remain after failures; check out_validData and out_stale.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqReadCoil EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF BOOL to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.ReqReadDiscrete
Modbus FC 2: read BOOL discrete inputs. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 2000. Usable length is clamped to array capacity. Only a successful validated reply updates the destination slice. Old values remain after failures; check out_validData and out_stale.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqReadDiscrete EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF BOOL to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.ReqReadHolding
Modbus FC 3: read UINT holding registers. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 125. Usable length is clamped to array capacity. Only a successful validated reply updates the destination slice. Old values remain after failures; check out_validData and out_stale.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqReadHolding EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF UINT to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF UINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.ReqReadInput
Modbus FC 4: read UINT input registers. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 125. Usable length is clamped to array capacity. Only a successful validated reply updates the destination slice. Old values remain after failures; check out_validData and out_stale.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqReadInput EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF UINT to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF UINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.RequestBase
Abstract request binding, scheduling and diagnostics. Derived requests register automatically when called with a valid initialized client. Call each instance every scan with stable array storage. Quantity zero disables this request. Actual length is MIN(in_quantity, remaining array capacity).
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ABSTRACT RequestBase
VAR_INPUT
{attribute 'symbol' := 'none'}
client: REFERENCE TO ClientBase; // Instance of atMBClient
{attribute 'symbol' := 'none'}
in_startAddr: UINT;
{attribute 'symbol' := 'none'}
in_quantity: UINT;
{attribute 'symbol' := 'none'}
in_dataOffset: UINT; // Offset position for data into array.
{attribute 'symbol' := 'none'}
in_unitId: BYTE := 0;
{attribute 'symbol' := 'none'}
in_timeout: SYSTIME := 0; // Reply timeout in ms; zero uses client/default calculation.
{attribute 'symbol' := 'none'}
in_minDelay: TIME := T#10MS; // This is the minimum delay between queries, only relevent if high priority.
{attribute 'symbol' := 'none'}
in_prioritySetpoint: INT := 50; // this requests priority compared to other requests. Lower value is higher priority.
{attribute 'symbol' := 'none'}
in_priorityCurrent: INT; //Current priority. This is decrimented and the request is executed when at zero.
{attribute 'symbol' := 'none'}
stats: RequestStats; //Request stats
END_VAR
VAR
{attribute 'symbol' := 'none'}
dataCapacity: UINT;
END_VAR
VAR
nativeFunction : BYTE;
nativeTransactionQuantity : UINT;
nativeTransactionDataIndex : UINT;
nativeInFlight : BOOL;
nativeReadComplete : BOOL;
nativeCopyAllowed : BOOL;
nativeWriteHold : BOOL;
nativeRequestStartMilliseconds : ULINT;
nativeDataIndex : DINT;
nativeCallResult : UDINT;
END_VAR
VAR_OUTPUT
out_nativeError : UDINT;
out_socketError : UDINT;
out_writeUncertain : BOOL;
out_validData : BOOL;
out_dataAgeMs : ULINT;
out_stale : BOOL := TRUE;
out_parameterError : BOOL;
END_VAR
VAR_INPUT
in_staleAfter : TIME := T#2S;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `client` | VAR_INPUT | `REFERENCE TO ClientBase` | Reference to the owning ClientBase concrete instance. Initialize/call client before first registration; retain a stable instance. |
| `in_startAddr` | VAR_INPUT | `UINT` | Zero-based Modbus protocol address, not a 40001/30001 display reference. Must fit the transaction into address space. |
| `in_quantity` | VAR_INPUT | `UINT` | Requested item count; actual stats.reqLength is MIN(this, available destination/source capacity). Zero makes the request inactive. |
| `in_dataOffset` | VAR_INPUT | `UINT` | Actual first index in the application array. For ARRAY[1..10], use 1 to start at the first element; not a relative offset. |
| `in_unitId` | VAR_INPUT | `BYTE := 0` | Modbus unit/slave ID, default 0. RTU requires explicit 1..247; TCP/gateway values depend on the target. |
| `in_timeout` | VAR_INPUT | `SYSTIME := 0` | Reply timeout override. ClientBase: TIME; RequestBase: SYSTIME numeric milliseconds (not microseconds). Zero selects inherited/calculated timeout. |
| `in_minDelay` | VAR_INPUT | `TIME := T#10MS` | Minimum start-to-start time before scheduler eligibility, default 10 ms. Not a fixed polling period. |
| `in_prioritySetpoint` | VAR_INPUT | `INT := 50` | Priority restored on success, default 50. Lower values win. Error backoff can replace current priority. |
| `in_priorityCurrent` | VAR_INPUT | `INT` | Mutable scheduler priority. Lower values win, equal values use age. WriteNow sets 0. Application need not maintain it each scan. |
| `stats` | VAR_INPUT | `RequestStats` | Per-request RequestStats instance maintained by request processing; inspect rather than overwrite. |
| `out_nativeError` | VAR_OUTPUT | `UDINT` | Result of the last completed/failed request; 0 success. Precise native code, distinct from IEC Error enum. |
| `out_socketError` | VAR_OUTPUT | `UDINT` | Native Linux errno snapshot as UDINT; may be historical. Used for both serial and sockets. |
| `out_writeUncertain` | VAR_OUTPUT | `BOOL` | Write may have reached target without a confirmed response. It is not proof of failure or success. Relevant for write requests. |
| `out_validData` | VAR_OUTPUT | `BOOL` | TRUE after a successful read; subsequent read failures do not necessarily clear it. Client release or invalidateNativeData clears it. |
| `out_dataAgeMs` | VAR_OUTPUT | `ULINT` | Age since last successful read in milliseconds. Updated by normal processing; completion early returns can defer refresh by one scan. |
| `out_stale` | VAR_OUTPUT | `BOOL := TRUE` | TRUE before valid read data or when age exceeds in_staleAfter. Array contents are retained. |
| `out_parameterError` | VAR_OUTPUT | `BOOL` | Array-offset validation for requests; full transaction validation can instead appear in out_nativeError/stats.lastErrorId. Slave: invalid port/interfaceName/table bounds or capacity. |
| `in_staleAfter` | VAR_INPUT | `TIME := T#2S` | Read data age threshold, default 2 s. out_stale becomes TRUE when age is strictly greater; does not stop polling. |
## ModbusMaster.RequestStats
Request counters, completion properties, online/offline tracking and 100 ms indicator lights. Normally maintained by RequestBase. Online means a valid response was received, including a Modbus exception; it does not guarantee successful data. Several fields are declared VAR_INPUT for compatibility but are maintained internally.
```iecst
{attribute 'monitoring_display' := 'toString'}
{attribute 'no_assign'}
FUNCTION_BLOCK RequestStats
VAR_INPUT
lastErrorId: Error; //Last error id
lastExceptionCode: ExceptionCodes; //Last modbus exception code. These are the standard modbus exceptions.
lastValidDuration: UDINT; // How long last transaction took (ms)
longestValidDuration: UDINT; //Longest valid duration (ms)
interval: UDINT; // Start-to-start interval (ms)
offlineCnt: UINT; //Count of how many times this request has gone offline
doneCnt: UDINT; // Count of successful request
errorCnt: UDINT; // Count of failed requests
doneCntRst: UDINT; // Count of succesful requests, resets on error result
errorCntRst: UDINT; // Count of failed requests, resets on succesful request
sinceLastExec: UDINT; // Time since the last start (ms)
timeoutCnt: UDINT;
reqLength: UINT; //Number of registers requested in request, used to calc active.
END_VAR
VAR_OUTPUT
executeLight: BOOL; //Execute that stays on momentarily
reqDoneLight: BOOL; //Request done that stays on momentarily
reqErrorLight: BOOL; //Request error that stays on momentarily
reqBusyLight: BOOL; //Request busy that stays on momentarily
online: BOOL; //Online means the requests are being replied to normally or with modbus exceptions. Communications are ok.
offline: BOOL; //Opposite of online, but starts out as false on program start.
active: BOOL; // This is true if its actually being used, and not having a count of 0 on the request.
executeMbFb: BOOL;
END_VAR
VAR
{attribute 'symbol' := 'none'}
doneIndicatorDelay: TOF;
{attribute 'symbol' := 'none'}
errorIndicatorDelay: TOF;
{attribute 'symbol' := 'none'}
busyIndicatorDelay: TOF;
{attribute 'symbol' := 'none'}
executeIndicatorDelay: TOF;
toString: STRING(20);
{attribute 'symbol' := 'none'}
executeTrig: R_TRIG; //Execute trigger
{attribute 'symbol' := 'none'}
offlineTrig: R_TRIG; //Offline trigger
{attribute 'symbol' := 'none'}
lastRequestStartMicroseconds: SYSTIME; //time of start of last request
{attribute 'symbol' := 'none'}
currentTimeMicroseconds: SYSTIME;
_execute: BOOL; //Execute trigger and status. Turn on to trigger request. Will turn off when request is complete
_reqDone: BOOL; //Request done
_reqBusy: BOOL; //Request busy
_reqError: BOOL; //Request error
END_VAR
VAR CONSTANT
{attribute 'symbol' := 'none'}
INDICATOR_HOLD_TIME: TIME:= T#100MS; //Light on time for debug indicators
END_VAR
VAR_INPUT
nativeResponseSeen : BOOL;
nativeLastSuccessMs : ULINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `lastErrorId` | VAR_INPUT | `Error` | Last mapped IEC error; successful completion resets to OK. |
| `lastExceptionCode` | VAR_INPUT | `ExceptionCodes` | Last Modbus exception, success=0; stats may substitute TIMEOUT=-1 for non-exception failures. |
| `lastValidDuration` | VAR_INPUT | `UDINT` | Last successful request duration (ms). |
| `longestValidDuration` | VAR_INPUT | `UDINT` | Maximum successful duration recorded; resetStats does not clear it. |
| `interval` | VAR_INPUT | `UDINT` | Start-to-start execution interval (ms). |
| `offlineCnt` | VAR_INPUT | `UINT` | Count of NOT online rising edges; can include initial not-online state, not only a physical disconnect. |
| `doneCnt` | VAR_INPUT | `UDINT` | Total successful completions; resetStats clears. |
| `errorCnt` | VAR_INPUT | `UDINT` | Total failed completions; resetStats clears. |
| `doneCntRst` | VAR_INPUT | `UDINT` | Consecutive successes; reset on error/offline/resetStats. |
| `errorCntRst` | VAR_INPUT | `UDINT` | Consecutive errors; reset on successful completion/resetStats. |
| `sinceLastExec` | VAR_INPUT | `UDINT` | Age since last execution start (ms), capped around 60000 by the statistics clock logic. |
| `timeoutCnt` | VAR_INPUT | `UDINT` | Statistics non-exception error count; can include other native failures. Not exclusively reply timeouts; resetStats does not clear it. |
| `reqLength` | VAR_INPUT | `UINT` | Effective transaction length; zero means inactive. |
| `executeLight` | VAR_OUTPUT | `BOOL` | Execution indicator with 100 ms off-delay. |
| `reqDoneLight` | VAR_OUTPUT | `BOOL` | Completion indicator with 100 ms off-delay. |
| `reqErrorLight` | VAR_OUTPUT | `BOOL` | Error indicator with 100 ms off-delay. |
| `reqBusyLight` | VAR_OUTPUT | `BOOL` | Busy indicator with 100 ms off-delay. |
| `online` | VAR_OUTPUT | `BOOL` | Communication status; valid normal/exception response sets evidence. Distinct from valid data. |
| `offline` | VAR_OUTPUT | `BOOL` | Offline status; initialized FALSE, explicitly set on client-offline or repeated failures. |
| `active` | VAR_OUTPUT | `BOOL` | TRUE when reqLength is nonzero. |
| `executeMbFb` | VAR_OUTPUT | `BOOL` | Legacy retained output; no assignment in current native implementation. Do not use as a trigger. |
| `nativeResponseSeen` | VAR_INPUT | `BOOL` | Internal communication-response evidence, maintained by nativeFinish and offline handling. |
| `nativeLastSuccessMs` | VAR_INPUT | `ULINT` | Internal successful-read timestamp in monotonic milliseconds. |
## ModbusMaster.ReqWriteCoil
Modbus FC 15: write BOOL coils. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 1968. Usable length is clamped to array capacity. Values are copied into native storage at submission. This FB uses the multiple-write FC even for one element. Use writeNow() to release a held uncertain write.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqWriteCoil EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF BOOL to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.ReqWriteHolding
Modbus FC 16: write UINT holding registers. Call every scan with a client reference and data array. Protocol start address is zero-based; in_dataOffset is the actual array index. Maximum transaction length is 123. Usable length is clamped to array capacity. Values are copied into native storage at submission. This FB uses the multiple-write FC even for one element. Use writeNow() to release a held uncertain write.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ReqWriteHolding EXTENDS RequestBase
VAR_IN_OUT
// ARRAY[] OF UINT to hold received data
{attribute 'symbol' := 'none'}
data: ARRAY[*] OF UINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `data` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Open array: BOOL for coils/discretes; UINT for registers. Stable VAR_IN_OUT storage. Writes snapshot values at submission; reads replace only their successful slice. |
## ModbusMaster.To_IPAddress
Returns the four supplied bytes as ARRAY[0..3] OF BYTE. Example: atMb.To_IPAddress(192,168,50,10). This is the ClientTCP address format; the slave bind address instead uses a packed DWORD.
```iecst
FUNCTION To_IPAddress : ARRAY[0..3] OF BYTE
VAR_INPUT
byte1: BYTE;
byte2: BYTE;
byte3: BYTE;
byte4: BYTE;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `byte1` | VAR_INPUT | `BYTE` | First IPv4 octet. |
| `byte2` | VAR_INPUT | `BYTE` | Second IPv4 octet. |
| `byte3` | VAR_INPUT | `BYTE` | Third IPv4 octet. |
| `byte4` | VAR_INPUT | `BYTE` | Fourth IPv4 octet. |
## ModbusSlave.ModbusSlave
Native Modbus TCP server. Same implementation and interface as SlaveTCP. Call once per scan with all four memory arrays. Array bounds are protocol addresses; each table is limited to 2000 elements and addresses 0..65535. Pushes application memory, performs bounded network processing, then copies native memory back. This is TCP only, not an RTU slave.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK ModbusSlave
VAR_IN_OUT
aDiscreteInputsMemory : ARRAY[*] OF BOOL;
aCoilsMemory : ARRAY[*] OF BOOL;
aInputRegistersMemory : ARRAY[*] OF UINT;
aHoldingRegistersMemory : ARRAY[*] OF UINT;
END_VAR
VAR_INPUT
in_enable : BOOL := TRUE;
in_reset : BOOL;
in_reconnectDelay : TIME := T#100MS;
interfaceName : WSTRING; // Legacy field; nonempty rejected. Use in_ipAddress.
in_ipAddress : DWORD; // Numeric bind IP, 0 = all interfaces.
port : UINT := 502;
END_VAR
VAR_OUTPUT
out_running : BOOL;
out_error : BOOL;
out_errorId : Error;
out_parameterError : BOOL;
out_socketError : UDINT;
out_connectedClients : UINT;
out_requestsReceived : UDINT;
out_repliesSent : UDINT;
out_exceptionReplies : UDINT;
END_VAR
VAR
serverHandle : UDINT;
serverStatus : ARRAY[0..23] OF UDINT;
serverIO : ARRAY[0..1999] OF WORD;
nowUs : SYSTIME;
nowMs : ULINT;
lastIP : DWORD;
lastPort : UINT;
lastRetry : TIME;
callResult : UDINT;
tableIndex : BYTE;
itemIndex : DINT;
tableStart : UINT;
tableCount : UINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `aDiscreteInputsMemory` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Read-only from network BOOL input table; FC2 reads. Application updates it. |
| `aCoilsMemory` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Read/write BOOL coil table. Array bounds are protocol addresses; FC1 reads, FC5/15 write. |
| `aInputRegistersMemory` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Read-only from network UINT input table; FC4 reads. Application updates it. |
| `aHoldingRegistersMemory` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Read/write UINT holding table; FC3 reads, FC6/16 write. |
| `in_enable` | VAR_INPUT | `BOOL := TRUE` | Enable processing; TRUE by default. FALSE releases transport. Continue scanning to refresh state. |
| `in_reset` | VAR_INPUT | `BOOL` | Slave one-shot recreation input. FB clears it internally; supplying TRUE every scan recreates every scan. |
| `in_reconnectDelay` | VAR_INPUT | `TIME := T#100MS` | Delay before native recovery attempt, default 100 ms; clamped to at least 1 ms. Effective timing also depends on scan interval and failure detection. |
| `interfaceName` | VAR_INPUT | `WSTRING` | Legacy slave field. Must be empty; nonempty is rejected. Use packed in_ipAddress instead. |
| `in_ipAddress` | VAR_INPUT | `DWORD` | ClientTCP: four IPv4 bytes. Slave: packed numeric DWORD, 0 binds all interfaces; e.g. DWORD#16#C0A8321F for 192.168.50.31. |
| `port` | VAR_INPUT | `UINT := 502` | Slave listening port, default 502, must be nonzero. |
| `out_running` | VAR_OUTPUT | `BOOL` | Native listener is bound and enabled. Does not mean a peer is connected. |
| `out_error` | VAR_OUTPUT | `BOOL` | Current server error flag when outputs are refreshed; some early returns leave other diagnostics unchanged. |
| `out_errorId` | VAR_OUTPUT | `Error` | IEC server error classification: parameter/internal/native socket class. Consult errno for OS detail. |
| `out_parameterError` | VAR_OUTPUT | `BOOL` | Array-offset validation for requests; full transaction validation can instead appear in out_nativeError/stats.lastErrorId. Slave: invalid port/interfaceName/table bounds or capacity. |
| `out_socketError` | VAR_OUTPUT | `UDINT` | Native Linux errno snapshot as UDINT; may be historical. Used for both serial and sockets. |
| `out_connectedClients` | VAR_OUTPUT | `UINT` | Number of native TCP peers connected (max 8 per server in supplied C source). |
| `out_requestsReceived` | VAR_OUTPUT | `UDINT` | Native request count for current server context. |
| `out_repliesSent` | VAR_OUTPUT | `UDINT` | Native fully transmitted reply count for current context, including exception replies. |
| `out_exceptionReplies` | VAR_OUTPUT | `UDINT` | Number of Modbus exception replies for current server context. |
## ModbusSlave.SlaveTCP
Native Modbus TCP server with four separate memory tables. Same implementation and interface as ModbusSlave. FC 1/2/3/4 read the tables; FC 5/6/15/16 write coils/holding registers. Array lower bounds define Modbus addresses. Call every scan and retain array storage. This is TCP only.
```iecst
{attribute 'no_assign'}
FUNCTION_BLOCK SlaveTCP
VAR_IN_OUT
aDiscreteInputsMemory : ARRAY[*] OF BOOL;
aCoilsMemory : ARRAY[*] OF BOOL;
aInputRegistersMemory : ARRAY[*] OF UINT;
aHoldingRegistersMemory : ARRAY[*] OF UINT;
END_VAR
VAR_INPUT
in_enable : BOOL := TRUE;
in_reset : BOOL;
in_reconnectDelay : TIME := T#100MS;
interfaceName : WSTRING; // Legacy field; nonempty rejected. Use in_ipAddress.
in_ipAddress : DWORD; // Numeric bind IP, 0 = all interfaces.
port : UINT := 502;
END_VAR
VAR_OUTPUT
out_running : BOOL;
out_error : BOOL;
out_errorId : Error;
out_parameterError : BOOL;
out_socketError : UDINT;
out_connectedClients : UINT;
out_requestsReceived : UDINT;
out_repliesSent : UDINT;
out_exceptionReplies : UDINT;
END_VAR
VAR
serverHandle : UDINT;
serverStatus : ARRAY[0..23] OF UDINT;
serverIO : ARRAY[0..1999] OF WORD;
nowUs : SYSTIME;
nowMs : ULINT;
lastIP : DWORD;
lastPort : UINT;
lastRetry : TIME;
callResult : UDINT;
tableIndex : BYTE;
itemIndex : DINT;
tableStart : UINT;
tableCount : UINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `aDiscreteInputsMemory` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Read-only from network BOOL input table; FC2 reads. Application updates it. |
| `aCoilsMemory` | VAR_IN_OUT | `ARRAY[*] OF BOOL` | Read/write BOOL coil table. Array bounds are protocol addresses; FC1 reads, FC5/15 write. |
| `aInputRegistersMemory` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Read-only from network UINT input table; FC4 reads. Application updates it. |
| `aHoldingRegistersMemory` | VAR_IN_OUT | `ARRAY[*] OF UINT` | Read/write UINT holding table; FC3 reads, FC6/16 write. |
| `in_enable` | VAR_INPUT | `BOOL := TRUE` | Enable processing; TRUE by default. FALSE releases transport. Continue scanning to refresh state. |
| `in_reset` | VAR_INPUT | `BOOL` | Slave one-shot recreation input. FB clears it internally; supplying TRUE every scan recreates every scan. |
| `in_reconnectDelay` | VAR_INPUT | `TIME := T#100MS` | Delay before native recovery attempt, default 100 ms; clamped to at least 1 ms. Effective timing also depends on scan interval and failure detection. |
| `interfaceName` | VAR_INPUT | `WSTRING` | Legacy slave field. Must be empty; nonempty is rejected. Use packed in_ipAddress instead. |
| `in_ipAddress` | VAR_INPUT | `DWORD` | ClientTCP: four IPv4 bytes. Slave: packed numeric DWORD, 0 binds all interfaces; e.g. DWORD#16#C0A8321F for 192.168.50.31. |
| `port` | VAR_INPUT | `UINT := 502` | Slave listening port, default 502, must be nonzero. |
| `out_running` | VAR_OUTPUT | `BOOL` | Native listener is bound and enabled. Does not mean a peer is connected. |
| `out_error` | VAR_OUTPUT | `BOOL` | Current server error flag when outputs are refreshed; some early returns leave other diagnostics unchanged. |
| `out_errorId` | VAR_OUTPUT | `Error` | IEC server error classification: parameter/internal/native socket class. Consult errno for OS detail. |
| `out_parameterError` | VAR_OUTPUT | `BOOL` | Array-offset validation for requests; full transaction validation can instead appear in out_nativeError/stats.lastErrorId. Slave: invalid port/interfaceName/table bounds or capacity. |
| `out_socketError` | VAR_OUTPUT | `UDINT` | Native Linux errno snapshot as UDINT; may be historical. Used for both serial and sockets. |
| `out_connectedClients` | VAR_OUTPUT | `UINT` | Number of native TCP peers connected (max 8 per server in supplied C source). |
| `out_requestsReceived` | VAR_OUTPUT | `UDINT` | Native request count for current server context. |
| `out_repliesSent` | VAR_OUTPUT | `UDINT` | Native fully transmitted reply count for current context, including exception replies. |
| `out_exceptionReplies` | VAR_OUTPUT | `UDINT` | Number of Modbus exception replies for current server context. |
## ClientBase.addRequest
Register a non-null RequestBase pointer once. Duplicate pointers are ignored. Capacity is 100 requests per client; overflow sets out_registrationFull. No removal API is provided. Normally called automatically by the request FB.
```iecst
//Adds the specified request to the global list
METHOD PUBLIC addRequest
VAR_INPUT
request: POINTER TO RequestBase;
END_VAR
VAR
requestIndex : DINT := 0;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `request` | VAR_INPUT | `POINTER TO RequestBase` | Internal wrapper state exposed for compatibility; normally leave under library control. |
## ClientBase.FB_exit
CODESYS lifecycle hook releasing owned native resources. Applications should use release/recreateClient rather than call lifecycle hooks manually. Server hooks close the server context; the client hook calls nativeRelease.
```iecst
METHOD FB_exit : BOOL
VAR_INPUT
bInCopyCode : BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `bInCopyCode` | VAR_INPUT | `BOOL` | Runtime lifecycle copy-code indicator; current implementation does not branch on it. |
## ClientBase.FB_reinit
CODESYS lifecycle hook clearing native handles and in-flight state. ClientBase also clears the request registry for re-registration; RequestBase clears execution/completion flags; servers clear their handle. These hooks alone do not establish qualified online-change support.
```iecst
METHOD FB_reinit : BOOL
VAR
requestIndex : DINT;
END_VAR
```
## ClientBase.nativeCall
Internal adapter to atMbCall_cext. Command 20 packs the ASCII serial path into WORD storage and passes serial settings in ABI fields; other commands use normal client arguments and status buffers. Return is the native command result, 0 for success.
```iecst
METHOD nativeCall : UDINT
VAR_INPUT
command : UDINT;
END_VAR
VAR
deviceBytes : POINTER TO BYTE;
deviceLength : UINT;
deviceIndex : DINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `command` | VAR_INPUT | `UDINT` | Native command selector. Use wrappers in application code. |
## ClientBase.nativeCycle
Internal per-scan engine: acquire context, tick nonblocking I/O, update diagnostics, copy completed read data, process registered requests, acknowledge completion, select the next request, and publish statistics. Invalid native handles are discarded and reopened on a later scan.
```iecst
METHOD nativeCycle
VAR
callResult : UDINT;
END_VAR
```
## ClientBase.nativeEnsureContext
Acquire/configure/enable a native context if absent. Returns TRUE when a handle exists or initialization succeeds. A handle does not mean connected; check out_connected. Failure records a native error and closes partially initialized contexts.
```iecst
METHOD PROTECTED nativeEnsureContext : BOOL
VAR
callResult : UDINT;
END_VAR
```
## ClientBase.nativeRelease
Close the native context, complete any active request as cancelled, clear selection, set registered requests offline and invalidate cached read data. Returns TRUE. It does not set in_enable FALSE; an enabled scanned client can reopen.
```iecst
METHOD nativeRelease : BOOL
VAR
requestIndex : DINT;
END_VAR
```
## ClientBase.nativeSelectNextRequest
Select an active, unheld request that meets in_minDelay and was not just completed this scan. Lowest in_priorityCurrent wins; oldest sinceLastExec breaks ties. Positive priorities are decremented when the best selected priority is positive. The selected request is submitted immediately; zero priority is not a prerequisite for execution.
```iecst
METHOD PROTECTED nativeSelectNextRequest
VAR
requestIndex : DINT;
selectedRequestIndex : DINT;
selectedPriority : INT;
oldestRequestAgeMilliseconds : UDINT;
END_VAR
```
## ClientBase.nativeUpdateDiagnostics
Publish native connection state, last error, errno and reconnect count. States 3..5 count as connected. A connected-to-disconnected transition marks registered requests offline.
```iecst
METHOD PROTECTED nativeUpdateDiagnostics
```
## ClientBase.nativeUpdateStatistics
Publish IEC send/reply counters, registered statistics pointers and active-request aggregate online flags. Every elapsed window of at least 1000 ms publishes submitted-request count and successful transaction-duration sum, then restarts the window.
```iecst
METHOD PROTECTED nativeUpdateStatistics
VAR
requestIndex : DINT;
END_VAR
```
## ClientBase.processAllRequests
Internal loop over registered non-null requests, dispatching processRequest. Returns immediately for an empty or invalid registry. Usually invoked by nativeCycle rather than application code.
```iecst
METHOD processAllRequests
VAR_INPUT
END_VAR
VAR
requestIndex: DINT; // Request registry index.
END_VAR
```
## ClientBase.recreateClient
Close/release the current context so the next enabled scan creates a fresh one with current settings. Cancels an active transaction and invalidates cached read data. Abstract on ClientBase; implemented by both concrete clients.
```iecst
METHOD ABSTRACT recreateClient
VAR_INPUT
END_VAR
```
## ClientBase.release
Stop this client by setting in_enable FALSE, then release its native context. Returns the release result. To resume, set in_enable TRUE and keep calling the client. A call that supplies in_enable := TRUE every scan will re-enable it.
```iecst
METHOD release : BOOL
```
## ClientBase.resetStats
Reset IEC send/reply/window counters and call each registered stats.resetStats. Does not clear native errno/reconnect counters or all per-request history. No transport recreation.
```iecst
METHOD resetStats
VAR
requestIndex : DINT;
END_VAR
```
## ClientBase.setAllRequestsOffline
Internal helper marking every registered request offline via its statistics FB. Returns TRUE after processing a nonempty valid registry; early return does not explicitly assign the return value.
```iecst
METHOD PROTECTED setAllRequestsOffline : BOOL
VAR_INPUT
END_VAR
VAR
requestIndex: DINT;
END_VAR
```
## ClientBase.setupClient
Returns whether nativeHandle is nonzero. It does not create a context or guarantee transport connectivity. Normal FB scanning performs initialization.
```iecst
METHOD setupClient : BOOL
VAR_INPUT
END_VAR
```
## ClientBase.activeIndex
Get the current active request registry index, or -1 when idle. Setting a valid index sets that request stats.execute TRUE; it does not bypass native scheduler selection or directly submit a transaction.
```iecst
PROPERTY activeIndex : DINT
```
## ClientBase.activeReqCnt
Private count of registered requests whose stats.active is TRUE. Zero quantity/usable length requests are inactive.
```iecst
PROPERTY PRIVATE activeReqCnt : UINT
```
## ClientBase.allRequestsComplete
Private legacy completion check. TRUE only if none of the registered requests has execute, reqDone, reqBusy or reqError set. Empty registry returns FALSE. This is not a network completion pulse.
```iecst
{attribute 'symbol' := 'none'}
PROPERTY PRIVATE allRequestsComplete : BOOL
```
## ClientBase.onlineCnt
Count registered requests with stats.online TRUE. Includes any registered request with that flag; used for aggregate reporting.
```iecst
{attribute 'symbol' := 'none'}
PROPERTY onlineCnt : DINT//Count of requests that are online
```
## ClientBase.requestExecuting
Private property returning activeIndex <> -1. Represents selected/active request state maintained by the scheduler.
```iecst
{attribute 'symbol' := 'none'}
PROPERTY PRIVATE requestExecuting : BOOL //There is at least one request executing
```
## ClientRTU.recreateClient
Close/release the current context so the next enabled scan creates a fresh one with current settings. Cancels an active transaction and invalidates cached read data. Abstract on ClientBase; implemented by both concrete clients.
```iecst
METHOD recreateClient
```
## ClientRTU.toString
ClientRTU monitoring property returning ClientStatus based on onlineCnt versus requestCnt. Reports allOk for an empty registry. RequestStats also has an internal STRING field of this name; these are different values.
```iecst
{attribute 'symbol' := 'none'}
PROPERTY toString : ClientStatus //Client request status noneOk = no requests working, someOk = some requests are working some are failing, allOk = all requests are working
```
## ClientTCP.recreateClient
Close/release the current context so the next enabled scan creates a fresh one with current settings. Cancels an active transaction and invalidates cached read data. Abstract on ClientBase; implemented by both concrete clients.
```iecst
METHOD recreateClient
```
## ReqReadCoil.processRequest
Derived request dispatch: performs ReqReadCoil transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqReadCoil.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## ReqReadDiscrete.processRequest
Derived request dispatch: performs ReqReadDiscrete transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqReadDiscrete.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## ReqReadHolding.processRequest
Derived request dispatch: performs ReqReadHolding transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqReadHolding.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## ReqReadInput.processRequest
Derived request dispatch: performs ReqReadInput transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqReadInput.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## RequestBase.busy
Assign stats.reqBusy from input in. Internal request helper. Although declared BOOL, its implementation does not assign a return value; use the side effect rather than the return.
```iecst
METHOD busy : BOOL
VAR_INPUT
in: BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in` | VAR_INPUT | `BOOL` | New state to assign. Normally used internally by completion helpers. |
## RequestBase.done
Set stats.reqDone. When in is TRUE, restore in_priorityCurrent to in_prioritySetpoint for the next scheduler cycle. Successful completion counters are maintained by the stats property setter.
```iecst
METHOD done
VAR_INPUT
// Done state
in: BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in` | VAR_INPUT | `BOOL` | New state to assign. Normally used internally by completion helpers. |
## RequestBase.err
Set stats.reqError and, on TRUE, record errorId/exceptionCode. Set next priority to 10 * MIN(consecutive errors,3)^2. Lower numeric priority wins, so this backs off repeated failures relative to lower-priority-number requests.
```iecst
METHOD err
VAR_INPUT
// Error state
in: BOOL;
errorId: Error;
exceptionCode: ExceptionCodes;
END_VAR
VAR
priorityMultiplier: INT; //Raise priority when not response
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `in` | VAR_INPUT | `BOOL` | New state to assign. Normally used internally by completion helpers. |
| `errorId` | VAR_INPUT | `Error` | Mapped IEC error supplied to the error helper. |
| `exceptionCode` | VAR_INPUT | `ExceptionCodes` | Modbus exception classification supplied to the error helper. |
## RequestBase.FB_reinit
CODESYS lifecycle hook clearing native handles and in-flight state. ClientBase also clears the request registry for re-registration; RequestBase clears execution/completion flags; servers clear their handle. These hooks alone do not establish qualified online-change support.
```iecst
METHOD FB_reinit : BOOL
```
## RequestBase.invalidateNativeData
Mark cached data invalid and stale. Does not erase the application array. Called during client release; applications should gate use of cached values with validity and age flags.
```iecst
METHOD PUBLIC invalidateNativeData
```
## RequestBase.nativeFinish
Complete a request from native result. Map errors, copy errno/write uncertainty, clear busy, update response/counters and successful-read freshness. Modbus exceptions count as replies and communication-online evidence. If enabled, uncertain writes are held pending writeNow().
```iecst
METHOD nativeFinish
VAR_INPUT
result : UDINT;
END_VAR
VAR
mapped : Error;
ex : ExceptionCodes;
duration : UDINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `result` | VAR_INPUT | `UDINT` | Native completion result; 0 success. |
## RequestBase.nativeProcess
Shared request processing called by derived processRequest. Completes native results or submits a selected request, sets its timeout and records busy/send counters. Updates data age and stale flags during ordinary processing. Completion branches can return before age refresh, so allow a subsequent scan for freshness diagnostics.
```iecst
METHOD nativeProcess
VAR_INPUT
functionCode : BYTE;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `functionCode` | VAR_INPUT | `BYTE` | Modbus FC; command 20 uses data bits, server push/pull use table ID. |
## RequestBase.processRequest
Abstract internal request dispatch implemented by each concrete read/write block.
```iecst
METHOD ABSTRACT processRequest
VAR_INPUT
END_VAR
```
## RequestBase.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD ABSTRACT recreateRequest : BOOL
```
## RequestBase.replyTimeout
Protected timeout property expressed internally in microseconds. Request in_timeout is milliseconds and takes precedence, then client TIME in_timeout, then a dataRate formula, then 1 second fallback. Submission rounds up to milliseconds and clamps to at least 1 ms.
```iecst
//Calculates the reply timout setting
PROPERTY PROTECTED replyTimeout : UDINT
```
## RequestStats.resetStats
Reset only doneCnt, doneCntRst, errorCnt and errorCntRst. Retains durations, offlineCnt, timeoutCnt and timestamps.
```iecst
METHOD resetStats
VAR_INPUT
END_VAR
```
## RequestStats.setClientOffline
Clear nativeResponseSeen and consecutive-success count, force online FALSE/offline TRUE. Does not clear data arrays. Declared BOOL but does not assign a return value.
```iecst
METHOD setClientOffline : BOOL
VAR_INPUT
END_VAR
```
## RequestStats.setToString
Private statistics helper formatting OK:<doneCnt>/Er:<errorCnt> into STRING(20). Declared BOOL but does not assign a return value.
```iecst
METHOD PRIVATE setToString : BOOL
VAR_INPUT
END_VAR
```
## RequestStats.execute
Statistics execution property. Setting TRUE starts the execution state only when reqDone and reqError are FALSE; otherwise the setter clears execution. Usually controlled by the scheduler.
```iecst
PROPERTY execute : BOOL
```
## RequestStats.reqBusy
Get/set the underlying request-busy flag. Normally managed by the native wrapper. The scan-held reqBusyLight provides a more visible monitoring indicator.
```iecst
PROPERTY reqBusy : BOOL
```
## RequestStats.reqDone
Get/set completion flag. When TRUE during execution, record duration, increment total/consecutive successes, clear consecutive errors and last error, clear execution and update the monitor string. Do not repeatedly drive this manually.
```iecst
PROPERTY reqDone : BOOL
```
## RequestStats.reqError
Get/set error flag. When TRUE during execution, increment total/consecutive errors, clear consecutive successes and execution. If lastExceptionCode is success, increment timeoutCnt and set TIMEOUT even for some non-timeout native errors.
```iecst
PROPERTY reqError : BOOL
```
## ReqWriteCoil.processRequest
Derived request dispatch: performs ReqWriteCoil transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqWriteCoil.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## ReqWriteCoil.writeNow
Clear uncertain-write hold and out_writeUncertain, then set in_priorityCurrent to 0. Returns TRUE. Requests a prompt opportunity at the next scheduler selection; does not guarantee transmission in this call and does not bypass connection/minimum-delay requirements.
```iecst
METHOD writeNow : BOOL
VAR_INPUT
END_VAR
```
## ReqWriteHolding.processRequest
Derived request dispatch: performs ReqWriteHolding transaction using shared nativeProcess, validates copy bounds and transfers the configured slice. Called by client scheduler; application calls the request FB body to register/bind its data.
```iecst
METHOD processRequest
```
## ReqWriteHolding.recreateRequest
Clear this request nativeInFlight. If it is the client active request, recreate the whole client connection first. Returns TRUE. May affect other requests sharing the same connection; this is not an independent transport.
```iecst
METHOD recreateRequest : BOOL
```
## ReqWriteHolding.writeNow
Clear uncertain-write hold and out_writeUncertain, then set in_priorityCurrent to 0. Returns TRUE. Requests a prompt opportunity at the next scheduler selection; does not guarantee transmission in this call and does not bypass connection/minimum-delay requirements.
```iecst
METHOD writeNow : BOOL
VAR_INPUT
END_VAR
```
## ModbusSlave.FB_exit
CODESYS lifecycle hook releasing owned native resources. Applications should use release/recreateClient rather than call lifecycle hooks manually. Server hooks close the server context; the client hook calls nativeRelease.
```iecst
METHOD FB_exit : BOOL
VAR_INPUT
bInCopyCode : BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `bInCopyCode` | VAR_INPUT | `BOOL` | Runtime lifecycle copy-code indicator; current implementation does not branch on it. |
## ModbusSlave.FB_reinit
CODESYS lifecycle hook clearing native handles and in-flight state. ClientBase also clears the request registry for re-registration; RequestBase clears execution/completion flags; servers clear their handle. These hooks alone do not establish qualified online-change support.
```iecst
METHOD FB_reinit : BOOL
```
## ModbusSlave.serverCall
Private adapter for native server commands. Uses separate server status and WORD staging buffers. Returns the command result; 0 means command accepted, not necessarily that the listener has bound.
```iecst
METHOD PRIVATE serverCall : UDINT
VAR_INPUT
command : UDINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `command` | VAR_INPUT | `UDINT` | Native command selector. Use wrappers in application code. |
## SlaveTCP.FB_exit
CODESYS lifecycle hook releasing owned native resources. Applications should use release/recreateClient rather than call lifecycle hooks manually. Server hooks close the server context; the client hook calls nativeRelease.
```iecst
METHOD FB_exit : BOOL
VAR_INPUT
bInCopyCode : BOOL;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `bInCopyCode` | VAR_INPUT | `BOOL` | Runtime lifecycle copy-code indicator; current implementation does not branch on it. |
## SlaveTCP.FB_reinit
CODESYS lifecycle hook clearing native handles and in-flight state. ClientBase also clears the request registry for re-registration; RequestBase clears execution/completion flags; servers clear their handle. These hooks alone do not establish qualified online-change support.
```iecst
METHOD FB_reinit : BOOL
```
## SlaveTCP.serverCall
Private adapter for native server commands. Uses separate server status and WORD staging buffers. Returns the command result; 0 means command accepted, not necessarily that the listener has bound.
```iecst
METHOD PRIVATE serverCall : UDINT
VAR_INPUT
command : UDINT;
END_VAR
```
| Member | Direction | Declaration | Meaning |
|---|---|---|---|
| `command` | VAR_INPUT | `UDINT` | Native command selector. Use wrappers in application code. |
## activeIndex.Get
Get accessor for activeIndex; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
VAR
requestIndex: DINT; //Loop variable
END_VAR
```
## activeIndex.Set
Set accessor for activeIndex; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## activeReqCnt.Get
Get accessor for activeReqCnt; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
VAR
requestIndex : DINT; //Loop variable
cnt: UINT;
END_VAR
```
## allRequestsComplete.Get
Get accessor for allRequestsComplete; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
VAR
requestIndex : DINT;
END_VAR
```
## onlineCnt.Get
Get accessor for onlineCnt; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
VAR
requestIndex : DINT; //Loop variable
cnt: UINT;
END_VAR
```
## requestExecuting.Get
Get accessor for requestExecuting; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## toString.Get
Get accessor for toString; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## replyTimeout.Get
Get accessor for replyTimeout; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## execute.Get
Get accessor for execute; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## execute.Set
Set accessor for execute; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqBusy.Get
Get accessor for reqBusy; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqBusy.Set
Set accessor for reqBusy; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqDone.Get
Get accessor for reqDone; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqDone.Set
Set accessor for reqDone; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqError.Get
Get accessor for reqError; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```
## reqError.Set
Set accessor for reqError; see the owning property reference for side effects. Runtime/property syntax normally invokes this accessor.
```iecst
```