brief introduction
open62541 uses CMake to build libraries and binaries. The version of the library is automatically detected with git describe. This command returns a valid version string based on the current tag. If you don't clone the source code directly, but use a tar or zip package from the release, you need to specify the version manually. In this case, for example
cmake -DOPEN62541_VERSION=v1.0.3
target
Translation and supplement open62541v1 2 official manual.
Building open62541 Library
Build with CMake on Ubuntu or Debian
sudo apt-get install git build-essential gcc pkg-config cmake python # enable additional features sudo apt-get install cmake-curses-gui # for the ccmake graphical interface sudo apt-get install libmbedtls-dev # for encryption support sudo apt-get install check libsubunit-dev # for unit tests sudo apt-get install python-sphinx graphviz # for documentation generation sudo apt-get install python-sphinx-rtd-theme # documentation style cd open62541 mkdir build cd build cmake .. make # select additional features ccmake .. make # build documentation make doc # html documentation make doc_pdf # pdf documentation (requires LaTeX)
Building with CMake on Windows
Here we explain the construction process of Visual Studio (2013 or later). To build with MinGW, simply replace the compiler's choice when calling CMake.
-
Download and install
-
Python 2.7.x (Python 3.x can also): https://python.org/downloads
-
CMake: http://www.cmake.org/cmake/resources/software.html
-
Microsoft Visual Studio: https://www.visualstudio.com/products/visual-studio-community-vs
-
-
Download the source code of open62541 (use git or download the zip file from github)
-
Open a command shell (cmd) and run it
cd <path-to>\open62541 mkdir build cd build <path-to>\cmake.exe .. -G "Visual Studio 14 2015" :: You can use use cmake-gui for a graphical user-interface to select features
Then open buildoppen62541.0 in Visual Studio 2015 SLN and build as usual.
Build on OS X
-
Download and install
-
Xcode: https://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12
-
Homebrew: http://brew.sh/
-
Pip (Python package manager, which may be pre installed): sudo easy_install pip
-
-
Run the following program in the shell
brew install cmake pip install sphinx # for documentation generation pip install sphinx_rtd_theme # documentation style brew install graphviz # for graphics in the documentation brew install check # for unit tests
Follow the instructions of Ubuntu and do not use the apt get command, as these are handled by the above package.
Build on OpenBSD
The following program runs on OpenBSD 5.8, gcc version 4.8.4, cmake version 3.2.3 and Python version 2.7.10.
- Install the latest gcc, python, and cmake.
pkg_add gcc python cmake
- Tell the system to actually use the latest GCC (it is installed as egcc on OpenBSD).
export CC=egcc CXX=eg++
- Now follow the instructions for Ubuntu/Debian.
cd open62541 mkdir build cd build cmake ... make
Build Debian packages in Docker container with CMake on Ubuntu or Debian
The following is an example of how to build a Debian package in the Docker container
- Download and install
- Docker Engine: https://docs.docker.com/install/linux/docker-ce/debian/
- docker-deb-builder: https://github.com/tsaarni/docker-deb-builder.git
- open62541: https://github.com/open62541/open62541.git
according to https://docs.docker.com/install/linux/docker-ce/debian/ Install Docker as described in.
Get the Docker DEB builder tool from github and create a Docker image for the required Debian and / or Ubuntu versions.
# make and goto local development path (e.g. ~/development) mkdir ~/development cd ~/development # clone docker-deb-builder utility from github and change into builder directory git clone https://github.com/tsaarni/docker-deb-builder.git cd docker-deb-builder # make Docker builder images (e.g. Ubuntu 18.04 and 17.04) docker build -t docker-deb-builder:18.04 -f Dockerfile-ubuntu-18.04 . docker build -t docker-deb-builder:17.04 -f Dockerfile-ubuntu-17.04 .
Make a local copy of open62541 git repo and check out a pack branch
# Make a local copy of open62541 git repo (for example, in the home directory). # And check out a pack branch (for example, pack/1.0). cd ~ git clone https://github.com/open62541/open62541.git cd ~/open62541 git checkout pack/1.0
You are now ready to build the Debian/Ubuntu open62541 package
# Go to local development path cd ~/development # Create a local output directory for the compiler where the software package can be placed after compilation mkdir output # Build Debian/Ubuntu packages in the Docker container (for example, Ubuntu-18.04). ./build -i docker-deb-builder:18.04 -o output ~/open62541
After the build is successful, you can find the Debian/Ubuntu package in ~ / development / docker DEB builder / output.
CMake build options and Debian packaging
If the open62541 library will use packaging branches (such as pack/master or pack/1.0) to build Debian packages, changing or adding CMake build options should be done in debian/rules files. If development branches (such as master or 1.0) are used, it should be done in debian/rules template files.
In debian/rules, the part that defines CMake build options is
... override_dh_auto_configure. dh_auto_configure -- -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUA_NAMESPACE_ZERO=FULL -DUA_ENABLE_AMALGAMATION=OFF -DUA_PACK_DEBIAN=ON ...
This CMake build option will be passed to CMake as a command line variable when Debian is packaged.
Build options
The open62541 project uses CMake to manage build options for code generation and build projects for different systems and ides. The tools ccmake or CMake GUI can be used to graphically set build options.
Most options are available in UA after code generation_ config. H (the single file version is open62541.h). But they usually do not need to be adjusted.
This CMake build option will be passed to CMake as a command line variable when Debian is packaged.
Main build options
- cmake_build_type
-
RelWithDebInfo - O2 optimization with debug symbols
-
Release -O2 optimization, no debug symbol
-
Debug -O0 optimization, with debugging symbols
-
MinSizeRel -O optimized, no debug symbol
- UA_LOGLEVEL
SDK only records UA_ Events of loglevel and above. The level of recorded events is as follows.
-
600: fatal
-
500: error
-
400: warning
-
300: Information
-
200: debugging
-
100: tracking
- ua_multithreading
The level of multithreading support. The current levels of support are as follows.
-
0-99: disable multithreading support.
-
100-199: marked UA_ The API functions of threadsafe macro are protected from internal disturbances. Multiple threads are allowed to call these functions of the SDK at the same time without causing race conditions. In addition, this level supports processing asynchronous method calls from external worker threads.
-
>=200: work is assigned to some internal worker threads. Currently only used for mDNS discovery. (experimental function! Expected bug s.)
Select build artifact
By default, only the main library share object libopen62541 So (open62541.dll) or static link file open62541 A (open62541.lib) is built. Additional artifacts can be specified through the following options.
ua_build_examples
From examples / * C compile examples of server and client.
ua_build_unit_tests
Compile unit tests. These tests can be performed with make test.
ua_build_selfsigned_certificate
Generate a self signed certificate for the server (openSSL required).
Detailed SDK functions
-
ua_enable_subscriptions
Enable subscription
-
ua_enable_subscriptions_events (experimental)
Enables the use of subscribed events. This is a new feature that is currently marked as experimental.
-
ua_enable_subscriptions_alarms_conditions (experimental)
Enable the use of subscribed a & C. This is a new feature based on events and is currently marked as experimental.
-
ua_enable_methodcalls
Enable method service set.
-
ua_enable_parsing
Enables parsing of human readable formats of built-in data types (Guid, NodeId, etc.). Utility functions that are not essential to the SDK.
-
ua_enable_nodemanagement
Enables the ability to dynamically add and remove nodes at run time
-
**ua_enable_amalgamation **
Compile to open41.41 file C and open62541 h. Not recommended for installation.
-
ua_enable_immutable_nodes
Nodes in the information model are not edited, but copied and replaced. Replacement is done through atomic operations, so the information model is always consistent and can be accessed from interrupts or parallel threads (depending on the implementation of the node storage plug-in). This function is UA_ Prerequisites for multithreading.
-
ua_enable_coverage
Measuring coverage of unit tests
-
ua_enable_discovery
Enable discovery services (LDS).
-
ua_enable_discovery_multicast
Enable multicast enabled discovery service (LDS-ME).
-
ua_enable_discovery_semaphore
Enable discovery register support
ua_namespace_zero
Namespace zero contains standard defined nodes. A complete namespace zero may not be required for all applications. The options you can select are as follows.
- MINIMAL. A bare namespace 0, compatible with most clients. However, the namespace 0 is too small to pass the CTT (OPC Foundation's conformance testing tool).
- REDUCED. Small namespace 0, via CTT.
- `FULL ': the complete namespace generated from the official XML definition is zero.
Advanced build options UA_FILE_NS0 can be used to overwrite the XML file used to generate namespace zero.
Some options are marked as advanced options. Advanced options need to be switched to visible in cmake GUI.
-
ua_enable_typedescription
Add type and member name to UA_DataType structure. Enabled by default.
-
ua_enable_statuscode_descriptions
Compile the human readable name of StatusCodes into binary. It is enabled by default.
-
ua_enable_full_ns0
Use the full NS0 instead of the smallest namespace 0 node set UA_FILE_NS0 specifies the files that generate NS0 from the namespace 0 folder. The default value is OPC Ua. NodeSet2. xml.
Debug build options
This set of build options is mainly useful for the development of the library itself.
-
UA_DEBUG
Enable assertions and additional definitions that are not used for production builds
-
ua_debug_dump_pkgs
Dump each package received by the server into hexdump format.
Build a shared library
Open62541 is so small that most users want to statically link the library to their programs. If you need a shared library (. DLL,. So), you can use build in CMake_ SHARED_ LIBS option to enable. Note that this option modifies ua_config.h file, which is also included in open62541.0 issued by a single file H medium.
Minimize binary file size
By adjusting the build configuration, you can greatly reduce the size of the generated binaries. Using open2541, you can configure the smallest server, requiring less than 100kB RAM and ROM.
The following options affect ROM requirements.
First, in CMake, the build type can be set to CMAKE_BUILD_TYPE=MinSizeRel. This sets the flag of the compiler to minimize the binary size. Build types also strip debugging information. Secondly, the binary size can be reduced through the above build flag deletion function.
Secondly, UA_ NAMESPACE_ Setting zero to minimum can reduce the size of the built-in information model. In some cases, setting this option can reduce the binary size by half.
Third, some functions may not be required and can be disabled to reduce the occupation of binary. An example of this is subscription or encrypted communication.
Finally, log information takes up a lot of space in binary files, which may not be needed in embedded scenarios. Transfer UA_ When loglevel is set to a value above 600 (fat), all logging can be stopped. In addition, the function flag UA_ENABLE_TYPEDESCRIPTION and UA_ENABLE_STATUSCODE_DESCRIPTIONS adds static information to the binary file, which is only used for human readable logging and debugging.
The RAM requirements of the server are mainly caused by the following settings.
- Size of information model
- Number of connected clients
- Configured pre allocated maximum information size
Build instance
Make sure you can follow the previous steps to build a shared library. A simpler way is to install open62541 in your operating system (see Installing open62541).
The compiler will then automatically find the includes and shared libraries.
cp /path-to/examples/tutorial_server_firststeps.c . # Copy sample server gcc -std=c99 -o server tutorial_server_firststeps.c -lopen62541
Build for a specific architecture
open62541 library can be built for many operating systems and embedded systems. This document shows an excerpt from a small number of tested architectures. Since the stack only uses the C99 standard, there are many supported architectures.
A complete list of implemented schema support can be found in the arch folder.
Windows, Linux, MacOS
These schemas are supported by default and are automatically selected by CMake.
Look at the previous chapter to see how to do this.
freeRTOS + LwIP
Thanks to @cabralfortiss
This document is a PR based discussion https://github.com/open62541/open62541/pull/2511 . If you have any questions, please check the discussion there first.
This document assumes that you have a basic example of using LwIP and freeRTOS and work normally. You just want to add an OPC UA task.
There are two main methods to build freeRTOS + LwIP open62541.
- Select the cross compiler in CMake, set the flag required for compilation (each microcontroller is different, so it may be difficult), and then run make in the folder, and the library should be generated. This approach can be difficult because you need to specify the include file and some other configurations.
- Using freeRTOSLWIP architecture to generate open6254 H and open6254 C files, and then put these files in the project of the IDE you use to compile. This is the simplest method, and the document only focuses on this method.
In CMake, use UA_ Select freertosLWIP for the architecture variable and use UA_ ENABLE_ The amalgamation variable enables mercury homogenization by simply selecting the local compiler. Compile and try as usual. Compilation will fail, but open62541 H and open62541 C will be generated.
Note: if you use freeRTOS's memory allocation function (pvPortMalloc and family), you also need to set the variable UA_ARCH_FREERTOS_USE_OWN_MEMORY_FUNCTIONS is set to true. Many users have to implement pvPortCalloc and pvPortRealloc.
If the terminal is used, the command should be like this
mkdir build_freeRTOS cd build_freeRTOS cmake -DUA_ARCHITECTURE=freertosLWIP -DUA_ENABLE_AMALGAMATION=ON ./ make
Remember, compilation will fail. This is not a problem, because you only need to find the generated files (open62541.h and open62541.c) in the directory you are trying to compile. Import these files in the IDE you use. There is no standard method in all ides, but you need to do the following configuration in your project.
- Add open62541 C file
- Add variable UA in compilation_ ARCHITECTURE_ FREERTOSLWIP
- Make sure open62541 H is included in a folder at compile time.
When compiling LwIP, you need a file called lwipopts H. In this file, you need to put all the configuration variables. You need to make sure you have the following configuration.
#define LWIP_ COMPAT_ Socks 0 / / do not perform name definition conversion in the network function name. #define LWIP_SOCKET 1 / / enable Socket API (usually set) #define LWIP_DNS 1 / / enable lwip_getaddrinfo function, struct addrinfo, etc. #define SO_REUSE 1 / / allows the socket to be set to be reusable #define LWIP_TIMEVAL_PRIVATE 0 / / this is optional. If you get a compilation error about redefining struct timeout, please set this flag.
For freeRTOS, there is a similar file called freertosconfig h. Usually, you should have an example project with this file. It is recommended to check only two variables.
#define configCHECK_FOR_STACK_OVERFLOW 1 #define configUSE_MALLOC_FAILED_HOOK 1
When running OPC UA server in freeRTOS + LwIP, most of the problems come from embedded systems with limited memory, so these definitions will allow you to check whether there are memory problems (which will save a lot of effort in finding hidden problems).
Now, you need to add the task of starting OPC UA server.
static void opcua_thread(void *arg){ //The default 64KB of memory for send and receive buffers poses a problem for many users. Using the following code, they are reduced to ~ 16KB UA_UInt32 sendBufferSize = 16000; //64KB is too large for my platform. UA_UInt32 recvBufferSize = 16000; //64 KB is too much for my platform. UA_UInt16 portNumber = 4840; UA_Server* mUaServer = UA_Server_new(); UA_ServerConfig *uaServerConfig = UA_Server_getConfig(mUaServer). UA_ServerConfig_setMinimal(uaServerConfig, portNumber, 0, sendBufferSize, recvBufferSize). //Very important: set the host name with your IP before starting the server. UA_ServerConfig_setCustomHostname(uaServerConfig, UA_STRING("192.168.0.102")). //The rest is the same as the example UA_Boolean running = true. //Add a variable node to the address space UA_VariableAttributes attr = UA_VariableAttributes_default; UA_Int32 myInteger = 42; UA_Variant_setScalarCopy(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]). attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US", "the answer"); attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", "the answer"). UA_NodeId myIntegerNodeId = UA_NODEID_STRING_ALLOC(1, "the.answer"); UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME_ALLOC(1, "the answer"); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_Server_addVariableNode(mUaServer, myIntegerNodeId, parentNodeId, parentReferenceNodeId, myIntegerName, UA_NODEID_NULL, attr, NULL, NULL). ) /* Allocations on the heap need to be freed */ UA_VariableAttributes_clear(&attr). UA_NodeId_clear(&myIntegerNodeId). UA_QualifiedName_clear(&myIntegerName). UA_StatusCode retval = UA_Server_run(mUaServer, &running); UA_Server_delete(mUaServer). }
In your main function, after initializing the TCP IP stack and all hardware, you need to add tasks.
//8000 is the stack size and 8 is the priority. These values may need to be changed according to your project if(NULL == sys_thread_new("opcua_thread", opcua_thread, NULL, 8000, 8)) LWIP_ASSERT("opcua(): Task creation failed.", 0);
Finally, add in the same file (or actually any file).
void vApplicationMallocFailedHook(){ for(;;){ vTaskDelay(pdMS_TO_TICKS(1000)). } } void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ){ for(;;){ vTaskDelay(pdMS_TO_TICKS(1000)). } }
And put a breakpoint in each vtask delay. These functions are called when there is a problem with the heap or stack. If the program gets here, you have a memory problem.
That's it. Your OPC UA server should run smoothly. If not, as mentioned earlier, please check https://github.com/open62541/open62541/pull/2511 Discussion in. If you still have questions, please ask them there to keep the discussion focused.