告别 matiec 与 Docker:aiDgePLC Editor 全面拥抱 STVM 字节码编译

告别 matiec 与 Docker:aiDgePLC Editor 全面拥抱 STVM 字节码编译

项目地址:https://gitee.com/galaxy_0/ai-dge-plceditor.git

一、背景:传统编译链的"阿喀琉斯之踵"

aiDgePLC Editor 是一款面向 aiDgeController Runtime 的集成开发环境,支持以结构化文本(ST,IEC 61131-3)编写 PLC 程序。在早期版本中,编辑器采用的是工业界经典的 matiec(iec2c)+ Docker 交叉编译 工具链:

复制代码
PLC 项目 JSON → plc.xml → program.st ──[matiec/iec2c]──▶ C 源码 ──[gcc + Docker]──▶ 固件

这条链路为项目立下了汗马功劳,但也暴露出三个难以回避的痛点:

  • 环境依赖沉重:用户必须安装 Docker 并拉取数十 MB 的交叉编译镜像,首次编译启动慢、网络受限场景几乎不可用。
  • 部署与跨平台复杂:matiec 与 gcc 的不同架构二进制需要逐一维护,每支持一块新板卡就要维护一套交叉编译工具链。
  • 编译反馈冗长:ST → C → 汇编 → 目标码的多层转换,使调试信息与源码的对应关系变得模糊。

二、新选择:STVM ------ 为 ST 而生的字节码虚拟机

STVM(Structured Text Virtual Machine)是一款轻量级的 ST 字节码虚拟机,提供完整的编译与运行时工具链:

工具 作用
stvmc 将 ST/IEC 源码编译为 .bytecode 字节码
stvm-run 在主机或嵌入式设备上加载并执行字节码
stvm-disasm 字节码反汇编,辅助调试

stvmc 支持两套语法前端:旧版 ST 子集(.st)与完整的 IEC 61131-3 模式(.iec / --iec),后者覆盖 FUNCTION、FUNCTION_BLOCK、CONFIGURATION、RESOURCE、TASK 等完整构造,恰好匹配 xml2st 生成的 OpenPLC 标准 ST 结构。

三、为什么是 STVM?

我们选择 STVM 而非其他方案,基于以下考量:

  1. "一次编译,到处运行":字节码与目标硬件解耦,运行时只需一个 stvm 解释器,省去 Docker 与交叉编译器。
  2. 编译即交付 :program.st → program.bytecode 一步到位,产物可直接上传至 Runtime,编译速度快、日志直接对应源码行号。
  3. 静态单文件部署 :我们将 stvmc.exe 以 /MT 静态运行时构建,仅依赖 KERNEL32.dll,无需额外运行库,随编辑器一同分发。
  4. 开源协议友好:STVM 采用 GPL-2.0 双授权,与 aiDgePLC Editor(GPL-3.0)的开源路线一致。

四、适配历程

本次适配不是简单的"换个编译器",而是对编译流水线的一次重构。

1. 工具链替换

复制代码
program.st ──[stvmc --iec]──▶ program.bytecode
  • 新增 StvmCompilerModule,封装 stvmc 调用:checkAvailability() 探测可用性,compileToBytecode() 生成字节码。
  • 强制使用 --iec 模式:xml2st 产出的 program.st 虽为 .st 扩展名,但包含 IEC 完整构造,旧 ST 子集无法解析。
  • 输出路径沿用原有 src/program.bytecode,便于 v4 Runtime 打包上传。

2. 清理 C 时代遗产

字节码流程不再产出 C 文件,以下步骤被整体移除:

  • handleGenerateDebugFiles(xml2st --generate-debug,生成 C 调试文件)
  • handleGenerateGlueVars(生成 LOCATED_VARIABLES.h)
  • C/C++ 块头文件与代码生成(c_blocks.h / c_blocks_code.cpp)
  • stCC 桥接代码注入
  • Docker 交叉编译(compiler-cross-module)

保留了仍有价值的环节:JSON→XML、XML→ST、静态资源拷贝、MD5 提取、运行时配置生成与上传。

3. 上游协作

适配过程中我们向 STVM 提交了一处关键修复:IecParser.cpp 的 parseTaskDeclaration() 原先不消费 TASK 声明末尾的分号,导致 OpenPLC 标准的 TASK task0(...); 解析失败。修复后 TASK 声明可被正确接受。

五、编译流水线现状

复制代码
项目 JSON
   │
   ▼ handleGenerateXMLfromJSON
plc.xml
   │
   ▼ handleTranspileXMLtoST (xml2st)
program.st
   │
   ▼ handleCompileSTtoBytecode (stvmc --iec)
program.bytecode
   │
   ├─ OpenPLC Runtime v3 ──► 上传 program.st / program.bytecode
   └─ OpenPLC Runtime v4 ──► 打包 src(含 bytecode + 配置)上传

六、用户体验提升

  • 零 Docker 依赖:下载即用,不再需要配置容器环境。
  • 编译速度显著提升:省去 C 编译与链接,ST 到字节码通常在毫秒到秒级完成。
  • 错误定位精准 :stvmc 的类型检查直接报告源码行号,例如 line 6: undefined variable 'b'。
  • 配置页面精简:移除了 Cross Compiler、Device、Communication Port 等面向旧工具链的选择项,界面更聚焦于程序本身。

七、已知边界与后续规划

STVM 的 IEC 前端仍在快速演进中,当前存在少量已知限制(例如 RESOURCE 内的 VAR_GLOBAL 段、表达式中直接使用 %IX0.0 地址字面量),我们正与上游保持沟通并持续跟进。同时,团队正推进:

  • stvm 嵌入式运行时:在 aiDgeController 硬件端集成 stvm-run,实现字节码直接执行。
  • 调试符号增强:让 stvmc 输出的字节码携带更丰富的源码映射信息,支持在线调试。
  • 构建流程沉淀:将 stvm 的获取、补丁、静态构建流程固化为一键脚本,确保版本升级可复现。

八、结语

从 matiec 的 C 代码生成到 STVM 的字节码编译,aiDgePLC Editor 完成了一次编译哲学的升级:不再把 ST 翻译成 C 再交给通用编译器,而是让 ST 直接成为可执行的字节码。这不仅简化了部署、加快了反馈,也为后续在嵌入式端实现真正的"解释执行"与"热更新"打开了大门。

如果你也在为 PLC 编程环境的编译链路过重而烦恼,欢迎关注 aiDgePLC Editor 与 STVM 的后续进展,一起让 ST 编程更轻、更快、更现代。

相关推荐
智购科技智能售货柜1 小时前
地下车库设备频繁掉线,排查发现是NB-IoT的PSM配置与心跳冲突~YH
物联网
做萤石二次开发的哈哈6 小时前
视频解码器怎么对接?解码上墙、电视墙开窗与场景切换的ISAPI接入实战
人工智能·物联网·监控·视频编解码·大屏端·萤石开放平台·蓝海aiot一站式工作台
辛迪聊物业数字化8 小时前
智慧社区SaaS平台架构拆解:从物业收费到IoT联动的落地实现
物联网·架构
wtblszn10 小时前
光伏工业物联网是什么
物联网
李永奉10 小时前
中科蓝讯SDK开发-BT897X、BT891X、AB573X、AB572X 系列 触摸按键提示音功能实现
网络·单片机·嵌入式硬件·mcu·物联网
权球物联分享物联网连接服务11 小时前
烟雾报警器物联网卡如何保障火情实时上报,怎么挑选稳定方案
物联网
HZZD_HZZD12 小时前
碳排放核算只报一个数,审计凭什么信你?合众致达蒙特卡洛不确定性量化实测:25.2万度园区月账95%置信区间收窄至±2.4%
大数据·物联网
SL_staff12 小时前
物模型是设备的数字身份证:属性、事件、服务如何决定IoT系统扩展性
java·物联网·全栈
wtblszn12 小时前
光伏发电与光热发电有什么区别
大数据·运维·物联网
TDengine (老段)14 小时前
TDengine TSDB 实战排障三(集群高可用)
数据库·物联网·时序数据库·tdengine·涛思数据·问题排查