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 控制—输出”为例:
- 固件层通过驱动读取模拟输入模块的原始值,写入 GDS 数据点
AI_Temp_Raw。 - IEC 61131-3 程序在 10 ms 周期任务中读取该数据点,做量程变换后写入
Temp_Value。 - C++ 实时应用订阅
Temp_Value,执行 PID 计算,把输出写入Heater_Out。 - 固件层读取
Heater_Out,驱动模拟输出模块更新电压。 - 诊断服务持续监控各环节的周期抖动和超时,异常时写入日志并触发报警。
这条链路中,GDS 是数据交换的枢纽,组件管理器保证各组件按依赖顺序启动。如果 C++ 应用启动时 PLC 程序尚未运行,组件管理器会等待其依赖项就绪后再启动,避免数据点未注册导致的读写失败。
三、架构总览图
下图把上述分层与交互关系整合为一张结构图。左侧是纵向层级,右侧是各层内部的关键组件,箭头表示主要数据流和控制流方向。
四、关键交互机制与工程要点
理解架构之后,实际工程中需要把握几个关键点。第一,实时域与非实时域的边界。PLC Runtime 和 C++ 实时应用运行在实时域,Web 服务、日志上传等运行在非实时域。跨域数据交换必须通过 GDS,且要注意非实时域写入的数据可能被实时任务以不确定的延迟读到。第二,组件启动顺序。组件管理器按依赖关系启动,但 GDS 数据点的注册是异步的,应用代码中应使用“等待数据点可用”的机制,而不是假设启动后立即能读写。第三,周期任务与优先级。IEC 任务和 C++ 实时线程共享 CPU,需要合理分配优先级和 CPU 亲和性,避免高优先级任务被低优先级任务阻塞。第四,诊断信息的读取路径。固件层和 Runtime 的诊断信息最终汇聚到诊断服务,可以通过 Web 界面、SNMP 或 OPC UA 读取,排障时应先确认问题出在哪一层,再深入对应日志。
把这张架构图记在脑子里,后续无论是写 C++ 实时组件、配置 IEC 任务周期,还是分析诊断日志,都能快速定位到对应的层和组件,而不是在整台控制器里盲目搜索。