3. PLCnext软件架构总览

PLCnext Control 的软件架构可以理解为一条从“硬件资源”到“用户应用”的纵向分层栈,同时又是一张横向贯通的组件交互网。纵向看,它由下至上依次是:硬件与引导层、Linux 实时系统层、固件层(Firmware)、Runtime 层、应用层。横向看,各层之间通过明确的接口通信:内核态与用户态之间靠驱动和系统调用,固件与 Runtime 之间靠服务接口,Runtime 与应用之间靠组件模型和全局数据空间。理解这套分层与交互关系,是后续做 C++/IEC 61131-3 混合编程、实时任务调优和诊断排障的基础。

一、纵向分层:从内核到应用

Linux 实时系统层是整台控制器的地基。PLCnext 使用带 PREEMPT_RT 补丁的 Linux 内核,把标准 Linux 的调度器改造成可抢占的实时调度器,使高优先级线程的调度延迟从毫秒级降到微秒级。这一层负责进程调度、内存管理、文件系统、网络协议栈和硬件驱动。对控制工程师而言,最需要关注的是:实时线程优先级(如 SCHED_FIFO 优先级 1~99)、CPU 隔离(isolcpus)、中断亲和性,以及内核启动参数。这些决定了上层 Runtime 能否稳定地以 1 ms 甚至更短的周期运行。

固件层(Firmware)位于 Linux 之上、Runtime 之下,是 PLCnext 特有的“平台服务层”。它包含设备抽象、硬件诊断、LED/按键管理、看门狗、安全启动校验、固件更新机制等。固件层把底层硬件差异封装成统一服务,向上暴露给 Runtime。例如,当你在应用里读取模块温度或触发一次固件升级时,实际调用的是固件层提供的服务接口,而不是直接操作寄存器。固件层还负责在系统启动时完成硬件自检,并把结果写入诊断日志,供上层读取。

Runtime 层是 PLCnext 的“运行时引擎”,也是整个平台最核心的部分。它包含多个并行运行的运行时组件:

  • PLC Runtime(IEC 61131-3):执行梯形图、功能块图、结构化文本等程序,由实时任务调度器按周期触发。
  • Linux Runtime(C++/Python 等):执行用高级语言编写的实时或非实时应用,通过 GDS(Global Data Space)与 PLC 程序交换数据。
  • GDS(全局数据空间):一个跨语言、跨进程的共享数据总线,所有变量以“数据点”形式注册,任何组件都可以按名称读写。
  • 组件管理器(Component Manager):负责加载、启动、停止和监控各个应用组件,管理依赖关系与生命周期。
  • 诊断与日志服务:收集来自固件、Runtime 和应用层的诊断信息,统一输出到 Web 界面或日志文件。

应用层是用户最终部署的业务逻辑。它可以是 IEC 61131-3 程序、C++ 实时应用、Python 脚本,也可以是 Web 可视化页面或 OPC UA 服务。应用层不直接接触硬件,而是通过 Runtime 提供的 API 和 GDS 数据点与下层交互。这种设计让应用与硬件解耦:同一套应用代码可以部署到不同型号的 PLCnext 控制器上,只要 Runtime 和固件层提供一致的接口。

二、组件交互关系:数据如何流动

分层只是静态结构,真正决定系统行为的是组件之间的动态交互。以一个典型的“温度采集—PID 控制—输出”为例:

  1. 固件层通过驱动读取模拟输入模块的原始值,写入 GDS 数据点 AI_Temp_Raw。
  2. IEC 61131-3 程序在 10 ms 周期任务中读取该数据点,做量程变换后写入 Temp_Value。
  3. C++ 实时应用订阅 Temp_Value,执行 PID 计算,把输出写入 Heater_Out。
  4. 固件层读取 Heater_Out,驱动模拟输出模块更新电压。
  5. 诊断服务持续监控各环节的周期抖动和超时,异常时写入日志并触发报警。

这条链路中,GDS 是数据交换的枢纽,组件管理器保证各组件按依赖顺序启动。如果 C++ 应用启动时 PLC 程序尚未运行,组件管理器会等待其依赖项就绪后再启动,避免数据点未注册导致的读写失败。

三、架构总览图

下图把上述分层与交互关系整合为一张结构图。左侧是纵向层级,右侧是各层内部的关键组件,箭头表示主要数据流和控制流方向。

PLCnext 软件架构分层与组件交互 应用层 IEC 61131-3 程序 C++ / Python 应用 Web / OPC UA 服务 可视化 HMI 用户业务逻辑,通过 GDS 与 Runtime 交换数据 API / GDS 数据点 Runtime 层 PLC Runtime IEC 任务调度 Linux Runtime C++/Python 执行 GDS 全局数据空间 组件管理器 生命周期管理 诊断与日志服务:周期抖动监控、超时报警、日志输出 运行时引擎,负责程序执行、数据交换与组件调度 服务接口 / 驱动调用 固件层(Firmware) 设备抽象 硬件诊断 看门狗 / 安全启动 固件更新 平台服务层,封装硬件差异,向上提供统一服务接口 系统调用 / 驱动 Linux 实时系统层 PREEMPT_RT 内核 实时调度器 内存 / 文件系统 网络协议栈 实时内核,提供微秒级调度延迟与硬件驱动支持 硬件平台:CPU / 内存 / 闪存 / 总线接口 / I/O 模块 纵向分层

四、关键交互机制与工程要点

理解架构之后,实际工程中需要把握几个关键点。第一,实时域与非实时域的边界。PLC Runtime 和 C++ 实时应用运行在实时域,Web 服务、日志上传等运行在非实时域。跨域数据交换必须通过 GDS,且要注意非实时域写入的数据可能被实时任务以不确定的延迟读到。第二,组件启动顺序。组件管理器按依赖关系启动,但 GDS 数据点的注册是异步的,应用代码中应使用“等待数据点可用”的机制,而不是假设启动后立即能读写。第三,周期任务与优先级。IEC 任务和 C++ 实时线程共享 CPU,需要合理分配优先级和 CPU 亲和性,避免高优先级任务被低优先级任务阻塞。第四,诊断信息的读取路径。固件层和 Runtime 的诊断信息最终汇聚到诊断服务,可以通过 Web 界面、SNMP 或 OPC UA 读取,排障时应先确认问题出在哪一层,再深入对应日志。

判断问题所在层的一个实用方法:如果所有应用都无响应,优先查 Linux 内核日志(dmesg)和固件自检结果;如果只有某个 IEC 任务周期抖动大,查 Runtime 的任务调度和 CPU 负载;如果数据点读写失败,查 GDS 注册状态和组件管理器日志。

把这张架构图记在脑子里,后续无论是写 C++ 实时组件、配置 IEC 任务周期,还是分析诊断日志,都能快速定位到对应的层和组件,而不是在整台控制器里盲目搜索。