feat(plc4net): add little-endian byte order support to the C# code generator (#2840) * feat(plc4net): add little-endian byte order support to ReadBuffer/WriteBuffer Adds a byte-order stack (default BIG_ENDIAN) with PushByteOrder/PopByteOrder, and wires it into the unsigned and signed multi-byte read/write paths. Single bytes, bits, strings and byte arrays are unaffected - they have no byte order to begin with. Little-endian float/double reads and writes fail loudly (NotImplementedException) instead of silently computing a wrong value, since no mspec here declares one yet. The ByteOrder enum itself already existed (added in #2771) but had no consumer anywhere in the codebase; this wires it up for the first time. * feat(plc4net): emit the little-endian push/pop wrapper in the C# generator ValidateModel now accepts byteOrder="LITTLE_ENDIAN" on a complex type; enums and dataIo still require BIG_ENDIAN only, since neither has a parse/serialize body to scope a push/pop to. A type that declares LITTLE_ENDIAN has its generated StaticParse/Serialize push it before its own body and pop it in a finally, mirroring the Java generator's pushContext/popContext - a nested type that declares no byte order of its own inherits it from the same buffer, because it parses or serializes while still inside the declaring type's try. Regenerating S7 and Modbus (previously the only two protocols that passed ValidateModel) produces byte-for-byte unchanged output. The upstream SLMP mspec, previously rejected outright for declaring LITTLE_ENDIAN, now generates successfully end-to-end.
Apache PLC4X is an effort to create a set of libraries for communicating with industrial grade programmable logic controllers (PLCs) in a uniform way. We are planning on shipping libraries for usage in:
PLC4X also integrates with other Apache projects, such as:
And brings stand-alone (Java) utils such as:
It also provides (Java) tools for usage inside an application:
Both the integration modules as also the OPC-UA Server and PLC4X Server are being released as part of the plc4x-extras release.
Depending on the programming language, the usage will differ. Therefore, please go to the Getting Started on the PLC4X website to look up the language of choice.
NOTE: Currently the minimum Java version is Java 21, and we have tested it up to Java 24. The project is currently split up into three repositories, the plc4x, plc4x-build-tools and plc4x-extras repository.
To be able to build all parts of the plc4x-extras repository, at least Java 21 is required.
See the PLC4J user guide on the website to start using PLC4X in your Java application: https://plc4x.apache.org/plc4x/latest/users/getting-started/plc4j.html
Currently, the project is configured to require the following software:
JAVA_HOME configured to point to that.libpcap/Npcap for raw socket tests in Java or use of passive-mode driversDocker for running some tests making use of TestcontainersWARNING: The code generation uses a utility which requires some additional VM settings. When running a build from the root, the settings in the .mvn/jvm.config are automatically applied. When building only a submodule, it is important to set the vm-args: --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED. In Intellij, for example, set these in the IDE settings under: Preferences | Build, Execution, Deployment | Build Tools | Maven | Runner: JVM Options.
When doing a full build, we automatically run a prerequisite check and fail the build with an explanation of what to do, if not all requirements are met.
A more detailed description is available on our website:
https://plc4x.apache.org/plc4x/latest/developers/preparing/index.html
PLC4C we also need:All requirements are retrieved by the build itself
PLC4Go we also need:All requirements are retrieved by the build itself
PLC4Py we also need:PLC4Net we also need:Part of the build requires quite a bit of ram. Before running the Docker build, please ensure that the Docker runtime has at least 12GB of ram available.
If you don't want to bother setting up the environment on your normal system, and you have Docker installed, you can also build everything in a Docker container:
docker compose up
This will build a local Docker container able to build all parts of PLC4X and will run a maven build of the local directory inside this container.
The default build will run a local release-build, so it can also be used to ensure reproducible builds when releasing.
Per default, it will store files locally:
out/.repositoryThe reason for this is that otherwise the artifacts would be packaged in with the source-release artifact, resulting in a 12GB or more zip archive. However, saving it in the main target directory would make the build delete the local repo every time a mvn clean is run. The out directory however is excluded per default from the assembly descriptor, and therefore it is not included in the source zip.
You must have at least Java 21 installed on your system and connectivity to Maven Central for downloading external third party dependencies. Maven 4.0.0-rc-5 or newer is required to build, so be sure it's installed and available on your system (the bundled Maven-Wrapper takes care of this automatically).
NOTE: There is a convenience Maven-Wrapper installed in the repo, when used, this automatically downloads and installs Maven. If you want to use this, please use ./mvnw or mvnw instead of the normal mvn command.
NOTE: When running from sources-zip, the mvnw might not be executable on Mac or Linux. This can easily be fixed by running the following command in the directory.
$ chmod +x mvnw
NOTE: If you are working on a Windows system, please use mvnw.cmd instead of ./mvnw in the following build commands.
Build PLC4X Java jars and install them in your local maven repository
./mvnw -P with-java install
You can now construct Java applications that use PLC4X. The PLC4X examples are a good place to start and are available inside the plc4j/examples directory, which is part of the plc4x-extras repository.
The Go drivers can be built by enabling the with-go profile:
./mvnw -P with-go install
The C# / .Net implementation is currently in a work in progress state. It includes Modbus TCP/RTU and S7 drivers, and TCP, serial, COTP and UDP transports. To be able to build the C# / .Net module, you currently need to activate the: with-dotnet profiles.
./mvnw -P with-dotnet install
The Python implementation is currently in a somewhat unclean state and still needs refactoring. To be able to build the Python module, you currently need to activate the: with-python profiles.
./mvnw -P with-python install
To build everything, the following command should work:
./mvnw -P with-c,with-dotnet,with-go,with-java,with-python,enable-all-checks install
In the past the build used to generate the code in every run. Especially when it comes to reproducible builds, this was problematic. We have recently updated the build to only generate the code if explicitly asked to do it.
By enabling the update-generated-code profile, this can be enabled.
So to build absolutely everything, the following command does the trick:
./mvnw -P with-c,with-dotnet,with-go,with-java,with-python,update-generated-code,enable-all-checks install
If you don't enable a language, the code for this language remains untouched by the build.
Join the PLC4X community by using one of the following channels. We'll be glad to help!
Subscribe to the following mailing lists:
Get the latest PLC4X news on LinkedIn: https://www.linkedin.com/company/apache-plc4x/posts
There are multiple forms in which you can become involved with the PLC4X project.
These are, but are not limited to:
We are a very friendly bunch so don’t be afraid to step forward. If you'd like to contribute to PLC4X, have a look at our contribution guide!
Apache PLC4X is released under the Apache License Version 2.0.