news 2026/3/6 2:39:58

OpenPLC Runtime v4 架构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenPLC Runtime v4 架构

OpenPLC Runtime v4 架构

概述

OpenPLC Runtime v4 是一个双进程系统,通过一个用于 OpenPLC Editor 通信的 REST API 服务器和一个实时 PLC 执行引擎来提供工业自动化能力。

系统组件

1. REST API 服务器进程 (Python/Flask)

REST API 服务器是一个基于 Flask 的 HTTPS 应用程序,提供以下功能:

  • 用于 PLC 控制和管理的REST API
  • 用于实时调试的WebSocket 接口
  • 程序编译编排
  • 用户认证和安全
  • 运行时进程管理

关键细节:

  • 端口:8443 (HTTPS)
  • 位置:webserver/app.py
  • TLS:自签名证书(自动生成)
  • 认证:基于 JWT

2. PLC 运行时核心 (C/C++)

PLC 运行时是一个实时执行引擎,具备以下功能:

  • 以确定性的时序执行已编译的 PLC 程序
  • 通过插件驱动程序管理 I/O 操作
  • 为变量检查提供调试接口
  • 通过看门狗监控系统健康状态
  • 维护生命周期状态(INIT, RUNNING, STOPPED, ERROR, EMPTY)

关键细节:

  • 可执行文件:build/plc_main
  • 位置:core/src/plc_app/
  • 调度:SCHED_FIFO(实时优先级)
  • 要求:root 权限或 CAP_SYS_NICE 能力

进程间通信

两个进程通过 Unix 域套接字进行通信:

PLC 运行时套接字

  • 路径:/run/runtime/plc_runtime.socket
  • 目的:命令与控制(启动、停止、状态查询)
  • 协议:基于文本的命令,附带同步响应
  • 实现:core/src/plc_app/unix_socket.c(服务器端),webserver/unixclient.py(客户端)

日志套接字

  • 路径:/run/runtime/log_runtime.socket
  • 目的:将日志从 PLC 运行时实时流式传输到 REST API 服务器
  • 实现:core/src/plc_app/utils/log.c

PLC 生命周期状态

PLC 运行时维护以下状态:

EMPTY → INIT → RUNNING ⟷ STOPPED → ERROR

状态描述

  • EMPTY: 未加载 PLC 程序
  • INIT: 程序已加载,正在初始化
  • RUNNING: 正在主动执行扫描周期
  • STOPPED: 程序已加载但未执行
  • ERROR: 可恢复的错误状态

状态管理器:core/src/plc_app/plc_state_manager.c

线程模型

REST API 服务器线程

  1. 主 Flask 线程:处理来自 OpenPLC Editor 的 HTTP/HTTPS 请求
  2. WebSocket 线程:管理来自 OpenPLC Editor 的调试连接
  3. 编译线程:异步运行构建过程
  4. 运行时管理器线程:监控 PLC 运行时进程

PLC 运行时线程

  1. 主线程:初始化和信号处理
  2. Unix 套接字线程:接收和处理命令
  3. PLC 周期线程:以实时优先级执行扫描周期
  4. 统计线程:记录性能指标
  5. 看门狗线程:监控心跳,并在挂起时终止进程
  6. 日志线程:管理日志套接字连接

实时执行

PLC 周期线程以 SCHED_FIFO 优先级运行,以确保确定性的时序:

  1. 读取输入:插件驱动程序从硬件读取
  2. 执行逻辑:运行已编译的 PLC 程序 (ext_config_run__())
  3. 写入输出:插件驱动程序写入硬件
  4. 休眠至下一周期:使用clock_nanosleep()实现精确时序

时序配置:

  • 扫描周期持续时间:由ext_common_ticktime__定义(通常为 50ms)
  • 跟踪的时序统计:最小/最大/平均扫描时间、周期时间、延迟、超时

插件系统

运行时支持动态加载的插件以实现硬件 I/O:

  • 插件类型:Python 和 C/C++
  • 配置plugins.conf文件
  • 虚拟环境:每个插件具有独立的 Python 依赖环境
  • 缓冲区保护:在扫描周期内通过互斥锁保护的 I/O 缓冲区

文档:参见docs/PLUGIN_VENV_GUIDE.mdcore/src/drivers/README.md

安全架构

TLS/HTTPS

  • 首次运行时生成自签名证书
  • 证书文件:webserver/certOPENPLC.pem,webserver/keyOPENPLC.pem
  • 主机名验证以防止注入攻击

认证

  • 用于 API 和 WebSocket 访问的 JWT 令牌
  • 密钥存储在/var/run/runtime/.env
  • 用于密码哈希的 256 位加密胡椒

文件上传安全

  • ZIP 文件验证(路径遍历、大小限制、压缩率)
  • 禁止的扩展名:.exe, .dll, .sh, .bat, .js, .vbs, .scr
  • 最大文件大小:单个文件 10 MB,总计 50 MB
  • 解压过程中剥离 macOS 元数据

实现:webserver/plcapp_management.py,webserver/credentials.py

数据持久化

运行时数据目录

位置:/var/run/runtime/

包含:

  • .env- 环境变量(JWT 密钥、数据库 URI、胡椒)
  • restapi.db- 用于用户账户的 SQLite 数据库
  • 套接字文件(运行时创建)

Docker 卷

在 Docker 中运行时,将/var/run/runtime挂载为命名卷以实现持久化:

dockerrun -v openplc-runtime-data:/var/run/runtime...

看门狗系统

看门狗通过跟踪plc_heartbeat原子变量来监控 PLC 健康状态:

  • 更新频率:每个扫描周期
  • 超时:2 秒内无更新
  • 动作:如果 PLC 无响应,则终止进程
  • 状态感知:仅在 RUNNING 状态下监控

实现:core/src/plc_app/utils/watchdog.c

性能监控

运行时跟踪详细的时序统计信息:

  • 扫描计数:执行的总周期数
  • 扫描时间:执行 PLC 逻辑花费的时间
  • 周期时间:每个周期的总时间(包括休眠)
  • 周期延迟:与目标时序的偏差
  • 超时:超过目标持续时间的周期

统计信息通过统计线程每 5 秒记录一次。

错误处理

REST API 服务器

  • 构建失败在BuildStatus枚举中跟踪
  • 编译日志流式传输到 OpenPLC Editor
  • 运行时断开连接时的优雅降级

PLC 运行时

  • 对 SIGINT 进行信号处理(优雅关闭)
  • 执行前验证状态转换
  • 插件故障与核心运行时隔离
  • 看门狗确保进程在挂起时终止

目录结构

openplc-runtime/ ├── webserver/ # Flask REST API 服务器 │ ├── app.py # 主应用程序入口 │ ├── restapi.py # REST API 蓝图 │ ├── debug_websocket.py # WebSocket 调试接口 │ ├── unixclient.py # Unix 套接字客户端 │ ├── plcapp_management.py # 构建编排 │ ├── runtimemanager.py # 运行时进程控制 │ ├── credentials.py # TLS 证书生成 │ └── config.py # 配置管理 ├── core/ │ ├── src/plc_app/ # PLC 运行时源代码 │ │ ├── plc_main.c # 主入口点 │ │ ├── plc_state_manager.c/h # 状态管理 │ │ ├── unix_socket.c/h # IPC 服务器 │ │ ├── debug_handler.c/h # 调试协议 │ │ └── utils/ # 实用工具(日志、看门狗、计时) │ ├── src/drivers/ # 插件驱动系统 │ └── generated/ # 生成的 PLC 代码(运行时) ├── scripts/ # 构建和管理脚本 │ ├── compile.sh # 编译 PLC 程序 │ ├── compile-clean.sh # 清理和重命名库 │ └── manage_plugin_venvs.sh # 插件虚拟环境管理 ├── build/ # 编译输出 │ ├── plc_main # 编译的运行时可执行文件 │ └── libplc_*.so # 编译的 PLC 程序库 └── venvs/ # Python 虚拟环境 ├── runtime/ # Web 服务器虚拟环境 └── {plugin_name}/ # 每个插件的虚拟环境

部署模式

原生 Linux

  • 通过install.sh直接安装
  • 通过包管理器安装系统依赖项
  • 使用start_openplc.sh启动运行时

Docker 容器

  • 官方镜像:ghcr.io/autonomy-logic/openplc-runtime:latest
  • 多架构支持:amd64, arm64, armv7
  • 需要为/var/run/runtime提供持久化卷
  • 暴露端口 8443 用于 HTTPS 访问

开发

  • 使用 CMake 进行本地构建
  • 包含测试环境的开发容器
  • 用于代码质量的预提交钩子

相关文档

  • 编辑器集成 - OpenPLC Editor 如何连接到运行时
  • 编译流程 - 构建流水线详情
  • API 参考 - REST 端点和响应
  • 调试协议 - WebSocket 调试接口
  • 插件系统 - 硬件 I/O 插件
  • 安全 - 认证和文件验证
  • Docker 部署 - 容器使用
  • 故障排除 - 常见问题
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 7:52:16

我用的是 Arch BTW”到底算不算吹牛?

在 Linux 圈子里,有一句话几乎已经成了文化符号: “I use Arch BTW.” 它既是炫耀,也是自嘲; 既是身份认同,也是社区玩梗。 但问题来了—— 如果你用的是 EndeavourOS、CachyOS、Manjaro,甚至是装了 Archinstall 的 Arch,那你到底“配不配”说这句话? 这看似是个玩…

作者头像 李华
网站建设 2026/3/4 6:32:34

AI工具评测:效率革命的实战地图

2026年自动化测试领域迎来AI深度整合,工具评测类内容占据流量榜首。爆款核心在于量化对比与场景化解决方案: 性能实测数据驱动决策:热门文章通过横向评测Selenium智能插件与Cypress云环境适应性(如API超时自愈率提升35%&#xff0…

作者头像 李华
网站建设 2026/3/4 12:40:01

React Native鸿蒙:TabView标签页视图

React Native鸿蒙:TabView标签页视图详解 摘要 本文深入探讨如何在OpenHarmony 6.0.0 (API 20)平台上使用React Native 0.72.5实现高性能的TabView标签页视图。通过分析React Native与OpenHarmony的集成机制,结合TabView组件的核心原理,详细…

作者头像 李华
网站建设 2026/3/4 11:48:13

在OpenHarmony上用React Native:CollapsibleTab折叠标签页

在OpenHarmony上用React Native:CollapsibleTab折叠标签页实战指南 摘要 本文将深入探讨如何在OpenHarmony 6.0.0 (API 20)平台上使用React Native 0.72.5实现高级的CollapsibleTab折叠标签页组件。通过详细的架构分析、适配要点和实战案例,您将掌握&a…

作者头像 李华
网站建设 2026/3/3 22:10:05

springboot基于java web的宠物托管系统(源码+文档+运行视频+讲解视频)

文章目录 系列文章目录目的前言一、详细视频演示二、项目部分实现截图三、技术栈 后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试 四、代码参考 源码获取 目的 宠物托管系统作为宠物服务行业的重要组成部分,对于满足宠物主人需求、保障宠物健康具有…

作者头像 李华