aiDgePLC --- IEC61131-3 ST PLC 虚拟机调试与运行环境
st 虚拟机开源地址:https://gitee.com/galaxy_0/stvm
什么是 aiDgePLC?
aiDgePLC 是一个轻量级、可嵌入的 IEC 61131-3 ST(结构化文本)调试与运行环境 ,
基于 STVM 虚拟机构建,为自动化工程师和嵌入式开发者提供:
- 🖥️ 交互式 CLI 调试器 --- 像使用 GDB 一样调试 PLC 程序
- 🌐 WebSocket 调试服务器 --- 浏览器/远程客户端实时调试
- 📝 源码行号断点 --- 直接在 ST 源码上设断点,无需关心字节码
- 👁️ 观察点(Watchpoint) --- 变量值变化自动暂停,精准定位逻辑问题
- 🔧 策略模式架构 --- 命令可扩展、可插拔,二次开发零摩擦
为什么选择 aiDgePLC?
🎯 为自动化工程师设计
传统 PLC 调试依赖厂商 IDE(如 TIA Portal、CODESYS),笨重且封闭。
aiDgePLC 兼容 OpenPLC Runtime v4 协议,无需安装数 GB 的商业软件。
它让你用熟悉的 IEC 61131-3 语言 编写程序,用类 GDB 命令 调试,或者使用openplc 集成开发环境(IDE)调试。
同时支持 CLI 调试,无需安装任何依赖。
st
PROGRAM main
VAR
temperature : REAL := 25.0;
heater : BOOL := FALSE;
END_VAR
IF temperature < 20.0 THEN
heater := TRUE;
ELSIF temperature > 30.0 THEN
heater := FALSE;
END_IF;
END_PROGRAM
$ aidgeplc-debug thermostat.iec
[aidgeplc-dbg | LOADED | ip=0] break 7:L ← 在加热器开启行设断点
[aidgeplc-dbg | LOADED | ip=0] watch temperature ← 监控温度变化
[aidgeplc-dbg | LOADED | ip=0] run ← 运行
[aidgeplc-dbg | PAUSED | ip=48] print temperature
temperature = 19.5
[aidgeplc-dbg | PAUSED | ip=48] print heater
heater = TRUE
🌐 远程调试,随时随地为 PLC 把脉
内置 WebSocket 调试服务器,兼容 OpenPLC Runtime v4 协议。
用OPENPLC IDE 或者浏览器,自己实现的APP远程调试运行在边缘设备上的 PLC 程序。
┌─────────────┐ WebSocket ┌──────────────┐ STVM ┌──────────┐
│ 浏览器/APP │ ←──────────────→ │ DebugServer │ ←────────→ │ ST VM │
│ (任意平台) │ ws://device:8443 │ (策略分发) │ │ (执行引擎)│
└─────────────┘ └──────────────┘ └──────────┘
🔩 策略模式,扩展无忧
命令分发基于 wheels::dm::strategy 模板类,新增命令只需一行注册:
cpp
registerCmd("myCommand", cmdMyCommand_impl); // 就这一行,完成
无需修改分发逻辑,无需 if-else 链,符合开闭原则。
🏗️ 可嵌入,可交叉编译
- CMake 构建,支持 WSL / Linux / 交叉编译
- stvm 作为外部依赖,不侵入修改
- 静态链接,单文件部署到 ARM64 设备
核心功能
调试器(Debugger)
| 功能 | 说明 |
|---|---|
| 文本载入自动编译 | load file.iec 即编译到内存执行 |
| 源码行号断点 | break 10:L --- 直接按 ST 源码行号设断点 |
| IP 地址断点 | break 48 --- 按字节码地址设断点(高级) |
| 观察点 | watch var --- 变量值变化自动暂停 |
| 单步执行 | step(步入)/ next(步过)/ finish(步出) |
| 变量查看/修改 | print var / set var=42 |
| 调用栈 | bt --- 查看调用层级 |
| 反汇编 | disasm --- 查看字节码上下文 |
| 寄存器/栈 | registers / stack --- 查看 VM 内部状态 |
调试服务器(DebugServer)
| 功能码 | 名称 | 说明 |
|---|---|---|
| 0x41 | DEBUG_INFO | 获取程序信息(入口、符号表) |
| 0x42 | DEBUG_SET | 设置变量跟踪标志 |
| 0x43 | DEBUG_GET | 获取单个变量值 |
| 0x44 | DEBUG_GET_LIST | 批量获取变量值 |
| 0x45 | DEBUG_GET_MD5 | 获取程序 MD5 |
| 0x46 | DEBUG_LOAD | 载入 ST 源码(远程编译) |
| 0x47 | DEBUG_RUN | 运行到断点/结束 |
| 0x48 | DEBUG_STEP | 单步执行 |
| 0x49 | DEBUG_BRK_SET | 设置断点(IP 或行号) |
| 0x4A | DEBUG_BRK_CLR | 清除断点 |
| 0x4B | DEBUG_BRK_LIST | 列出断点 |
| 0x4C | DEBUG_STATE | 查询状态 |
| 0x4D | DEBUG_RESET | 重置执行 |
| 0x4E | DEBUG_CALLSTACK | 查询调用栈 |
| 0x4F | DEBUG_DISASM | 反汇编 |
0x41-0x45 兼容 OpenPLC Runtime v4 协议,0x46-0x4F 为 aiDgePLC 扩展。
快速体验
联系作者获取软件
30 秒调试
bash
# 写一个温度控制器
cat > /tmp/thermostat.iec << 'EOF'
PROGRAM main
VAR
temp : REAL := 25.0;
heater : BOOL := FALSE;
END_VAR
IF temp < 20.0 THEN
heater := TRUE;
ELSIF temp > 30.0 THEN
heater := FALSE;
END_IF;
END_PROGRAM
EOF
# 启动调试
./aidgeplc-debug /tmp/thermostat.iec
30 秒启动服务器
bash
./aidgeplc-debug-server --port 8443 --load /tmp/thermostat.iec
# 用 Python 连接:
# import websockets
# ws = await websockets.connect("ws://localhost:8443/api/debug")
# await ws.send("41") # 获取程序信息
架构一览
aiDgePLC/
├── include/aidgeplc/
│ ├── debugger.hpp ← 调试器接口(断点/观察点/单步/变量/栈)
│ └── debug_server.hpp ← WebSocket 服务器接口(协议/strategy 分发)
├── src/
│ ├── debugger/Debugger.cpp ← 调试器实现
│ └── debug_server/DebugServer.cpp ← 服务器实现
├── tools/
│ ├── aidgeplc-debug/ ← CLI 调试器入口
│ └── aidgeplc-debug-server/ ← 服务器入口
├── stvm/ ← STVM 虚拟机(外部依赖/子模块)
├── CMakeLists.txt ← 构建(FetchContent: cpp-misc, libhv)
└── build.sh ← 一键构建脚本
技术栈:
- STVM --- ST 字节码虚拟机 + 编译器
- cpp-misc ---
wheels::dm::strategy策略模式模板 - libhv --- 轻量级 WebSocket 服务器
- CMake --- 跨平台构建,支持交叉编译
- C++17 --- 现代C++,无第三方运行时依赖
谁在使用 aiDgePLC?
- 🔬 PLC 算法原型验证 --- 写 ST 代码快速验证逻辑,无需真实 PLC 硬件
- 🏭 工业自动化教学 --- 学生在命令行中学习 PLC 编程与调试
- 📡 边缘设备远程运维 --- 通过 WebSocket 远程调试运行在 ARM64 设备上的程序
- 🧪 CI/CD 自动化测试 --- 嵌入测试框架,自动验证 ST 程序正确性
- 🔌 OpenPLC 生态扩展 --- 兼容 OpenPLC v4 协议,可直接集成
路线图
- CLI 交互式调试器
- 源码行号断点
- 观察点(Watchpoint)
- WebSocket 调试服务器
- 策略模式命令分发
- 交叉编译支持
- Web UI 调试界面
- 多 POU 函数/FB 调试
- 断点条件表达式
- 调试会话录制与回放