大多数的OPC UA 建模工具通常是将NodeSet 编译成为C 或者C# 的源代码,然后和Server 程序一起编译。比如uaModeler,Opc foundation 的UA ModelCompiler 以及Open62541 提供的nodeset_Compiler 都是如此,这种方式在载入配套规范的Nodeset 无疑是比较方便的,但是对于用户自定义的信息模型,需要灵活地加载。特别是嵌入式控制器,更需要动态地加载信息模型。
值得庆幸的是,许多Opc Ua 的协议站提供了导入NodeNet的程序。例如在Python-opcua 中。使用:
server.import_xml("../schemas/UA-Nodeset/DI/Opc.Ua.Di.NodeSet2.xml")
server.import_xml("../schemas/UA-Nodeset/Robotics/Opc.Ua.Robotics.NodeSet2.xml")
在Open62541 中是NodeSetLoader库。但是网络上有关它的编译和使用信息很少,为此,本博文记录编译的过程。
Step 1 编译和安装Open62541
下载Open62541 包,提示的编译方法是:
mkdir build
cd build
cmake ..
make
但是值得注意的是 node-loader 的编译过程中,需要引用Open62541 package ,如何实现他们的联系,十分重要。 否则会出现:
解决的方法是将open62541 安装到usr/local.具体的方法是:make install
另一个问题是cmake 时 。UA_ENABLE_AMALGMATION 不能选择,要不然它将会Install 一个单一的open62541.h .无法被open62541_nodeset_loader 应用。
Step 2 下载 Open62541/open62541-nodeset-loader
下载地址:
GitHub - open62541/open62541-nodeset-loader: Library for loading opc ua nodesets from xml and sorting the nodes
安装依赖项。libxml-dev
sudo apt-get install libxml2-dev
Step3 CMake
mkdir build
cd build
cmake ..
make
编译出来的是一个静态库,为了让应用程序能够使用这个库,也需要sudo make install 才行
yao@T3660:~/yao2023/C++/open62541-nodeset-loader-master/build$ sudo make install
Step 4 应用程序
#include <NodesetLoader/backendOpen62541.h>
#include <NodesetLoader/dataTypes.h>
#include <open62541/plugin/log_stdout.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
static volatile UA_Boolean running = true;
static void stopHandler(int sign) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");
running = false;
}
int main(int argc, const char *argv[]) {
UA_Server *server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
//provide the server and the path to nodeset
//returns true in case of successful import
if(!NodesetLoader_loadFile(server, "../Opc.Ua.Di.NodeSet2.xml", NULL))
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "importing the xml nodeset failed");
}
UA_StatusCode retval = UA_Server_run(server, &running);
//NodesetLoader is allocating memory for custom dataTypes, user has to manually clean up
const UA_DataTypeArray *customTypes =
UA_Server_getConfig(server)->customDataTypes;
UA_Server_delete(server);
NodesetLoader_cleanupCustomDataTypes(customTypes);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
Step5 编译
gcc ./OpcUaLoader.c -o OpcUaLoader -lopen62541 -lNodesetLoader -lxml2
显然,open62541 ,nodeset_loader 都是以静态库使用的。
Step 6 运行,使用uaExperter 查看结果。你看到了UA/DI 命名空间以及对象。
现在,我们能够在open62541 Server 中动态倒入NodeSet2 模型了。