3. PLC程序结构与单元测试切入点
在产线单元测试与虚拟调试中,PLC程序结构决定了“哪些部分可以单独拿出来测、哪些必须联调”。如果程序组织混乱,测试就只能整机跑,问题定位会非常困难。因此,理解OB、FB、FC、DB的组织方式,并据此识别可独立测试的功能块与耦合边界,是单元测试设计的第一步。
一、OB/FB/FC/DB的组织方式与测试含义
西门子PLC(以S7-1200/1500为例)的程序结构由四类基本元素构成,它们各自承担不同职责,也对应不同的测试策略。
OB(组织块)是操作系统与用户程序的接口,决定程序的执行时机和优先级。常见OB包括:OB1(主循环)、OB100(启动)、OB35(循环中断)、OB82(诊断中断)等。OB本身通常不包含复杂逻辑,而是调用FB/FC。测试时,OB的“可测性”较低,因为它依赖扫描周期和硬件事件,一般通过仿真或在线监控验证调用关系是否正确。
FB(功能块)是带背景数据块的功能单元,具有“记忆”能力,适合实现状态机、步序控制、PID等需要保持状态的逻辑。FB的测试价值最高:只要给定输入和背景DB的初始状态,就能在仿真环境中独立运行,观察输出和状态变化。
FC(功能)是无记忆功能的函数,适合实现数学运算、逻辑组合、数据转换等纯逻辑。FC的测试更简单:输入确定则输出确定,不依赖历史状态,适合做单元测试中的“纯函数”验证。
DB(数据块)分为全局DB和背景DB。全局DB用于存储共享数据,背景DB与FB实例绑定。DB本身不执行逻辑,但它是耦合的重要来源:多个FB/FC读写同一个全局DB时,就形成了数据耦合,测试时必须考虑数据初始化和隔离。
二、状态机与步序控制的测试切入点
产线单元中,设备动作通常由状态机或步序控制实现。例如一个“气缸伸出—到位检测—缩回”的单元,其FB内部可能包含Step0~Step5的步序。测试这类FB时,不能只看最终输出,而要验证每一步的转移条件。
以一个典型步序FB为例,其内部结构如下:
FB "CylinderCtrl"
VAR_INPUT
Start : Bool; // 启动命令
SensorOut : Bool; // 伸出到位传感器
SensorIn : Bool; // 缩回到位传感器
FaultReset : Bool; // 故障复位
END_VAR
VAR_OUTPUT
ValveOut : Bool; // 电磁阀输出
StepNo : Int; // 当前步号
Error : Bool; // 故障标志
END_VAR
VAR
Step : Int := 0; // 内部步序
Timer : TON; // 超时定时器
END_VAR
该FB的步序逻辑可概括为:Step0等待Start;Step1输出ValveOut并启动超时定时器;Step2等待SensorOut;Step3关闭ValveOut;Step4等待SensorIn;Step5完成复位。测试时,可以构造输入序列,逐拍推进,观察StepNo和ValveOut是否符合预期。
这里的关键是:状态机的每个状态和转移条件都是可独立测试的。例如,只测试“Step1超时未收到SensorOut时,Error是否置位”,不需要真实气缸动作,只需在仿真中强制SensorOut保持FALSE并推进定时器即可。
三、识别可独立测试的功能块与耦合边界
并非所有FB都能独立测试。判断标准是:该FB的输入输出是否完整、是否依赖外部全局数据、是否依赖其他FB的运行结果。
可独立测试的FB通常具备以下特征:输入输出接口清晰;状态保存在自身背景DB中;不直接读写其他FB的背景DB;不依赖硬件I/O的实时值(可通过仿真强制)。
耦合边界则出现在以下情况:多个FB共享同一个全局DB;FB之间通过全局DB传递中间结果;FB调用其他FB并依赖其输出。此时,单元测试需要构造“桩”或“替身”,或者将耦合部分一起测试。
下面这张图展示了一个产线单元的程序结构、数据耦合关系以及推荐的测试切入点。图中左侧为OB调度层,中间为FB/FC功能层,右侧为DB数据层;虚线表示耦合边界,绿色标记表示可独立测试的块,橙色标记表示需要联调或构造桩的块。
四、从结构到测试用例的映射方法
识别出可独立测试的FB后,下一步是将其转化为测试用例。以“FB 气缸控制”为例,可以设计如下测试序列:
| 测试编号 | 初始状态 | 输入激励 | 预期输出/状态 | 验证点 |
|---|---|---|---|---|
| TC-01 | Step=0, Error=FALSE | Start=TRUE | Step=1, ValveOut=TRUE | 启动转移正确 |
| TC-02 | Step=1, Timer运行中 | SensorOut=TRUE | Step=2, ValveOut保持 | 到位检测转移 |
| TC-03 | Step=1, Timer超时 | SensorOut=FALSE | Error=TRUE, Step保持 | 超时故障处理 |
| TC-04 | Step=4, SensorIn=FALSE | SensorIn=TRUE | Step=5, 完成标志 | 缩回到位完成 |
这些用例可以在PLCSIM或虚拟调试环境中执行,不需要真实气缸。测试时,通过强制输入变量、监控StepNo和ValveOut,即可判断FB行为是否符合设计。
五、耦合边界的处理策略
当FB之间存在耦合时,单元测试需要采取不同策略。常见做法有三种:
- 构造桩模块:用简化的FC或FB替代被调用的块,只返回固定值或简单逻辑,使被测FB可以独立运行。
- 数据隔离:为被测FB分配独立的背景DB,避免与其他实例共享全局DB。测试前初始化DB,测试后检查DB变化。
- 联合测试:当耦合过于紧密、拆分成本过高时,将相关FB作为一个测试单元,一起验证输入输出关系。
在实际产线单元中,建议先按“设备动作”划分FB,再按“数据共享”识别耦合。例如,气缸FB和输送带FB如果都读写同一个“单元状态DB”,则它们之间存在数据耦合,测试时需要确保DB初始状态一致,或使用独立的测试DB。
总结来说,OB/FB/FC/DB的组织方式决定了测试的粒度:OB负责调度,不单独测试;FB和FC是单元测试的核心;DB是耦合的载体,需要识别并隔离。状态机和步序控制提供了天然的测试切入点——每个状态和转移条件都可以独立验证。通过构造输入序列、监控状态变量、判断输出结果,可以在虚拟调试环境中高效完成单元测试,为后续联调打下基础。