
open62541 是 OPC UA开放平台通信统一架构的开源实现旨在从嵌入式微控制器到全尺寸工业服务器的各种环境中运行。系统架构概览本项目遵循严格的分层架构每一层都向其上层暴露定义良好的接口且仅依赖于其下层的抽象。这种分离机制支持选择性编译——你可以通过 CMake 标志在构建时剔除整个子系统——从而确保最小的嵌入式内存占用能够排除从 Pub/Sub 到加密的所有非必要功能。三个水平带——核心实现层、插件系统层和平台抽象层——构成了架构的骨干。请注意核心模块完全通过include/open62541/plugin/中的接口头文件与插件进行通信从不直接链接到特定的实现。正是这种间接性使得你可以将默认的 zip-tree NodeStore 替换为自定义后端或者用 OpenSSL 替代 mbedTLS 进行加密操作而无需修改任何一行核心代码。源码树布局代码仓库的组织方式确保每个顶层目录都具有单一且明确的职责。下表将每个目录映射到了其对应的架构角色。目录架构角色核心内容src/OPC UA 核心逻辑服务器服务、客户端引擎、PubSub 管理器、安全通道、类型系统include/open62541/公共 C API 与插件接口server.h,client.h,pubsub.h,types.h,plugin/*.hplugins/默认插件实现配置构建器、访问控制、NodeStore (ziptree)、加密后端、历史数据、日志arch/特定于平台的 EventLoop 与时钟POSIX、Win32、Zephyr、FreeRTOS、lwIP 适配器deps/捆绑的第三方依赖JSON/UBJSON 解析器、mDNS 响应器、MQTT 客户端、Base64、XML 解析器tools/构建基础设施与代码生成CMake 模块、数据类型生成器、节点集编译器、证书工具examples/参考应用程序极简服务器/客户端教程、加密、发现、PubSub、自定义数据类型tests/单元与集成测试套件模糊测试目标、多线程测试、网络回放、加密测试核心实现层 (src/)src/目录将 OPC UA 功能分解为四个内聚模块以及一个共享的类型子系统。服务器模块src/server/是最大的模块包含了完整的 NS0 引导逻辑、所有 OPC UA 服务实现发现、节点管理、订阅、被监控项、方法、视图、会话管理以及异步操作处理。客户端模块src/client/从调用者的视角映射了服务器的关注点连接生命周期、订阅管理和异步服务调度。PubSub 模块src/pubsub/独立于客户端-服务器路径实现 OPC UA PubSub 传输模型包括发布者组、订阅者组、数据集写入器/读取器以及网络消息编码器。在共享层面ua_securechannel.c和ua_securechannel_crypto.c实现了客户端和服务器共同依赖的消息安全层而ua_types*.c则提供了包含二进制、JSON 和 XML 编码的完整类型系统。公共 API (include/open62541/)公共头文件是你的应用程序唯一应该包含的文件。它们被设计为能够通过tools/amalgamate.py合并成单个头文件open62541.h以便于分发。头文件层次结构被有意设计得很扁平types.h定义了所有的 OPC UA 数据类型并被server.h、client.h和pubsub.h传递包含。插件接口位于plugin/目录下最终用户不需要直接包含它们——它们仅供插件实现和核心模块使用。服务器结构定义在内部头文件中的UA_Server结构体是所有服务器端操作的核心调度器。它聚合了服务器配置、会话注册表、安全通道列表、命名空间表、订阅管理器、异步操作管理器、服务器组件树以及 GDS全局发现服务器证书管理器。当启用多线程时一个可选的互斥锁会被条件编译。一个关键的架构决策是ServerComponent子系统。服务器组件如 PubSub 传输层或发现管理器具有明确的生命周期——start、stop、clear——并被存储在按数字标识符索引的 zip-tree 中。它们只能在父服务器已经运行时启动并且在所有组件都达到STOPPED状态之前服务器不会完全关闭。这确保了在复杂部署环境中干净利落的拆卸顺序。客户端结构UA_Client结构体从远程访问的视角映射了服务器的关注点。它管理着一个UA_SecureChannel、一个带有其身份验证状态的会话、包含被监控项的活跃订阅列表、挂起的异步服务调用队列以及用于自动进行 URI 到索引映射的内部命名空间表。客户端不会自行产生线程——相反用户必须定期调用UA_Client_run_iterate或驱动外部的UA_EventLoop来处理网络 I/O、订阅保活以及安全通道续期。插件架构插件系统是 open62541 的主要可扩展机制。每个在不同部署之间可能产生差异的主要子系统——安全、访问控制、节点存储、日志、历史数据、网络、证书管理——都是通过在include/open62541/plugin/中定义的函数指针接口进行访问的。默认实现位于plugins/目录下除非被明确替换否则会被 CMake 构建系统自动链接。插件接口头文件默认实现用途SecurityPolicyplugin/securitypolicy.hplugins/crypto/mbedtls/,openssl/对称/非对称加密、签名验证AccessControlplugin/accesscontrol.hplugins/ua_accesscontrol_default.c会话身份验证、基于角色的权限NodeStoreplugin/nodestore.hplugins/ua_nodestore_ziptree.c信息模型节点的存储与检索EventLoopplugin/eventloop.harch/posix/,arch/zephyr/,arch/lwip/统一的 I/O 多路复用、定时器、连接管理Loggerplugin/log.hplugins/ua_log_stdout.c,ua_log_syslog.c带有严重性级别的结构化日志输出HistoryDatabaseplugin/historydatabase.hplugins/historydata/历史节点的历史数据访问CertificateGroupplugin/certificategroup.hplugins/crypto/ua_certificategroup_*.c证书信任列表管理NodeStore 插件值得特别关注。默认实现使用 zip-tree一种概率平衡树来存储信息模型中的所有节点。ReferenceType 系统通过位域表示进行了优化其中每个ReferenceTypeNode都包含一个预计算的、由其所有子类型组成的位域从而极大地加速了浏览操作。ReferenceType 的最大数量被限制为 128 个四个 32 位字前 18 个索引保留给标准的 OPC UA 引用类型如HierarchicalReferences、HasComponent和HasProperty。编译时功能配置open62541 使用由 CMake 选项驱动并通过include/open62541/config.h.in具体化的编译时配置系统。这不是运行时配置——它决定了哪些代码路径会被编译进最终二进制文件中。功能标志控制着整个子系统核心协议功能:UA_ENABLE_METHODCALLS,UA_ENABLE_NODEMANAGEMENT,UA_ENABLE_SUBSCRIPTIONS,UA_ENABLE_SUBSCRIPTIONS_EVENTS,UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS,UA_ENABLE_HISTORIZING,UA_ENABLE_QUERY。传输与编码:UA_ENABLE_PUBSUB,UA_ENABLE_PUBSUB_INFORMATIONMODEL,UA_ENABLE_PUBSUB_FILE_CONFIG,UA_ENABLE_JSON_ENCODING,UA_ENABLE_XML_ENCODING,UA_ENABLE_MQTT。安全:UA_ENABLE_ENCRYPTION在选择 mbedTLS、OpenSSL 或 LibreSSL 时自动设置,UA_ENABLE_DISCOVERY,UA_ENABLE_DISCOVERY_MULTICAST。平台:UA_ARCHITECTURE_POSIX,UA_ARCHITECTURE_WIN32,UA_ARCHITECTURE_ZEPHYR,UA_ARCHITECTURE_LWIP,UA_ARCHITECTURE_FREERTOS。构建模式:UA_ENABLE_AMALGAMATION单文件输出,UA_MULTITHREADING01-99 表示部分线程安全100 表示带互斥锁的完全线程安全。内存占用优化: 禁用了订阅、PubSub、历史数据和加密的极简嵌入式构建编译出的 ROM 占用可以控制在 100 KB 以下。务必从你真正需要的功能标志开始然后逐步增量添加——每一个启用的标志都会引入相应的类型定义、服务实现和插件依赖。平台抽象层arch/目录提供了 open62541 与平台无关的核心与主机操作系统或 RTOS 之间的粘合层。每个架构子目录提供EventLoop 实现与平台原生的 I/O 多路复用机制集成POSIX 上的 epoll/kqueueWin32 上的 WaitForMultipleObjectsZephyr 事件循环。连接管理器用于 TCP 和 UDP 传输并可选地支持以太网和中断处理。时钟和时间函数用于单调时钟和挂钟时间。架构选择发生在 CMake 配置阶段。可用的架构包括posixLinux、macOS、BSD、win32、zephyr、freertos-lwip和posix-lwip。跨架构共享的通用 EventLoop 逻辑位于arch/common/中包括定时器子系统和 MQTT 连接管理。架构EventLoop 后端传输方式目标平台posixepoll / kqueueTCP, UDP, ETH, Interrupt桌面级 Linux/macOS/BSDwin32WaitForMultipleObjectsTCP, UDP, ETH, InterruptWindows 桌面/服务器zephyrZephyr 原生TCP, UDPZephyr RTOS (NXP, Nordic 等)freertos-lwip自定义轮询TCP, UDPFreeRTOS lwIP 协议栈posix-lwipepoll lwIP 套接字TCP, UDP搭载 lwIP 的 POSIX 主机依赖管理open62541 在deps/目录下精心挑选并内置了一组依赖项以最大程度减少外部构建要求。这些依赖项不会在系统范围内安装——它们会被直接编译进 open62541 库中。核心依赖包括依赖项源文件使用者JSON/UBJSON 解析器cj5.c/hJSON 编码、PubSub JSON 配置Base64 编解码器base64.c/h证书处理、XML 编码mDNS 响应器mdnsd/多播发现MQTT 客户端mqtt-c/基于 MQTT 传输的 PubSubXML 解析器yxml.c/hXML 编码与节点集加载Zip-treeziptree.c/hNodeStore、MonitoredItems、ServerComponents自定义 printfmp_printf.c/h对嵌入式友好的格式化输出数字解析parse_num.c/h,itoa.c/h,dtoa.c/h配置解析、数据类型转换零外部依赖构建: 除了 C99 编译器和 CMake 之外open62541 可以构建其整个技术栈——包括通过内置的 mbedTLS 子模块实现 TLS 加密——而无需依赖 C 标准库以外的任何系统库。这使得它极其适合在物理隔离或资源高度受限的构建环境中使用。数据流请求在服务器中的旅程理解单个 OPC UA 请求在服务器中穿行的路径有助于阐明所有架构部件是如何相互关联的。此序列中的每个箭头都跨越了一个架构边界。ConnectionManager 存在于arch/中SecureChannel 和服务存在于src/中而 SecurityPolicy、AccessControl 和 NodeStore 则是插件。这意味着这些组件中的任何一个都可以被独立替换而无需修改其他组件。合并与单文件分发tools/amalgamate.py脚本会将所有选定的源文件、头文件以及生成的类型定义合并到单一的open62541.c和open62541.h文件对中。这由UA_ENABLE_AMALGAMATIONCMake 选项控制。合并极大地简化了集成到无法使用 CMake 的项目中的过程——只需将这两个文件放入你的构建系统即可。合并后的输出会遵循所有的功能标志仅包含已启用功能的代码。