学习open62541 --- [75] 生成namespace文件的简便方法

news2024/12/26 15:42:51

在之前的文章中,生成namespace文件是使用open62541提供的nodeset_compiler.py,根据nodeset_compiler.rst(位于open62541/doc/)里的描述,有更好的方法:使用cmake命令ua_generate_nodeset_and_datatypes来生成。

nodeset_compiler.py只能生成nodeset文件;ua_generate_nodeset_and_datatypes不仅可以生成nodeset文件,还能生成datatype文件和nodeid文件,另外可以很简单的处理依赖问题。

PS:ua_generate_nodeset_and_datatypes也是open62541提供的。

open62541也提供了例子,即example/nodeset/,但是看着明白却不知道怎么用。本文从实践的角度来讲解具体用法,开发环境是Debian 10


一 修改python脚本权限

因为ua_generate_nodeset_and_datatypes会调用python脚本generate_nodeid_header.py,所以先要给脚本添加权限,否则无法生成,这个坑也是我调试了很久才发现的…

chmod 755 open62541/tools/generate_nodeid_header.py

二 命令解释

ua_generate_nodeset_and_datatypes是一个自定义的CMake命令,位于文件open62541/tools/cmake/macros_public.cmake里,

其用法介绍如下,
在这里插入图片描述
其产生的CMake目标为open62541-generator-ns-${NAME},这个NAME由用户指定。该命令的输入参数有以下这些,

  • Options:
    • INTERNAL:Include internal headers. Required if custom datatypes are added.
  • Arguments taking one value:
    • NAME:Short name of the nodeset. E.g. ‘di’
    • FILE_NS:Path to the NodeSet2.xml file. Multiple values can be passed. These nodesets will be combined into one output.
    • [FILE_CSV]:Optional path to the .csv file containing the node ids, e.g. ‘OpcUaDiModel.csv’
    • [FILE_BSD]:Optional path to the .bsd file containing the type definitions, e.g. ‘Opc.Ua.Di.Types.bsd’. Multiple files can be passed which will all combined to one resulting code.
    • [BLACKLIST]:Blacklist file passed as --blacklist to the nodeset compiler. All the given nodes will be removed from the generated nodeset, including all the references to and from that node. The format is a node id per line. Supported formats: “i=123” (for NS0), “ns=2;s=asdf” (matches NS2 in that specific file), or recommended “ns=http://opcfoundation.org/UA/DI/;i=123” namespace index independent node id
    • [TARGET_PREFIX]:Optional prefix for the resulting targets. Default open62541-generator
  • Arguments taking multiple values:
    • [NAMESPACE_MAP]:Array of Namespace index mappings to indicate the final namespace index of a namespace uri when the server is started. This parameter is mandatory if FILE_CSV or FILE_BSD is set.
    • [IMPORT_BSD]:Optional combination of types array and path to the .bsd file containing additional type definitions referenced by the FILES_BSD files. The value is separated with a hash sign, i.e. ‘UA_TYPES#${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.Types.bsd’.
      Multiple files can be passed which will all be imported.
    • [DEPENDS]:Optional list of nodeset names on which this nodeset depends. These names must match any name from a previous call to this funtion. E.g. ‘di’ if you are generating the ‘plcopen’ nodeset

这里只需要注意:xx.NodeSet2.xml提供nodeset,.csv文件提供nodeid的定义,.bsd文件提供datatype的定义。


三 使用

首先搭建一个基本工程,这里不再赘述,工程里的CMakeLists.txt内容如下,

cmake_minimum_required(VERSION 3.5)

project(demo)

set(OPEN62541_VERSION "v1.3.4") # 设置open62541的版本号
set(UA_NAMESPACE_ZERO FULL CACHE STRINGS "xxx" FORCE) # UA_NAMESPACE_ZERO必须设置为FULL

# 必须要有这个,因为ua_generate_nodeset_and_datatypes由open62541提供
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/open62541)

# 必须设置变量open62541_TOOLS_DIR,否则报错,用户根据实际位置定义
set(open62541_TOOLS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/open62541/tools CACHE PATH "Path to the directory that contains the tooling of the stack")
# 必须设置变量open62541_NODESET_DIR,否则报错,用户根据实际位置定义
set(open62541_NODESET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/open62541/deps/ua-nodeset CACHE PATH "Path to the directory that contains the OPC UA schema repository")


# PLCopen and Robotics requires the full ns0 as basis
if(UA_NAMESPACE_ZERO STREQUAL "FULL")

    # Generate types and namespace for DI
    ua_generate_nodeset_and_datatypes(
        NAME "di"
        FILE_CSV "${open62541_NODESET_DIR}/DI/OpcUaDiModel.csv"
        FILE_BSD "${open62541_NODESET_DIR}/DI/Opc.Ua.Di.Types.bsd"
        NAMESPACE_MAP "2:http://opcfoundation.org/UA/DI/"
        FILE_NS "${open62541_NODESET_DIR}/DI/Opc.Ua.Di.NodeSet2.xml"
        INTERNAL
    )

    # generate PLCopen namespace which is using DI
    ua_generate_nodeset_and_datatypes(
        NAME "plc"
        # PLCopen does not define custom types. Only generate the nodeset
        FILE_NS "${open62541_NODESET_DIR}/PLCopen/Opc.Ua.PLCopen.NodeSet2_V1.02.xml"
        # PLCopen depends on the di nodeset, which must be generated before
        DEPENDS "di"
        INTERNAL
    )

    # Generate types and namespace for Robotics
    ua_generate_nodeset_and_datatypes(
        NAME "robotics"
        FILE_CSV "${open62541_NODESET_DIR}/Robotics/Opc.Ua.Robotics.NodeIds.csv"
        FILE_BSD "${open62541_NODESET_DIR}/Robotics/Opc.Ua.Robotics.Types.bsd"
        NAMESPACE_MAP "3:http://opcfoundation.org/UA/Robotics/"
        FILE_NS "${open62541_NODESET_DIR}/Robotics/Opc.Ua.Robotics.NodeSet2.xml"
        DEPENDS "di"
        INTERNAL
    )

endif()

本文例子生成3个nodeset:DI,PLCopen和Robotics,其中PLCopen和Robotics依赖DI,相关nodeset文件在open62541/deps/ua-nodeset里。注意要先生成DI的nodeset,因为它是被另外2个依赖。

操作步骤如下:

  1. 修改python脚本权限,第一节已经说过
  2. cd到build目录下执行cmake ..
  3. 生成DI的nodeset:make open62541-generator-ns-di, "di"就是NAME对应的值
  4. 生成PLCopen的nodeset:make open62541-generator-ns-plc,"plc"就是NAME对应的值
  5. 生成Robotics的nodeset:make open62541-generator-ns-robotics,"robotics"就是NAME对应的值

执行完毕之后,在build/src_generated/open62541下可以看到生成的.c/h文件,
在这里插入图片描述
过去使用nodeset_compiler.py只能生成namespace_xx_generated.c/h,而使用这个cmake命令还能生成xx_nodeids.h和types_xx_generated.c/h。

当然也可以根据需要来设置,如果需要生成xx_nodeids.h和types_xx_generated.c/h,那么就使用FILE_CSV和FILE_BSD来指定对应的文件,前提是这些csv和bsd文件事先存在;如果不需要,只要namespace_xx_generated.c/h,那么就可以删除FILE_CSV和FILE_BSD,例如Robotics,可以改成如下,

    # Generate namespace for Robotics
    ua_generate_nodeset_and_datatypes(
        NAME "robotics"
        FILE_NS "${open62541_NODESET_DIR}/Robotics/Opc.Ua.Robotics.NodeSet2.xml"
        DEPENDS "di"
        INTERNAL
    )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/339803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT可以写文章吗?来看看他对卷积神经网络的解释是否准确

文章目录提问chatGPT的回答第一次回答第二次回答结果提问 chatGPT的回答 在回答时候由于字数限制它不能一口气输出全部结果,此时可以采用两种方法让它继续输出: 复制它的上一步回答给它,它会接着回复直接发送继续,它也会接着回复…

体验100问 | 「体验管理」是一个正确的职业选择吗?

Guofu 第 84⭐️ 篇原创干货分享(点击👆🏻上方卡片关注我,加⭐️星标⭐️~)Q003:体验管理是一个正确的职业选择吗?🤔 龙国富说: 1、职业选择应该去寻求“不变”的事情这件事其实在我…

DS期末复习卷(三)

选择题 某数据结构的二元组形式表示为A(D&#xff0c;R)&#xff0c;D{01&#xff0c;02&#xff0c;03&#xff0c;04&#xff0c;05&#xff0c;06&#xff0c;07&#xff0c;08&#xff0c;09}&#xff0c;R{r}&#xff0c;r{<01&#xff0c;02>&#xff0c;<01&a…

淘宝API接口系列,获取购买到的商品订单列表,卖出的商品订单列表,订单详情,订单物流,买家信息,收货地址列表,买家token

custom自定义API操作buyer_order_list获取购买到的商品订单列表buyer_order_detail获取购买到的商品订单详情buyer_order_express获取购买到的商品订单物流buyer_address_list收货地址列表buyer_address_add添加收货地址buyer_info买家信息buyer_token买家tokenseller_order_li…

类的继承

类的继承&#xff1a;一个类继承另一个类&#xff0c;自动拥有这个类的属性和方法&#xff0c;类似于包含与被包含的关系。被继承的类称为父类--子类则是继承父类的类。一个父类可以有多个子类&#xff1b;一个子类可以有多个父类&#xff08;多继承&#xff09;问题创建子类时…

CUDA中的流序内存分配

文章目录CUDA中的流序内存分配1. Introduction2. Query for Support3. API Fundamentals (cudaMallocAsync and cudaFreeAsync)4. Memory Pools and the cudaMemPool_t注意&#xff1a;设备的内存池当前将是该设备的本地。因此&#xff0c;在不指定内存池的情况下进行分配将始终…

测试开发之Django实战示例 第七章 创建电商网站

第七章 创建电商网站在上一章里&#xff0c;创建了用户关注系统和行为流应用&#xff0c;还学习了使用Django的信号功能与使用Redis数据库存储图片浏览次数和排名。这一章将学习如何创建一个基础的电商网站。本章将学习创建商品品类目录&#xff0c;通过session实现购物车功能。…

java流浪动物救助系统(毕业设计)

项目类型&#xff1a;Java web项目/Java EE项目&#xff08;非开源&#xff09; 项目名称&#xff1a;基于JSPServlet的流浪动物救助网站[dwjz_web] 进行源码获取 用户类型&#xff1a;双角色&#xff08;爱心人士、管理员&#xff09; 项目架构&#xff1a;B/S架构 设计思…

全景拼接python旗舰版

前言在这个项目中&#xff0c;您将构建一个管道&#xff0c;将几幅图像拼接成一个全景图。您还将捕获一组您自己的图像来报告最终的结果。步骤1 特征检测与描述本项目的第一步是对序列中的每幅图像分别进行特征检测。回想一下我们在这个类中介绍过的一些特征探测器&#xff1a;…

KDS安装步骤

KDS kinetis design studio 软件 第一步官网(https://www.nxp.com/ 注册账号下载set成功下载软件。 随着AI&#xff0c;大数据这些技术的快速发展&#xff0c;与此有关的知识也普及开来。如何在众多网站中寻找最有价值的信息&#xff0c;如何在最短的时间内获得最新的技…

家政服务小程序实战教程09-图文卡片

小程序还有一类需求就是展示服务的列表&#xff0c;我们这里用图文卡片组件来实现&#xff0c;我们先要添加一个标题&#xff0c;使用网格布局来实现 第一列添加一个文本组件&#xff0c;第二列添加一个图标组件 修改文本组件的文本内容&#xff0c;设置外边距 设置第二列的样式…

PHP session反序列化漏洞

session请求过程&#xff1a; 当第一次访问网站时&#xff0c;Seesion_start()函数就会创建一个唯一的Session ID&#xff0c;并自动通过HTTP的响应头&#xff0c;将这个Session ID保存到客户端Cookie中。同时&#xff0c;也在服务器端创建一个以Session ID命名的文件&#xff…

Netty网络应用基础

文章目录前言一、基础概念狭义网络网络应用工程库二、总体框架三、应用分层总结前言 开始之前&#xff0c;咱们先澄清一些基础概念、总体框架和应用分层&#xff0c;避免在后续的讨论中给大家带来误解。 一、基础概念 狭义网络 常规Java后端开发中应用到的计算机网络&#x…

【ArcGIS Pro二次开发】(2):创建一个Add-in项目

Add-In即模块加载项&#xff0c;是一种能够快速扩展桌面应用程序功能的全新扩展方式。 一、创建新项目 1、打开VS2002&#xff0c;选择创建新项目。 2、在搜索框中输入“arcgis pro”&#xff0c;在搜索结果中选择【ArcGIS Pro 模块加载项】创建项目&#xff0c;注意选择语言应…

OpenSSL发布修复程序以解决多个安全漏洞!

OpenSSL 项目已发布修复程序以解决多个安全漏洞&#xff0c;包括开源加密工具包中的一个高严重性错误&#xff0c;该错误可能会使用户遭受恶意攻击。 国际知名白帽黑客、东方联盟创始人郭盛华表示&#xff0c;该问题被追踪为CVE-2023-0286&#xff0c;与类型混淆有关&#xff…

激光雷达相关技术

一、参考资料 17篇点云处理综述-点云语义分割、点云物体检测、自动驾驶中的点云处理…… #三维视觉 #点云 3D点云数据标准 自动驾驶之心 自动驾驶之心-专栏 二、重要信息 1. 黑车检测难题 从2018年至今&#xff0c;高线数机械式激光雷达的测距能力一直停留在200米10%反…

Fastjson 1.83漏洞利用猜想

0x00 前言 这篇是去年五月发到i春秋的~ 在不久前fastjson<1.2.83又爆出来了新的问题,详细内容可以参考 https://github.com/alibaba/fastjson/wiki/security_update_20220523,这篇文章主要是抛转引玉,写一种可能的利用思路,详细的利用链可能要等大佬们来给出了。 文内…

【LeetCode】动态规划总结

动态规划解决的问题 动态规划和贪心的区别&#xff1a; 动态规划是由前一个状态推导出来的&#xff1b; 贪心是局部直接选最优的。 动态规划解题步骤 状态定义&#xff1a;确定dp数组以及下标的含义状态转移方程&#xff1a;确定递推公式初始条件&#xff1a;dp如何初始化遍历…

java学习记录day7

类与对象 对象数组与管理 对象数组就是数组里的每个元素都是对象&#xff1a;House[] home new House[10];使用对象数组实现多个House的管理。 拓展:数组的扩充: 扩充原来数组的一半&#xff1a; public void add(House[] home){int newLen home.length*3/21;home Array…

ARM uboot源码分析3-启动第一阶段

一、start.S 解析7 总结回顾&#xff1a;lowlevel_init.S 中总共做了哪些事情&#xff1a; 检查复位状态、IO 恢复、关看门狗、开发板供电锁存、时钟初始化、DDR 初始化、串口初始化并打印 ‘O’、tzpc 初始化、打印 ‘K’。 其中值得关注的&#xff1a;关看门狗、开发板供电锁…