OPC UA/DA协议库open62541的源码编译及案例测试

您所在的位置:网站首页 linux使用cmake编译 OPC UA/DA协议库open62541的源码编译及案例测试

OPC UA/DA协议库open62541的源码编译及案例测试

2023-05-27 13:42| 来源: 网络整理| 查看: 265

目录

一、下载源码

二、编译源码

三、案例编译

        3.1 工程目录

        3.2 server端

        3.3 client端

       3.4 程序运行

四、补充open62541库的linux编译

        4.1 cmake版本升级

        4.2 python3支持

        4.3 open62541源码编译

一、下载源码

        win10系统下,安装git工具,下载open62541库源码,该源码是MPLv2的License

git clone --recursive https://github.com/open62541/open62541.git #gitee git clone --recursive https://gitee.com/qihuanweidu007/open62541.git #如果某些模块无法加载,重新调整网络后,继续加载确保无fail输出 cd open62541 git submodule update --remote --recursive

         系统安装了cmake、MinGW、VC和python3工具,将工作路径加入环境变量path中。

二、编译源码

        进入open62541目录

#本文的源码路径是D:\\workForOrgCode\\open62541 #创建编译目录 mkdir build_mingw #或cmd指令md指令创建目录 cd build_mingw cmake -G "MinGW Makefiles" .. -DUA_ENABLE_AMALGAMATION=ON #如果提示无法查找到python3包,直接显式指定 cmake -G "MinGW Makefiles" .. -DUA_ENABLE_AMALGAMATION=ON -DPython3_EXECUTABLE="D:\\workForSoftware\\python36\\python.exe" #编译 mingw32-make -j4 #或cmake --build . --config release #vc编译 md build_vc cd build_vc #本文采用vs2013版本 cmake -G "Visual Studio 12 2013" .. -DUA_ENABLE_AMALGAMATION=ON -DPython3_EXECUTABLE="D:\\workForSoftware\\python36\\python.exe" cmake --build . --config release 可能会出现 error C2220: 警告被视为错误 - 没有生成“object”文件, 可以通过文本编辑工具将生成的open62541.c文件改为ANSI格式,然后再次编译

       在编译过程中,会显示生成open62541.h和open62541.c文件,然后再编译成库文件,按官方说法,直接引入open62541.h和open62541.c来源码及生成库文件来开发,

        如果不想引入那么大的open62541.h头文件,也可以按需引入各个头文件,这些文件的存放路径例如:

#"D:\\workForOrgCode\\open62541\\include" #"D:\\workForOrgCode\\open62541\\build_mingw\\src_generated" #"D:\\workForOrgCode\\open62541\\arch" #"D:\\workForOrgCode\\open62541\\deps" #"D:\\workForOrgCode\\open62541\\plugins\\include"

        库文件生成输出在build_mingw\bin目录下。

三、案例编译         3.1 工程目录 #D:\workForOrgCode\open62541目录下 demo server_test bin build_mingw build_vc src main.c CMakeLists.txt client_test bin build_mingw build_vc src main.c CMakeLists.txt         3.2 server端

                main.c,这里采用的是直接引入编译生成的open62541.h头文件,也可直接引用仅涉及的头文件,如注释的那样:

#include //#include //#include #include "open62541.h" UA_Boolean running = true; void signalHandler(int sig) { running = false; } int main(int argc, char** argv) { signal(SIGINT, signalHandler); /* catch ctrl-c */ /* Create a server listening on port 4840 */ UA_Server *server = UA_Server_new(); UA_ServerConfig_setDefault(UA_Server_getConfig(server)); /* Add a variable node */ /* 1) Define the node attributes */ UA_VariableAttributes attr = UA_VariableAttributes_default; attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); UA_Int32 myInteger = 42; UA_Variant_setScalar(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); /* 2) Define where the node shall be added with which browsename */ UA_NodeId newNodeId = UA_NODEID_STRING(1, "the.answer"); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_NodeId variableType = UA_NODEID_NULL; /* take the default variable type */ UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, "the answer"); /* 3) Add the node */ UA_Server_addVariableNode(server, newNodeId, parentNodeId, parentReferenceNodeId, browseName, variableType, attr, NULL, NULL); /* Run the server loop */ UA_StatusCode status = UA_Server_run(server, &running); UA_Server_delete(server); return status; }

        CMakeLists.txt,如果采用了单独引入各个头文件的方式,主要把各个头文件及关联头文件的所在路径添加进来,如这些目录(include_directories)如本文所注释掉的那些:

# CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 项目信息 project (opc_server_test) # if(WIN32) message(STATUS "windows compiling...") add_definitions(-D_PLATFORM_IS_WINDOWS_) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(WIN_OS true) else(WIN32) message(STATUS "linux compiling...") add_definitions( -D_PLATFORM_IS_LINUX_) add_definitions("-Wno-invalid-source-encoding") # add_definitions("-O2") set(UNIX_OS true) set(_DEBUG true) endif(WIN32) set(UA_IPV6 0) set(org_dir ${PROJECT_SOURCE_DIR}/../..) #即D:\\workForOrgCode\\open62541 set(build_dir ${PROJECT_SOURCE_DIR}/../../build_mingw) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_vc) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_linux) # set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 指定源文件的目录,并将名称保存到变量 SET(source_h # #${build_dir}/open62541.h #由于添加了其所在目录,不用直接添加 ) SET(source_cpp # ${PROJECT_SOURCE_DIR}/src/main.c ${build_dir}/open62541.c ) #头文件目录 include_directories( ${build_dir} #引入open62541.h所在目录 #${org_dir}/include #${build_dir}/src_generated #${org_dir}/arch #${org_dir}/deps #${org_dir}/plugins/include ) if (${UNIX_OS}) add_definitions( "-DUA_ARCHITECTURE_POSIX" ) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") link_directories() # 指定生成目标 add_executable(opc_server_test ${source_h} ${source_cpp} ) #link target_link_libraries(opc_server_test -lpthread ${build_dir}/bin/libopen62541.a ) endif(${UNIX_OS}) if (${WIN_OS}) add_definitions( "-DUA_ARCHITECTURE_WIN32" ) link_directories( "${build_dir}/bin" ) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin) # 指定生成目标 add_executable(opc_server_testd ${source_h} ${source_cpp} ) #link target_link_libraries(opc_server_testd ws2_32.lib wsock32.lib Iphlpapi.lib #win下依赖的基础库 ${build_dir}/bin/libopen62541.a #mingw #${build_dir}/bin/Debug/open62541d.lib #vc ) else(CMAKE_BUILD_TYPE) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin) # 指定生成目标 add_executable(opc_server_test ${source_h} ${source_cpp}) #link target_link_libraries(opc_server_test ws2_32.lib wsock32.lib Iphlpapi.lib ${build_dir}/bin/libopen62541.a #mingw #${build_dir}/bin/Release/open62541.lib #vc #D:\\workForOrgCode\\open62541\\build_vc\\bin\\Release\\open62541.lib #vc ) endif (CMAKE_BUILD_TYPE) endif(${WIN_OS})

        编译 ,注意mingw和vc编译时,需要在CMakeLists.txt中调整一下配置路径      

#D:\workForOrgCode\open62541\demo\server_test #工程配置在CMakeLists.txt set(build_dir ${PROJECT_SOURCE_DIR}/../../build_mingw) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_vc) #link ${build_dir}/bin/libopen62541.a #mingw #${build_dir}/bin/Release/open62541.lib #vc 编译 cd build_mingw cmake -G "MinGW Makefiles" .. mingw32-make -j4 #或cmake --build . --config release #D:\workForOrgCode\open62541\demo\server_test #工程配置在CMakeLists.txt #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_mingw) set(build_dir ${PROJECT_SOURCE_DIR}/../../build_vc) #link #${build_dir}/bin/libopen62541.a #mingw ${build_dir}/bin/Release/open62541.lib #vc 编译 cd build_vc cmake -G "Visual Studio 12 2013" .. cmake --build . --config release         3.3 client端

        main.c,如果不想直接引用open62541.h,可独立引用关联文件,注意在CMakeLists.txt中配置这头文件所在的目录

#include //#include //#include //#include #include "open62541.h" int main(int argc, char *argv[]) { /* Create a client and connect */ UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode status = UA_Client_connect(client, "opc.tcp://localhost:4840"); if(status != UA_STATUSCODE_GOOD) { UA_Client_delete(client); return status; } /* Read the value attribute of the node. UA_Client_readValueAttribute is a * wrapper for the raw read service available as UA_Client_Service_read. */ UA_Variant value; /* Variants can hold scalar values and arrays of any type */ UA_Variant_init(&value); status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value); if(status == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) { printf("the value is: %i\n", *(UA_Int32*)value.data); } /* Clean up */ UA_Variant_clear(&value); UA_Client_delete(client); /* Disconnects the client internally */ return status; }

        CMakeLists.txt

#在D:\workForOrgCode\open62541\demo\client_test目录下 # CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 项目信息 project (opc_client_test) # if(WIN32) message(STATUS "windows compiling...") add_definitions(-D_PLATFORM_IS_WINDOWS_) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(WIN_OS true) else(WIN32) message(STATUS "linux compiling...") add_definitions( -D_PLATFORM_IS_LINUX_) add_definitions("-Wno-invalid-source-encoding") # add_definitions("-O2") set(UNIX_OS true) set(_DEBUG true) endif(WIN32) set(UA_IPV6 0) set(org_dir ${PROJECT_SOURCE_DIR}/../..) set(build_dir ${PROJECT_SOURCE_DIR}/../../build_mingw) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_vc) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_linux) # set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 指定源文件的目录,并将名称保存到变量 SET(source_h # #${build_dir}/open62541.h ) SET(source_cpp # ${PROJECT_SOURCE_DIR}/src/main.c ${build_dir}/open62541.c ) #头文件目录 include_directories( ${build_dir} #${org_dir}/include #独立引用关联头文件需要配置各文件目录 #${build_dir}/src_generated #${org_dir}/arch #${org_dir}/deps #${org_dir}/plugins/include ) if (${UNIX_OS}) add_definitions( "-DUA_ARCHITECTURE_POSIX" ) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") link_directories() # 指定生成目标 add_executable(opc_client_test${source_h} ${source_cpp} ) #link target_link_libraries(opc_client_test -lpthread ${build_dir}/bin/libopen62541.a ) endif(${UNIX_OS}) if (${WIN_OS}) add_definitions( "-DUA_ARCHITECTURE_WIN32" ) link_directories( "${build_dir}/bin" ) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin) # 指定生成目标 add_executable(opc_client_testd ${source_h} ${source_cpp} ) #link target_link_libraries(opc_client_testd ws2_32.lib wsock32.lib Iphlpapi.lib ${build_dir}/bin/libopen62541.a #mingw #${build_dir}/bin/Debug/open62541d.lib #vc ) else(CMAKE_BUILD_TYPE) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin) # 指定生成目标 add_executable(opc_client_test ${source_h} ${source_cpp}) #link target_link_libraries(opc_client_test ws2_32.lib wsock32.lib Iphlpapi.lib ${build_dir}/bin/libopen62541.a #mingw #${build_dir}/bin/Release/open62541.lib #vc #D:\\workForOrgCode\\open62541\\build_vc\\bin\\Release\\open62541.lib #vc ) endif (CMAKE_BUILD_TYPE) endif(${WIN_OS})

        编译类似服务端。

       3.4 程序运行

        程序运行测试,先开启服务端,然后开启客户端,如下,客户端连接上服务端,取回一个数值并打印出来“the value is 42”,如果没有连接上,请检查端口是否被其他程序占用或防火墙隔离:

四、补充open62541库的linux编译         4.1 cmake版本升级

        本文ubuntu16-64bit环境,先升级cmake工具(原来是3.5.2版本的)

#D:\workForOrgCode\open62541 mkdir cmake_new_version cd cmake_new_version #cmake 源码ftp网站https://cmake.org/files/ 下载需要的版本 wget https://cmake.org/files/v3.24/cmake-3.24.2.tar.gz tar -zxvf cmake-3.24.2.tar.gz cd cmake-3.24.2 #apt-get install libssl-dev #OPENSSL依赖 或./configure -DCMAKE_USE_OPENSSL=OFF ./configure make -j4 #root 用户下 make install update-alternatives --install /usr/bin/cmake cmake /usr/local/bin/cmake 1 --force cmake --version         4.2 python3支持

        再安装python3支持

#root 用户下 apt-get install python python3 python-pip python3-pip whereis python3 #例如/usr/bin/python3         4.3 open62541源码编译

        编译过程大致如下:

#确保cmake > 3.15版本,确保安装了python3支持,确保安装了gcc #进入open62541目录 mkdir build_linux cd build_linux cmake .. -DUA_ENABLE_AMALGAMATION=ON -DUA_MULTITHREADING=100 -DPython3_EXECUTABLE="/usr/bin/python3" make -j4 #open62541.c:68808:43: error: comparison is always false due to limited range of data type [-Werror=type-limits] if(i < T##_MIN || (i > 0 && (t)i >= T##_MAX)) #修改为:if(i < T##_MIN || (i > 0 && (t)i >= T##_MAX)) ,再次编译 make -j4

        编译结果输出如下:

         案例编译与win类似。

#先调整CMakeLists.txt #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_mingw) #set(build_dir ${PROJECT_SOURCE_DIR}/../../build_vc) set(build_dir ${PROJECT_SOURCE_DIR}/../../build_linux) #进入open62541目录 cd demo/server_test mkdir build_linux cd build_linux cmake .. -DUA_ENABLE_AMALGAMATION=ON make -j4 #client端类似


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3