open62541之概述
open62541 是一个用 C 语言编写的免费、开源的OPC UA (OPC 统一架构 / IEC 62541)实现。它提供了一个全功能的 SDK,用于构建 OPC UA 服务器和客户端,以及发布-订阅(PubSub)通信——所有这些都集成在单一且与平台无关的库中。无论你是在工厂车间连接工业设备,还是将安全的机器对机器通信嵌入到微控制器中,open62541 都能将完整的 OPC UA 协议栈以足够小的体积交付,甚至能直接在裸机目标上运行。
什么是 OPC UA?
OPC 统一架构是一种在IEC 62541系列标准中定义的工业通信协议。它定义了四个相互交织的层级,open62541 将其作为一个内聚的 SDK 共同实现:
- 协议层— 一种基于 TCP(或 HTTP/SOAP)构建的异步消息交换协议,被组织为安全通道、会话和原始连接。
- 类型系统— 一种丰富的数据类型系统,具有二进制和 JSON 编码方案,涵盖 25 种内置类型以及任意复杂的结构体、数组和联合体。
- 信息模型— 一种结合了面向对象与语义三元组关系(节点-引用-节点)的元模型,能够实现数据的自描述表示。
- 服务层— 37 种用于浏览、读写、调用方法、管理订阅等的标准服务——每种服务均定义为类型化的请求/响应消息对。
OPC UA 由 OPC 基金会负责维护,该基金会同时还推动伴随规范的制定,将这些特定领域的概念(机器人、机床、能源管理)转化为可复用的 OPC UA 信息模型。
高层架构
open62541 的架构采用分层设计,其核心是一个以插件为中心的抽象边界。所有与平台相关的及算法上可替换的功能都通过明确定义的插件接口暴露出来,这使得核心库保持高度可移植性,并且除 C99 标准库外没有任何其他依赖。
公共 API 表面被有意设计得极简。开发者通过三个主要的入口头文件——server.h、client.h和pubsub.h——与库进行交互,而types.h和common.h则提供共享的数据类型和状态码。位于include/open62541/plugin/下的插件头文件定义了加密、事件循环、节点存储、访问控制、日志记录和历史数据的扩展点。
项目结构一览
代码仓库的组织结构清晰地分离了公共接口、核心逻辑、可替换插件、平台移植和构建工具:
open62541/ ├── include/open62541/ 📤 公共 API 头文件 (server, client, pubsub, types) │ └── plugin/ 📤 插件接口头文件 ├── src/ 🔧 核心库 (除 C99 外零外部依赖) │ ├── server/ 🔧 服务器服务、会话、订阅、NS0 │ ├── client/ 🔧 客户端连接、订阅、高级 API │ ├── pubsub/ 🔧 发布-订阅协议实现 │ └── util/ 🔧 事件过滤器解析器、内部工具 ├── plugins/ 🔌 默认插件实现 (加密、日志、节点存储) ├── arch/ 🖥️ 特定平台的事件循环移植 (POSIX, Win32, Zephyr, FreeRTOS) ├── deps/ 📦 第三方依赖 (mdnsd, mqtt-c, libc_time 等) ├── examples/ 📝 教程与示例应用 ├── tools/ 🛠️ 代码生成、证书、CI 脚本、代码合并 ├── tests/ ✅ 单元测试、模糊测试、加密测试、集成测试 └── doc/ 📖 Sphinx 文档源码这种分离确保了src/中的核心库仅需 C99 标准库即可干净地编译。其他所有功能——TLS 后端、网络 I/O、证书存储、发现多播——都是在构建时通过选定的插件注入的。
支持的特性
open62541 实现了全面的 OPC UA 特性集。当前的开发版本v1.5.0-rc2在已获认证的 v1.4 基线之上,扩展了 PubSub 改进、新的实时 PubSub 模型以及类型化的异步客户端回调。
通信栈
| 类别 | 特性 | 状态 |
|---|---|---|
| 编码 | OPC UA 二进制 | ✅ 已支持 |
| OPC UA JSON (v1.05 规范) | ✅ 已支持 | |
| OPC UA XML | 🌙 部分支持 | |
| 传输 | UA-TCP 安全通道二进制 | ✅ 已支持 |
| 加密 | 无 | ✅ 已支持 |
| Basic128Rsa15 | ✅ 已支持 | |
| Basic256 | ✅ 已支持 | |
| Basic256Sha256 | ✅ 已支持 | |
| Aes256Sha256RsaPss | ✅ 已支持 | |
| 身份验证 | 匿名 | ✅ 已支持 |
| 用户名 / 密码 | ✅ 已支持 | |
| X.509 证书 | ✅ 已支持 | |
| 加密后端 | mbedTLS | ✅ 已支持 |
| OpenSSL | ✅ 已支持 | |
| LibreSSL | 🧪 实验性支持 |
服务器服务
| 服务集 | 关键服务 | 状态 |
|---|---|---|
| 发现 | FindServers、GetEndpoints、RegisterServer | ✅ |
| 安全通道 | Open / Close SecureChannel | ✅ |
| 会话 | Create / Close / Activate / Cancel | ✅ |
| 节点管理 | Add/Delete Nodes & References | ✅ |
| 视图 | Browse、TranslateBrowsePaths | ✅ |
| 属性 | Read、Write、HistoryRead/Update | ✅ |
| 方法 | Call | ✅ |
| 被监控项 | Create / Delete / Modify / SetTriggering | ✅ |
| 订阅 | Create / Modify / Publish / Transfer | ✅ |
| 订阅 | DataChange、Event 被监控项、过滤器 | ✅ |
| 发现 | 本地发现服务器、mDNS 多播 | ✅ |
发布-订阅 (PubSub)
| 特性 | 状态 |
|---|---|
| 二进制编码 (UADP) | ✅ |
| JSON 编码 | ✅ |
| 消息加密 / 解密 | ✅ |
| UDP / 多播传输 | ✅ |
| 以太网传输 | ✅ |
| MQTT 传输 | ✅ |
| 运行时发布者与订阅者配置 | ✅ |
| 安全密钥服务 (SKS) 模型 | ✅ |
| 实时 PubSub 模型 (偏移表、自定义状态机) | ✅ 新增 |
客户端 SDK
客户端支持所有 OPC UA 服务,并提供同步和异步两种 API。订阅通过事件循环在后台处理。client_highlevel.h中的高级 API 为常见的读写、浏览和调用操作提供了便捷的封装。
平台支持
open62541 被设计为可以运行在任何地方——从功能完备的 Linux 服务器到资源受限的微控制器。特定于平台的代码被隔离在事件循环插件架构之后,并为主要目标平台提供了移植版本:
| 平台 | 架构 | 事件循环实现 |
|---|---|---|
| Linux / macOS / BSD | POSIX | arch/posix/— epoll/kqueue TCP、UDP、以太网、中断 |
| Windows | Win32 | 默认基于 Winsock 的事件循环 |
| Zephyr RTOS | Zephyr | arch/zephyr/— 原生 Zephyr 网络 |
| FreeRTOS + lwIP | freertos-lwip | arch/freertos/+arch/lwip/— lwIP TCP/UDP |
| POSIX + lwIP | posix-lwip | 混合 POSIX 时钟 + lwIP 网络 |
构建配置
open62541 使用CMake作为其构建系统,并提供大量选项以便你根据具体用例定制库。以下列出了最常用的选项:
| CMake 选项 | 默认值 | 描述 |
|---|---|---|
UA_ENABLE_AMALGAMATION | OFF | 将库合并为单个open62541.c/.h以便于集成 |
UA_ENABLE_ENCRYPTION | OFF | 加密后端:MBEDTLS、OPENSSL或LIBRESSL |
UA_ENABLE_SUBSCRIPTIONS | ON | 启用订阅和被监控项支持 |
UA_ENABLE_SUBSCRIPTIONS_EVENTS | ON | 启用事件监控 |
UA_ENABLE_HISTORIZING | ON | 启用历史数据访问(客户端和服务器) |
UA_ENABLE_DISCOVERY | ON | 启用本地发现服务器 (LDS) |
UA_ENABLE_DISCOVERY_MULTICAST | OFF | mDNS 发现:MDNSD或AVAHI |
UA_ENABLE_JSON_ENCODING | ON | 启用 JSON 编码 (v1.05 规范) |
UA_ENABLE_PUBSUB | OFF | 启用 PubSub 协议支持 |
UA_MULTITHREADING | 0(嵌入式) /100(桌面端) | 线程安全级别(≥100 会启用内部互斥锁) |
UA_LOGLEVEL | 100 | 最低日志级别:TRACE(100) → FATAL(600) |
