Seems to be working great
This commit is contained in:
+13
-42
@@ -1,6 +1,6 @@
|
||||
# atMb 0.4 API reference
|
||||
# atMb 0.8 API reference
|
||||
|
||||
Generated from `library/atMb-Threaded.export`. Declarations below are the current source. Use USER-GUIDE.md for lifecycle, units and examples. Internal fields remain exposed where required by existing IEC inheritance; do not overwrite engine state from application code.
|
||||
Generated from `library/atMb-OnlineChange.export`. Declarations below are the current source. Use USER-GUIDE.md for lifecycle, units and examples. Internal fields remain exposed where required by existing IEC inheritance; do not overwrite engine state from application code.
|
||||
|
||||
## atMbCall_cext
|
||||
|
||||
@@ -106,7 +106,7 @@ END_TYPE
|
||||
|
||||
## ModbusMaster.ClientBase
|
||||
|
||||
Shared abstract client scheduler and registry. Call concrete client every scan; worker handles transaction progress. Exposes aggregated stats and toString.
|
||||
Shared abstract client scheduler and registry. Call concrete client every scan; IEC task handles transaction progress. Exposes aggregated stats and toString.
|
||||
|
||||
```iecst
|
||||
{attribute 'monitoring_display' := 'toString'}
|
||||
@@ -564,7 +564,7 @@ VAR_INPUT
|
||||
sentCnt : UDINT;
|
||||
replyCnt : UDINT;
|
||||
exceptionCnt : UDINT;
|
||||
totalValidDuration : ULINT; // Sum of successful worker transaction durations, milliseconds.
|
||||
totalValidDuration : ULINT; // Sum of successful transport transaction durations, milliseconds.
|
||||
END_VAR
|
||||
VAR
|
||||
previousOnline : BOOL;
|
||||
@@ -774,7 +774,7 @@ END_VAR
|
||||
|
||||
## ClientBase.FB_exit
|
||||
|
||||
Lifecycle resource release. Worker is joined by component exit; context hooks close their owned handle. Use public release for application shutdown.
|
||||
Lifecycle resource release. context hooks close their owned handle. Use public release for application shutdown.
|
||||
|
||||
```iecst
|
||||
METHOD FB_exit : BOOL
|
||||
@@ -815,7 +815,7 @@ END_VAR
|
||||
|
||||
## ClientBase.processCycle
|
||||
|
||||
Refresh scan lease, read completed results, process request completions, acknowledge result and select next transaction. OS I/O progression is performed by the worker.
|
||||
Refresh scan lease, read completed results, process request completions, acknowledge result and select next transaction. Transport I/O progresses during the owning PLC call.
|
||||
|
||||
```iecst
|
||||
METHOD processCycle
|
||||
@@ -826,7 +826,7 @@ END_VAR
|
||||
|
||||
## ClientBase.ensureContext
|
||||
|
||||
Check 0.4 worker capability, allocate/configure/enable a context. A nonzero handle does not imply connectivity. Old components are rejected with error 259.
|
||||
Allocate/configure/enable a context. A nonzero handle does not imply connectivity. Old components are rejected with error 259.
|
||||
|
||||
```iecst
|
||||
METHOD PROTECTED ensureContext : BOOL
|
||||
@@ -1138,7 +1138,7 @@ METHOD PUBLIC invalidateData
|
||||
|
||||
## RequestBase.finishRequest
|
||||
|
||||
Map a completed result and write uncertainty, collect worker timing/read age, update reply/exception/timeout counters and completion flags. Successful reads become valid; errors retain old array values.
|
||||
Map a completed result and write uncertainty, collect transport timing/read age, update reply/exception/timeout counters and completion flags. Successful reads become valid; errors retain old array values.
|
||||
|
||||
```iecst
|
||||
METHOD finishRequest
|
||||
@@ -1239,7 +1239,7 @@ PROPERTY reqBusy : BOOL
|
||||
|
||||
## RequestStats.reqDone
|
||||
|
||||
On successful executing completion, increment saturated success counters, clear errors and execution, update display. Worker supplies duration.
|
||||
On successful executing completion, increment saturated success counters, clear errors and execution, update display. Transport supplies duration.
|
||||
|
||||
```iecst
|
||||
PROPERTY reqDone : BOOL
|
||||
@@ -1307,7 +1307,7 @@ END_VAR
|
||||
|
||||
## ModbusSlave.FB_exit
|
||||
|
||||
Lifecycle resource release. Worker is joined by component exit; context hooks close their owned handle. Use public release for application shutdown.
|
||||
Lifecycle resource release. context hooks close their owned handle. Use public release for application shutdown.
|
||||
|
||||
```iecst
|
||||
METHOD FB_exit : BOOL
|
||||
@@ -1327,7 +1327,7 @@ METHOD FB_reinit : BOOL
|
||||
|
||||
## ModbusSlave.serverCall
|
||||
|
||||
Private synchronous server/worker ABI adapter using server staging/status arrays.
|
||||
Private synchronous server ABI adapter using server staging/status arrays.
|
||||
|
||||
```iecst
|
||||
METHOD PRIVATE serverCall : UDINT
|
||||
@@ -1339,7 +1339,7 @@ END_VAR
|
||||
|
||||
## SlaveTCP.FB_exit
|
||||
|
||||
Lifecycle resource release. Worker is joined by component exit; context hooks close their owned handle. Use public release for application shutdown.
|
||||
Lifecycle resource release. context hooks close their owned handle. Use public release for application shutdown.
|
||||
|
||||
```iecst
|
||||
METHOD FB_exit : BOOL
|
||||
@@ -1359,7 +1359,7 @@ METHOD FB_reinit : BOOL
|
||||
|
||||
## SlaveTCP.serverCall
|
||||
|
||||
Private synchronous server/worker ABI adapter using server staging/status arrays.
|
||||
Private synchronous server ABI adapter using server staging/status arrays.
|
||||
|
||||
```iecst
|
||||
METHOD PRIVATE serverCall : UDINT
|
||||
@@ -1539,32 +1539,3 @@ STRUCT
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
```
|
||||
|
||||
## ModbusMaster.Worker
|
||||
|
||||
Optional single global worker controller. CPU -1 restores inherited mask; nonnegative selects an OS CPU. Affinity error is explicit. Configure watchdog longer than expected scan gaps.
|
||||
|
||||
```iecst
|
||||
FUNCTION_BLOCK Worker
|
||||
VAR_INPUT
|
||||
in_cpu : DINT := -1; // -1 restores inherited affinity; >=0 selects an OS CPU ID.
|
||||
in_interval : TIME := T#1MS; // Worker sleep 1..20 ms; not a hard real-time guarantee.
|
||||
in_watchdog : TIME := T#2S; // 100 ms..60 s; closes contexts whose FB stops scanning.
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
out_running : BOOL;
|
||||
out_error : BOOL;
|
||||
out_errorCode : UDINT;
|
||||
out_osError : UDINT;
|
||||
out_cpu : DINT := -1;
|
||||
out_cycles : ULINT;
|
||||
END_VAR
|
||||
VAR
|
||||
status : ARRAY[0..23] OF UDINT;
|
||||
configured : BOOL;
|
||||
lastCpu : DINT;
|
||||
lastInterval : TIME;
|
||||
lastWatchdog : TIME;
|
||||
command : UDINT;
|
||||
END_VAR
|
||||
```
|
||||
|
||||
+18
-46
@@ -1,61 +1,33 @@
|
||||
# Build and upgrade to atMb 0.6
|
||||
# Build and upgrade to atMb 0.8
|
||||
|
||||
## Build on ARM64 Linux
|
||||
|
||||
From the repository root:
|
||||
Build from the repository root and clean between architectures:
|
||||
|
||||
```sh
|
||||
sudo apt install build-essential m4 dos2unix python3
|
||||
make -C component-source/component SDKDIR="$(realpath ExtensionSDK)" clean
|
||||
make -C component-source/component SDKDIR="$(realpath ExtensionSDK)" all
|
||||
mkdir -p artifacts/arm64
|
||||
cp component-source/component/out/libCmpAtomModbus.so artifacts/arm64/
|
||||
```
|
||||
|
||||
Run these commands on an ARM64 build machine. On an x86 laptop, ordinary gcc
|
||||
builds x86 output; use the appropriate cross-compiler instead.
|
||||
|
||||
## Cross-compile ARMv7 hard-float on the laptop
|
||||
For the UR2000 ARMv7 hard-float target:
|
||||
|
||||
```sh
|
||||
sudo apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf make m4 dos2unix
|
||||
make -C component-source/component SDKDIR="$(realpath ExtensionSDK)" clean
|
||||
make -C component-source/component SDKDIR="$(realpath ExtensionSDK)" CC="arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard" all
|
||||
mkdir -p artifacts/armv7hf
|
||||
cp component-source/component/out/libCmpAtomModbus.so artifacts/armv7hf/
|
||||
arm-linux-gnueabihf-readelf --version-info artifacts/armv7hf/libCmpAtomModbus.so
|
||||
make -C component-source/component \
|
||||
SDKDIR="$(realpath ExtensionSDK)" \
|
||||
CC="arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard" all
|
||||
```
|
||||
|
||||
The makefile supplies `-pthread` during compilation/linking. Always clean between
|
||||
architectures. Check `file`, ELF attributes, NEEDED libraries and GLIBC symbol
|
||||
requirements against the target. Adding pthread can change the required glibc
|
||||
version; the previously checked binaries do not establish compatibility of this build.
|
||||
The WL2000 runtime was ARMv7/VFPv3-D16 hard-float. The UC20 OS was ARM64/glibc 2.39;
|
||||
its runtime architecture/component support still needs target verification.
|
||||
Use the matching ARM64 compiler for Raspberry Pi/UC20 and check ELF architecture
|
||||
and GLIBC requirements before deployment. The C component is version **0.5.0.0**.
|
||||
|
||||
## CODESYS
|
||||
## CODESYS and online change
|
||||
|
||||
1. Keep the prior working `.library` and PLC application for rollback.
|
||||
2. Create a fresh library project named `CmpAtomModbus.library` and import
|
||||
`library/atMb-Threaded.export`. Importing into an old project does not delete
|
||||
renamed/removed objects; a fresh project avoids duplicate old methods.
|
||||
3. Preserve Project Information title `CmpAtomModbus`, namespace `atMb`, and
|
||||
Standard/SysTime references. Verify library version 0.6.0.0 in Project Information.
|
||||
4. Add a C Implemented Library object and attach the **new 0.4.0.0** component for
|
||||
each exact target device. Do not attach files from `backup/`.
|
||||
5. Compile, install the library and update application references. Rename application
|
||||
diagnostic accesses using `RENAMED-MEMBERS.json`. `ClientTCP`/`ClientRTU` and
|
||||
request function-block names remain the same.
|
||||
6. Use a full download and verify the runtime loads component 0.4.0.0. If manually
|
||||
preloading an old component, remove/replace that preload during maintenance so
|
||||
it does not conflict with the embedded component.
|
||||
7. Start on a bench with the default worker settings; verify unplug/replug, device
|
||||
reboot, disabled client and PLC stop/start behavior before deployment.
|
||||
1. Create a fresh library project and import `library/atMb-OnlineChange.export`.
|
||||
2. Verify Project Information version **0.8.0.0**, namespace `atMb`, and the
|
||||
existing Standard/SysTime references.
|
||||
3. Add a C Implemented Library object with the rebuilt **0.5.0.0** component.
|
||||
4. Compile the library and update the application reference.
|
||||
5. Test online change while idle, during an active read, during disconnect, and
|
||||
with an active write. Confirm clients reopen and data becomes valid.
|
||||
|
||||
The C ABI layout/signature is unchanged (0x709EE65B, API 0.2.0.0). Component version
|
||||
is 0.4.0.0. Command 41 capability checking prevents this IEC export operating with
|
||||
an old component; it does not eliminate target/compiler compatibility checks.
|
||||
|
||||
Host validation: `make -C component-source test`. Host frame/function compilation
|
||||
used the supplied SDK and generated headers; a fresh SDK/M4 build and the IDE
|
||||
compile were not available in the execution environment.
|
||||
The external ABI signature/API version is unchanged. There is no worker FB,
|
||||
thread-affinity setting, or native worker thread in this release.
|
||||
|
||||
+6
-9
@@ -1,11 +1,8 @@
|
||||
# Migration housekeeping
|
||||
# Release housekeeping
|
||||
|
||||
The prior working library, export and ARM binaries are retained under `backup/`.
|
||||
They are not the threaded release. New source is imported from `atMb-Threaded.export`
|
||||
and rebuilt in the IDE with a newly built 0.4 C component. Previous IDE caches,
|
||||
editor lock/options files and C build outputs were omitted from this package.
|
||||
Git metadata is retained; no commit or push was made.
|
||||
The active release is `atMb-OnlineChange.export`, library version 0.8.0.0, with
|
||||
C component version 0.5.0.0. The old threaded export and ARM binaries are kept
|
||||
under `backup/` for rollback/reference and are not part of the active release.
|
||||
|
||||
`RENAMED-MEMBERS.json` is the exact old-to-new mapping for application changes.
|
||||
The previous transport prefix is removed from active IEC code and comments.
|
||||
Public request output is now out_errorCode; client output is out_lastErrorCode.
|
||||
No Git commit or push was made. Build outputs and IDE cache files are omitted
|
||||
from the release archive.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Export import correction
|
||||
|
||||
The Worker object in the first threaded export contained an unnamed List element.
|
||||
The generator cleared its attributes as well as its children. This revision
|
||||
restores Name="ChildObjectGuids", preserves an empty child list, and matches the
|
||||
original export envelope (no XML declaration, CRLF line endings).
|
||||
|
||||
All collection elements now retain serialization attributes. XML parsing passes.
|
||||
CODESYS import has not been verified in an IDE. If import still fails, capture the
|
||||
exact error text and whether it occurs before or after the object selection dialog.
|
||||
The C sources and IEC program logic are unchanged by this correction.
|
||||
+27
-182
@@ -1,190 +1,35 @@
|
||||
# atMb 0.4 user guide
|
||||
# atMb 0.8 user guide
|
||||
|
||||
## Thread and PLC calls
|
||||
## Execution model
|
||||
|
||||
One C worker progresses all TCP/RTU client transactions and TCP slave connections.
|
||||
It owns no pointers into IEC memory: request values, replies and slave tables live
|
||||
in fixed C storage. The external call copies buffers synchronously and serializes
|
||||
state access using a priority-inheritance engine mutex. No network wait or sleep
|
||||
is performed while that mutex is held. Serial driver calls can still take time;
|
||||
this is not a hard real-time or lock-free PLC interface.
|
||||
TCP, RTU and slave transport progress synchronously when the owning client or
|
||||
slave FB is called. Keep the related client, request FBs and data arrays in one
|
||||
PLC task and call them every scan. This version intentionally has no native
|
||||
worker thread, CPU-affinity input, or scan watchdog.
|
||||
|
||||
Continue calling each client/request and slave every PLC scan. Client request
|
||||
selection is still performed by the IEC scheduler. A transaction can finish while
|
||||
the PLC is not scanning, and its result waits for the next scan; the worker does
|
||||
not independently cycle through the PLC request registry. TCP slaves respond from
|
||||
the last copied memory snapshot between scans.
|
||||
The C state machines use nonblocking sockets and fixed storage. Serial driver
|
||||
calls remain target-dependent, and a long PLC task interval can delay transport
|
||||
progress; choose request timeouts accordingly.
|
||||
|
||||
## Optional worker configuration and a separate core
|
||||
## Online change
|
||||
|
||||
```iecst
|
||||
VAR
|
||||
commWorker : atMb.Worker;
|
||||
END_VAR
|
||||
`FB_reinit` closes the native context before CODESYS replaces IEC instance memory,
|
||||
then clears handles, active request pointers and registration arrays. Request FBs
|
||||
clear in-flight state. TCP/RTU clients and slave listeners reopen on a later PLC
|
||||
scan. Expect active requests to be cancelled and reads to remain stale until a
|
||||
validated reply arrives. Writes already transmitted are not replayed.
|
||||
|
||||
// Example only: CPU 2 must be online and permitted on this PLC.
|
||||
commWorker(in_cpu := 2, in_interval := T#1MS, in_watchdog := T#2S);
|
||||
```
|
||||
## Status and recovery
|
||||
|
||||
Use only one Worker configuration instance for the component. Clients/servers
|
||||
start the worker automatically with defaults even without this FB. Default CPU -1
|
||||
uses the thread creator's inherited affinity mask; it is not a promise of all CPUs.
|
||||
A nonnegative value pins the worker to that Linux logical CPU ID. CPU affinity does
|
||||
not reserve an exclusive core or move the PLC task: choose a CPU outside the PLC
|
||||
task's configured affinity where the runtime allows it. Changes affect this worker
|
||||
only. Failure is visible in `out_errorCode` and `out_osError`; no silent fallback.
|
||||
Client statistics aggregate all registered requests. `toString` uses
|
||||
`OK:<successful requests>/Er:<failed requests>`. Three consecutive failed request
|
||||
results are required before a request is exposed as offline; a short TCP-to-RTU
|
||||
converter reconnect therefore does not immediately mark every request offline.
|
||||
A valid response restores online immediately. Reconnect remains automatic
|
||||
through the synchronous state machine.
|
||||
|
||||
The worker uses normal OS scheduling and explicitly avoids inheriting a PLC task's
|
||||
real-time priority. Sleep interval is 1..20 ms, default 1 ms; scheduling jitter can
|
||||
make actual intervals longer. Very short reply deadlines must account for worker
|
||||
interval and transaction framing. `out_cycles` helps monitor worker progress.
|
||||
|
||||
## Scan-loss watchdog
|
||||
|
||||
Each client/server refresh call renews its own lease; another client's scans do
|
||||
not keep a stopped client alive. Default expiry is 2 s, configurable 100 ms..60 s.
|
||||
If scanning stops, the worker closes that context's connection/listener. In-flight
|
||||
requests finish as cancelled; potentially transmitted writes retain uncertainty.
|
||||
Handles/storage remain allocated for recovery. The next client/server refresh
|
||||
resumes connection attempts using the same context. Explicit release frees it.
|
||||
|
||||
Choose a watchdog longer than the worst expected PLC scan gap. This bounds how
|
||||
long a stopped PLC's server can respond with its last memory snapshot; it is not
|
||||
an immediate CODESYS application-stop hook. Component exit stops and joins the
|
||||
worker before freeing connections. Repeated thread shutdown/start is tested.
|
||||
|
||||
## TCP read
|
||||
|
||||
```iecst
|
||||
VAR
|
||||
mb : atMb.ClientTCP;
|
||||
readHolding : atMb.ReqReadHolding;
|
||||
values : ARRAY[0..9] OF UINT;
|
||||
END_VAR
|
||||
|
||||
mb(in_ipAddress := atMb.To_IPAddress(192,168,50,10), in_port := 502,
|
||||
in_enable := TRUE, in_timeout := T#500MS, in_reconnectDelay := T#100MS);
|
||||
readHolding(client := mb, in_unitId := 1, in_startAddr := 0,
|
||||
in_quantity := 10, in_dataOffset := 0, data := values);
|
||||
```
|
||||
|
||||
Keep one IEC task as owner of the related FB instances and arrays. Call the client
|
||||
before request registration on startup; polling starts after registration. The C
|
||||
entry point is serialized but that does not make concurrent IEC FB access safe.
|
||||
TCP addresses are four BYTEs; slave bind addresses are packed DWORDs.
|
||||
|
||||
RTU uses `ClientRTU(in_device := '/dev/ttyUSB0', in_baudRate := 9600,
|
||||
in_parity := 0, in_dataBits := 8, in_stopBits := 1, in_rs485 := FALSE)` and the same
|
||||
request FBs. RTU IDs must be 1..247. The runtime account needs serial permissions.
|
||||
Kernel RS485 direction control requires a supported driver. USB automatic-direction
|
||||
adapters generally use FALSE. Supported baud rates: 1200,2400,4800,9600,19200,38400,
|
||||
57600,115200. Physical timing/driver validation remains necessary.
|
||||
|
||||
## Requests, data and priorities
|
||||
|
||||
| Block | Function | Array | Maximum quantity |
|
||||
|---|---|---|---|
|
||||
| ReqReadCoil | 1 | BOOL | 2000 |
|
||||
| ReqReadDiscrete | 2 | BOOL | 2000 |
|
||||
| ReqReadHolding | 3 | UINT | 125 |
|
||||
| ReqReadInput | 4 | UINT | 125 |
|
||||
| ReqWriteCoil | 15 | BOOL | 1968 |
|
||||
| ReqWriteHolding | 16 | UINT | 123 |
|
||||
|
||||
Protocol addresses are zero-based; `in_dataOffset` is the actual array index, not
|
||||
a relative offset. Effective length is MIN(quantity, remaining array capacity).
|
||||
Zero length disables a request and now retains its statistics history. Arrays and
|
||||
FB instances must stay valid. There are 16 shared TCP/RTU client slots, 100 IEC
|
||||
requests per client, one in-flight transaction per client and four TCP server slots.
|
||||
|
||||
Lower `in_priorityCurrent` wins; oldest start age breaks ties. A request need not
|
||||
reach zero to run. Success restores `in_prioritySetpoint`; errors use 10/40/90
|
||||
priority backoff. `in_minDelay` is start-to-start eligibility, not a fixed period.
|
||||
|
||||
Successful reads update the destination slice. Errors retain previous data; use
|
||||
`out_validData AND NOT out_stale`. Data age includes time the completed reply waited
|
||||
for a PLC scan. Client release invalidates cached data but does not erase arrays.
|
||||
An exception reply indicates communication, but does not produce valid read data.
|
||||
|
||||
Writes snapshot their source slice at submission. The worker never automatically
|
||||
replays a request. The IEC scheduler still polls write FBs cyclically. Set client
|
||||
`in_holdUncertainWrites := TRUE` to pause an uncertain write after a failure;
|
||||
`writeNow()` clears the hold and sets priority zero once the application decides
|
||||
retrying is appropriate. It does not bypass min-delay/connection conditions.
|
||||
|
||||
## Timeouts and reconnects
|
||||
|
||||
Request `in_timeout` is numeric milliseconds (SYSTIME); client `in_timeout` is TIME.
|
||||
Nonzero request timeout wins, then client timeout, then the existing baud/data-rate
|
||||
formula. TCP's calculated default is about 38 ms, so an explicit timeout is clearer.
|
||||
The C worker uses CLOCK_MONOTONIC for deadlines, independent of PLC-provided time.
|
||||
|
||||
`in_reconnectDelay` defaults to 100 ms. Recovery proceeds without PLC ticks while
|
||||
the scan lease is valid. Actual downtime includes failure detection, retry delay,
|
||||
worker scheduling and remote-device readiness. Idle TCP disconnects are detected;
|
||||
there is no zero-downtime guarantee. TCP_NODELAY reduces small-message coalescing.
|
||||
|
||||
`recreateClient()` closes/recreates a context and cancels any active request.
|
||||
`release()` also sets `in_enable := FALSE`; a subsequent call explicitly passing
|
||||
TRUE re-enables it. Closing a context clears C lifetime counters.
|
||||
|
||||
## Client statistics
|
||||
|
||||
Both clients expose `stats : ClientStats` and a public string property `toString`.
|
||||
The monitor display and `stats.toString` use `OK:<doneCnt>/Er:<errorCnt>`. For example,
|
||||
requests with 10/2 and 7/1 completions/errors show `OK:17/Er:3` on the client.
|
||||
|
||||
| Client member | Aggregation |
|
||||
|---|---|
|
||||
| doneCnt / errorCnt | Sum of registered request successes/failures |
|
||||
| sentCnt / replyCnt | Sum of accepted submissions / normal or exception replies |
|
||||
| exceptionCnt / timeoutCnt | Sum of exception replies / result 5 or 6 timeouts |
|
||||
| offlineCnt | Sum of request online-to-offline transitions |
|
||||
| requestCount | Registered requests, including disabled ones |
|
||||
| activeCount | Nonzero effective-length requests |
|
||||
| onlineCount / offlineCount / unknownCount | Active request communication state |
|
||||
| busyCount | Active requests executing |
|
||||
| staleCount | Active read requests with stale data |
|
||||
| heldWriteCount | Active write requests paused after uncertain delivery |
|
||||
| totalValidDuration | Sum of successful transaction duration totals, ms |
|
||||
| averageValidDuration | Weighted mean: totalValidDuration / doneCnt, integer ms |
|
||||
| longestValidDuration | Maximum successful duration across requests |
|
||||
| online / offline | Nonempty active set, all online / all explicitly offline |
|
||||
|
||||
Historical counters include registered inactive requests; state counts include
|
||||
only active requests. An empty client is neither online nor offline. Aggregate
|
||||
counters are ULINT. Per-request counters retain their existing types and saturate
|
||||
rather than wrap; request offline counts saturate at UINT max. Successful duration
|
||||
accumulation stops when the associated success counter saturates to keep the mean
|
||||
consistent. There is no misleading aggregate of consecutive-error streaks or
|
||||
unrelated start intervals.
|
||||
|
||||
`numMsgSent`/`numMsgReply` remain as saturated UDINT mirrors of aggregate totals.
|
||||
The one-second window fields remain scan-published counts/duration totals.
|
||||
Request `lastValidDuration` now measures C submit-to-completion, excluding the PLC
|
||||
pickup delay. `resetStats()` resets totals, duration history, timeout and offline
|
||||
counts consistently, while retaining connection state and data freshness. Resetting
|
||||
during a transaction allows its eventual completion to be counted after reset.
|
||||
|
||||
`out_errorCode` is the request result; `out_lastErrorCode` is the client's last
|
||||
engine error. OS errno is `out_socketError`. Historical last errors may persist
|
||||
after recovery. Result 260 means worker/affinity setup failed. A non-timeout failure
|
||||
no longer increments timeoutCnt. See the API reference for all declarations.
|
||||
|
||||
## TCP slave memory exchange
|
||||
|
||||
`SlaveTCP` and `ModbusSlave` provide the same TCP server behavior. Supply four arrays:
|
||||
`aCoilsMemory`, `aDiscreteInputsMemory`, `aHoldingRegistersMemory`, `aInputRegistersMemory`.
|
||||
Their lower/upper bounds are Modbus addresses within 0..65535; max 2000 per table.
|
||||
FC1/2/3/4 read; FC5/6/15/16 write coils/holding registers. Bind IP 0 means all
|
||||
interfaces; interfaceName must remain empty. Up to eight peers per server.
|
||||
|
||||
Remote changes are marked dirty in C. An old PLC push cannot overwrite dirty
|
||||
values before pull acknowledges them. Multiple remote writes before a scan expose
|
||||
the latest value, not an event history. After pull, a later application push may
|
||||
intentionally override those values. Other tasks must not race the array exchange.
|
||||
Table bounds/length changes require `in_reset := TRUE` to recreate the server;
|
||||
a changed mapping is rejected rather than silently discarding pending writes.
|
||||
|
||||
Online-change pointer ownership and physical hardware certification remain future
|
||||
work. This release needs a full download and on-target validation.
|
||||
For TCP-to-RTU converters, set `ClientTCP.in_baudrate` to the converter's
|
||||
serial baud rate. When no explicit request or client timeout is supplied, the
|
||||
library estimates timeout from the request/response frame size and baud rate,
|
||||
then adds turnaround and device-processing margin. Direct TCP clients should
|
||||
leave `in_baudrate` at zero and use the normal fixed TCP timeout.
|
||||
|
||||
+23
-33
@@ -1,39 +1,29 @@
|
||||
# Validation and remaining qualification
|
||||
# Validation and online-change qualification
|
||||
|
||||
IEC library version: 0.6.0.0. C component version: 0.4.0.0.
|
||||
External C ABI signature/API version are unchanged.
|
||||
Release versions: IEC library **0.8.0.0**, C component **0.5.0.0**. The external
|
||||
ABI signature/API version is unchanged.
|
||||
|
||||
## Passed on the Linux build host
|
||||
Host validation completed:
|
||||
|
||||
- Strict C compilation with warnings treated as errors for the test targets.
|
||||
- Bridge capacity, context pool, handle generation and shutdown tests.
|
||||
- Nine direct TCP and nine bridge TCP protocol/error/recovery scenarios.
|
||||
- RTU tests over real pseudo-terminals: fragmented frames, CRC errors, timeouts,
|
||||
exceptions, register/coil writes, invalid write echoes and recovery.
|
||||
- TCP slave FC1/2/3/4/5/6/15/16, address/exception handling and bind recovery.
|
||||
- Worker TCP and RTU responses complete with a 100 ms deadline while PLC calls
|
||||
are paused for 250 ms; results remain available for the next call.
|
||||
- Worker duration/age reporting and rejection of an unacknowledged result overwrite.
|
||||
- Slave service between scans and remote writes preserved against stale PLC pushes.
|
||||
- Scan watchdog transport shutdown and resumption, including uncertain sent writes
|
||||
without automatic worker replay; server watchdog listener restart.
|
||||
- CPU affinity configuration/restoration, invalid configuration rejection,
|
||||
concurrent status calls, and 20 worker shutdown/restart cycles.
|
||||
- Worker tests repeated after priority-inheritance mutex/error-reporting changes.
|
||||
- Full component host shared-object compile using the uploaded generated SDK headers;
|
||||
ComponentEntry and atmbcall_cext exported. This is not a fresh M4/ARM SDK build.
|
||||
- Updated IEC export parsed, object identifiers/references checked, basic structured
|
||||
text block balance checked, common client toString verified, and old embedded
|
||||
component removed. These checks do not substitute for the CODESYS compiler.
|
||||
- Strict synchronous C build and bridge capacity/pool/handle/shutdown tests.
|
||||
- Direct and bridge TCP normal, fragmented, timeout, protocol-error, exception,
|
||||
write and reconnect scenarios.
|
||||
- RTU pseudo-terminal frame, CRC, timeout, exception, register/coil write and
|
||||
recovery scenarios.
|
||||
- TCP slave function-code, exception, address and bind-recovery scenarios.
|
||||
- XML export parsing, object references, collection metadata and removal of the
|
||||
threaded Worker object.
|
||||
- C client `FB_reinit` closes its native context before clearing IEC pointers;
|
||||
slave `FB_reinit` closes its listener before clearing its handle.
|
||||
|
||||
## Required before deployment
|
||||
Required on each target before production:
|
||||
|
||||
Rebuild the C component for each target with its compatible SDK/toolchain, check
|
||||
its ELF architecture and GLIBC dependencies, import the export in CODESYS, compile,
|
||||
embed/deploy the rebuilt component and perform a full download. No updated compiled
|
||||
.library or ARM binary is supplied. Previous binaries are backups only.
|
||||
- Rebuild for the exact CPU/toolchain and verify ELF/GLIBC compatibility.
|
||||
- Compile/import the export in CODESYS and embed the matching C component.
|
||||
- Test online change while idle, during an active read, during disconnect and
|
||||
during an active write.
|
||||
- Verify contexts reopen, request pointers are rebuilt, data becomes valid, and
|
||||
no stale socket/listener remains after repeated online changes.
|
||||
|
||||
CODESYS IDE compilation, physical target/serial hardware testing, prolonged load
|
||||
and disconnect testing, and online-change behavior were not qualified here.
|
||||
Online change remains future work. Confirm watchdog and reconnect settings under
|
||||
actual PLC task jitter and network failures before production use.
|
||||
Physical target, prolonged soak, and CODESYS IDE qualification were not available
|
||||
in the host environment. Keep the previous threaded release as rollback only.
|
||||
|
||||
+13
-33
@@ -1,37 +1,17 @@
|
||||
# Worker ABI and lifecycle
|
||||
# Synchronous ABI and online-change lifecycle
|
||||
|
||||
The 16-argument atMbCall_cext ABI and its signature are retained. Calls are serialized
|
||||
by the lifecycle mutex and priority-inheritance engine mutex. The worker accesses
|
||||
fixed C contexts only. Calls may wait briefly for the engine mutex; no claim of
|
||||
hard real-time maximum latency is made for OS/serial-driver operations.
|
||||
There is no native worker thread in atMb 0.8. The existing 16-argument
|
||||
`atMbCall_cext` ABI is retained, and every transport tick runs synchronously in
|
||||
the PLC task that owns the IEC client or slave instance.
|
||||
|
||||
New commands:
|
||||
The C component uses fixed context pools, generation-checked handles and no
|
||||
retained IEC pointers. Request values and results are copied through the ABI
|
||||
buffers during the owning PLC call.
|
||||
|
||||
| Command | Purpose | Parameters / result |
|
||||
|---|---|---|
|
||||
| 12 | Client transaction timing | Normal handle; status[21] duration ms, [22] successful-read age ms (saturated UDINT); other client status fields retained |
|
||||
| 40 | Configure/start global worker | startAddress=CPU+1 (0 inherited mask), connectTimeoutMs=interval 1..20, responseTimeoutMs=watchdog 100..60000 |
|
||||
| 41 | Worker capabilities/status | No start side effect; available even before worker starts |
|
||||
For online change, `FB_reinit` closes the native context first, clears the client
|
||||
handle and all IEC request pointers, and resets active-request state. The next
|
||||
PLC scan recreates the context using the current configuration. Slave blocks
|
||||
close their listener before clearing their native handle.
|
||||
|
||||
Worker status words: [0] capability 0x00040000; [1] running; [2] pthread error;
|
||||
[3] configured CPU+1, 0 inherited mask; [4] interval ms; [5] watchdog ms;
|
||||
[6:7] cycle counter low/high; [8:9] monotonic heartbeat low/high. Remaining words zero.
|
||||
Error 260 reports worker initialization or CPU-affinity failure. Invalid settings
|
||||
return 1. Invalid settings do not change current affinity/timing.
|
||||
|
||||
Client command 5 and server command 34 now refresh the context's scan lease and
|
||||
snapshot state; they do not perform socket reads/writes. All deadline times are
|
||||
sourced from CLOCK_MONOTONIC; the ABI nowMs argument is retained but ignored.
|
||||
Command 6 rejects a new transaction until completion is acknowledged with command
|
||||
10. Completion data cannot be overwritten by another request before acknowledgment.
|
||||
|
||||
Worker shutdown sets a stop flag, releases the mutex, joins the thread, then
|
||||
closes contexts. Generation-tagged handles prevent access to released slots.
|
||||
Watchdog expiry closes transport while preserving the slot and terminal result;
|
||||
refresh resumes it. No worker thread is restarted repeatedly on link failure;
|
||||
existing TCP/RTU state machines retry within it.
|
||||
|
||||
Socket progress is nonblocking. Socket close/configuration calls may also occur
|
||||
synchronously for explicit close/reconfigure commands. These and serial ioctls are
|
||||
OS calls, so target execution-time measurement remains necessary. The worker uses
|
||||
normal SCHED_OTHER, not a high-priority busy loop.
|
||||
The external ABI signature/API version remain unchanged. Component version is
|
||||
0.5.0.0; IEC library version is 0.8.0.0.
|
||||
|
||||
Reference in New Issue
Block a user