夜雨聆风学习资料网

ARTICLE · 1134354

安全PLC程序结构规范:防止逻辑混乱的模板设计

安全PLC程序结构规范:防止逻辑混乱的模板设计

🟢 选型指南|安全PLC程序结构规范:防止逻辑混乱的模板设计

「硬件选对了,程序写乱了,安全功能照样不成立。」——安全PLC的CPU、认证功能块库都是经过认证的,但把它们连起来的应用程序,认证机构并不替你背书。这篇文章聊聊安全PLC程序的结构化模板设计,以及几个能在评审和审计里省下大量时间的做法。


01开场:一份“谁都在改”的安全程序

某汽车零部件厂的老冲压线,安全PLC是2015年上的。八年里程序被三拨人维护过:最初的集成商、两年前的改造商、以及厂里自己的一位电气工程师。

一次定期的安全功能验证里,出现了这样一幕:

•安全门 S1 的输入信号,在程序里被引用 7 处:安全输出逻辑、HMI 显示、与机器人互锁、光幕逻辑,以及三个不同年代的历史遗留网络

•其中一处是两年前改造时加的临时旁路,注释写着“调试后删除”——但没删

•急停回路的输出点,在两个网络里都被写:一处按急停逻辑写 0,另一处按“设备启动条件”写 1

验证时按下急停,输出确实断了——因为两个网络的执行顺序里,“写 0”恰好排在“写 1”之后。

换个说法:这台设备的安全功能,依赖的是两个写操作的先后顺序,而不是设计者的明确意图。 只要有人调整网络顺序、或在中间插入一段程序,这个先后关系就变了,而现场没有人会发现——直到某次真正需要它动作的时候。

这次只是险兆(near miss),没有人员受伤。整改时做的第一件事不是换硬件,而是重写程序结构:把 7 处引用归并到 1 处、把双写输出改成单一所有者、把旁路逻辑从“散落在程序各处”改成“集中在一个带许可条件和计时的功能块里”。

这个案例想说明的是:安全PLC的硬件是认证过的,程序不是。应用程序的正确性,只能靠结构规范 + 验证流程来保证。


02先看数据:程序结构问题一般长什么样

以下分布来自几个项目程序评审的经验整理,属于示意性质,不是统计抽样结果,供对照自查:

问题类型
大致占比
典型表现
发现难度
同一输出被多处写入(双写)
约 3 成
急停、门锁输出被多个网络驱动
高——只在特定执行顺序下暴露
一个安全功能的逻辑分散在多个块/网络
约 2 成
同一安全门被引用 5~7 处
中
复位逻辑不统一
约 2 成
有的自动复位、有的手动,复位点各写各的
中
旁路 / Muting 无许可条件与记录
约 1 成
调试用的旁路长期在线
低,但整改代价高
时间参数以“魔数”形式散落在逻辑里
约 1 成
500ms、2s 直接写死在网络中
低
程序文档与版本记录缺失
约 1 成
程序与电气图纸、SISTEMA 计算不一致
高

把这些数字放到一台设备上看:一个中等规模的冲压单元,安全程序可能有 3000~6000 个网络,涉及 10~20 个安全功能。结构一旦失控,靠“逐条读程序”是查不干净的——这也是为什么结构规范值得在项目开始时就定下来。


03结构规范的八个要点

1|先搞清楚:安全认证覆盖到哪里为止

这是很多讨论容易含糊的地方。分工大致是这样的(以各厂商证书和标准原文为准):

层次
认证情况
责任方
安全CPU / F-CPU 硬件
有认证(通常到 PL e / SIL 3)
厂商
安全运行组 / 安全任务机制(双通道、测试脉冲、内存保护等)
有认证
厂商
认证功能块库(急停、门监控、反馈监控、全局确认等)
库块本身经过认证
厂商
把库块连成“这台设备的安全功能”的应用程序(SRASW)不在认证范围用户 / 集成商

也就是说:“用了认证功能块”不等于“程序是对的”。 标准对安全相关应用软件(SRASW)是有具体要求的——软件安全要求规范、架构设计、模块化设计、编码限制、集成与测试、验证、修改管理(ISO 13849-1 的软件条款;2015 版在 4.6 条,2023 版章节编排有调整,以标准原文为准)。IEC 61508-3 则给出了更完整的软件安全生命周期框架。

应用程序这部分,只能靠自己的规范和流程。

2|四层结构模板:把“读、判、写、报”分开

一个比较省心的结构是把安全程序分成四层,职责不交叉:

安全应用程序的四层结构(建议模板)

① 输入映射层 物理I/O → 安全输入变量 双通道等效性 / 反相信号检查(多数厂商可用专用库块完成) 测试脉冲状态、输入诊断位汇总 —— 只做“读”,不做逻辑判断;输入变量只在本层写入

② 逻辑判断层 一个安全功能 = 一个功能块实例 急停类 / 门监控类 / 光幕+Muting 类 / 双手控制类 / 使能类 … 复位信号、许可条件、时间参数在本层显式取得(不从全局随意取用)

③ 输出驱动层 每个安全输出只有一个所有者(单一写入者原则) 输出 = 逻辑层结果 + EDM 反馈监控结果 输出变量只在本层写入

④ 诊断与信息层 把前两层的诊断位、复位需求、旁路生效状态汇总成状态字 以只读方式交给标准PLC / HMI 显示 —— 禁止标准程序回写安全数据

这四层不是标准强制要求,但好处很实在:读程序的人知道去哪儿找“这个输出为什么是 0”。

3|单一所有者:一个安全输出只允许一处写

这是投入产出比最高的一条规范。

做法
说明
输出变量只在一个网络/块中写入
其他位置只允许“读”,不允许写
“启动条件”与“安全条件”合并到同一块的输入
而不是分别写同一个输出点
编译器的“多次写入”警告当成错误处理
不要以“能编译过”为通过标准
交叉引用表纳入交付物
评审时先看引用次数,超过 1 处的写入点逐个确认

⚠️ 一个容易踩的坑:有同事会认为“写 0 的那段在写 1 的后面,所以没问题”。这在功能上是成立的,但在可维护性上不成立——它把安全逻辑变成了对执行顺序的隐式依赖,而这种依赖在图纸和文档里看不出来。顺序一旦变化,安全功能就悄悄降级了。

4|功能块实例化:一个安全功能 = 一个实例 = 一个地址

规范
理由
一个安全功能对应一个独立实例
复位、诊断、故障代码都独立,互不干扰
一个实例对应一个唯一的安全地址/编号
PROFIsafe 的 F_Dest_Add、FSoE 的 Safety Address、CIP Safety 的 Safety Network Number 等
地址编号表随程序一起交付
审计和后期改造时最常用的两张表之一
避免多个功能共用一个实例
共用会让复位语义变得含糊:按一次复位,是把两个功能都复位,还是都保持?

5|复位逻辑集中化

复位是安全程序里最容易“各写各的”的部分,建议统一约定:

议题
建议做法
复位方式
手动复位优先;自动复位要有明确理由并做风险评估
复位条件
故障已清除 + 防护装置已关闭 + 操作者视觉确认(可用二次确认或延时辅助)
上电行为
上电后不自动启动,回到“需要复位”状态
全局复位与本地复位
明确分工:全局确认(如各厂商库里的全局确认类块)用于统一复位通道,本地复位按钮用于具体工位
文档化
每个安全功能的复位方式和复位点位置写进功能清单

(防止意外启动、重启动要求可参考 IEC 60204-1 / GB/T 5226.1 与 ISO 14118 / GB/T 19670。)

6|旁路与 Muting:结构化,而不是“藏起来”

调试用的旁路是现场的现实需求,禁不掉,但可以结构化成安全的东西:

要素
建议
许可条件
钥匙开关 / 权限等级 / HMI 二次确认,缺一不可
时间限制
到时自动撤销,不允许“一直有效”
状态上报
旁路生效必须出现在 HMI 和状态字里,且只读
记录
记入 HMI 事件或程序计数器,便于事后追溯
物理隔离
能做成钥匙开关最好——程序里的旁路永远不如一把钥匙可靠
禁止项
把旁路做成“一直接通的常数逻辑”,或把旁路点写在安全逻辑层之外没人看得见的地方

7|命名与参数集中管理

规范
说明
变量命名加前缀(如 SF_ / F_ 类前缀)
一眼区分安全变量与标准变量,避免标准程序误用
时间参数集中在一张常量表/参数块
不写魔数;改参数时不会漏改
语言限制
安全程序一般限制在梯形图(LAD)/ 功能块图(FBD)或受限的结构化文本子集
慎用(或不用)
跳转、间接寻址、指针、浮点比较、未认证的第三方库——有些 F-CPU 干脆不支持
程序注释
每个安全功能顶部写:功能说明、对应设备位号、复位方式、验证记录编号

8|变更与再验证:程序版本本身就是安全资料

动作
要求
版本号
每次下载到CPU的程序有唯一版本号,只增不改
变更记录
改了哪个块、为什么改、谁改的、影响哪些安全功能
影响分析
变更后受影响的安全功能需要重新验证,不必全量,但要有分析依据
验证记录
“程序版本 + 验证项目 + 验证结果 + 日期 + 验证人”——审计时最常被查的就是这个
存档
程序源文件、参数表、地址表、验证记录一并归档,不随人员变动而丢失

04模板示例:一个安全门监控功能的骨架

下面是一个结构示意(中立伪代码,不是任何厂商的实际实现),主要用来看“一个实例应该包含哪些东西”:

【安全门监控功能 —— 结构示意】

实例名    : SF_DOOR_01

安全地址  : 1001

对应设备  : 冲压线上料门 S1

私有变量(本实例独占,不与其它实例共用)

  IN_A       门开关通道A

  IN_B       门开关通道B(等效性 / 反相检查)

  EDM        K1、K2 反馈触点

  RESET      复位按钮(手动,上升沿有效)

  LOCK_REQ   门锁/运行许可请求

  时间参数    t_EDM_START / t_EDM_STOP / t_RESET  ← 取自集中参数表,不写魔数

每个扫描周期的处理顺序

  1) 读输入映射层的双通道状态,做等效性判断

  2) 门未关闭 → 输出禁止启动,并置“需要复位”

  3) 门关闭且等效性成立 → 等待复位(不自动启动)

  4) 复位条件:门关闭 + 故障已清除 + RESET 上升沿 + 视觉确认

  5) 输出驱动:ON 条件全部满足才输出;

     EDM 反馈在 t_EDM_START 内未到位 → 判故障

  6) 任一故障 → 断开输出 + 置“需要复位” + 上报诊断码

对外输出(供输出驱动层与诊断层使用)

  Q_ENABLE        安全使能 —— 本实例是该变量唯一的写入者

  DIAG_CODE       故障代码

  RESET_REQUIRED  需要复位标志

  BYPASS_ACTIVE   旁路生效标志(如配置了旁路)

一个实践中的省力做法:多数厂商的认证功能块库里,等效性检查、EDM 监控、启动测试、诊断代码、复位需求判断这些内部逻辑已经做好了(例如西门子 F 库中的急停、门监控、反馈监控、全局确认等类别的块;皮尔磁(Pilz) PNOZmulti 的图形元素;倍福 TwinSAFE 的逻辑端子等)。优先调用库块,而不是手写梯形图实现等效性判断,是最省事、也最经得起审计的一条。具体的块名、引脚和限制条件,以厂商最新手册为准。


05品牌 / 平台对比:安全程序结构与组态工具

平台 / 品牌
典型产品
组态软件
安全程序语言
安全域与标准域的关系
模板 / 库支持
西门子
S7-1500F / S7-1200F
TIA Portal
F-LAD、F-FBD(安全程序不支持 ST/SCL)
同一 CPU 内的安全运行组,与标准程序分区
F 库较完整,交叉引用与编译检查成熟
罗克韦尔
GuardLogix
Studio 5000
以梯形图为主(高版本另有扩展,以版本说明为准)
同一控制器内安全任务与标准任务分离
认证安全指令集 + 安全标签机制
Pilz
PNOZmulti 2 / PSS 4000
PNOZmulti Configurator / PAS4000
图形元素连线(无需编程)/ IL、LD、FBD、ST
安全侧完全独立
元素库 + 模板工程,中小设备最省事
欧姆龙
NX 系列安全CPU
Sysmac Studio
安全程序与标准程序同工程、分区编写
FSoE 安全通信
安全功能块库
倍福
TwinSAFE
TwinCAT 3 Safety Editor
独立安全工程,FBD / 梯形
安全工程与标准工程彻底解耦
TwinSAFE 逻辑端子 / 功能块
施耐德
Modicon M580 Safety
EcoStruxure Control Expert
LD / FBD / ST(受限子集)
同一工程内的安全任务
安全库
三菱
MELSEC iQ-R 安全CPU
GX Works3
FBD / 梯形
安全CPU 与标准CPU 分离或并行
安全功能块
威琅 / 基恩士
samosPRO / 安全控制器
samos PRO PLAN 等
图形化组态
安全侧独立
图形元素库,替代安全继电器的场景

几点选型上的体会:

1.程序结构能力比库块数量更重要——交叉引用检查、安全/标准变量隔离、编译期“多次写入”告警这些机制,直接决定后期维护成本

2.改造项目优先“安全侧独立 + 图形化组态”——不改原标准程序,风险最小

3.多人维护的场合,模板先行——先定层次结构、命名规范、参数表、实例清单,再动手写逻辑

4.各厂商允许的安全语言集合、库块命名与版本差异较大,上表仅为结构性对照,具体以官方最新手册和认证证书为准


06坑点总结:安全程序里最容易踩的坑

#
坑点
典型表现
可能的后果
建议做法
1
同一输出多处写入
急停输出被“安全逻辑”和“启动逻辑”分别写
安全功能依赖执行顺序,顺序一变即降级
单一所有者原则 + 交叉引用检查
2
逻辑分散
一个安全功能分散在 5~7 处引用
修改时改不全,留下隐患
一个功能一个实例
3
调试旁路未删
注释写“调试后删除”
防护装置实际被旁路
旁路结构化 + 到期自动撤销 + 状态上报
4
复位逻辑各写各的
同一个门在两个块里有两种复位方式
复位语义混乱,可能出现非预期启动
复位规范统一 + 功能清单记录
5
手写等效性判断
不用库块,自己写双通道比较
漏掉断线检测、测试脉冲、时序细节
优先使用认证库块
6
时间参数是魔数
500ms、2s 直接写死在网络里
改参数时漏改,时序不一致
集中参数表
7
标准程序回写安全数据
HMI/标准PLC 写安全变量
安全数据被非安全逻辑污染
安全变量只读对外
8
多个功能共用实例
两个门共用一个监控实例
复位、诊断相互干扰
一功能一实例一地址
9
安全地址编号无表
现场凭记忆或临时翻组态找地址
改造时配错地址,通信建立失败
地址编号表作为交付物
10
程序版本无记录
现场程序与归档不一致
审计无法追溯,变更无法复现
版本号 + 变更记录 + 再验证
11
下载即完事
改完程序直接下载,不做验证
未经验证的修改进入生产
影响分析 + 验证记录
12
扫描周期忽略不计
安全运行组周期过长
安全功能响应时间变长,影响按 ISO 13855 计算的安全距离
周期与响应时间纳入 SISTEMA / 计算书

07结语

回到开场那条冲压线——问题从来不在硬件选型上,而在于程序有没有“结构”。四层分层、单一写入者、一功能一实例、复位集中、旁路结构化、参数集中、变更留痕,这几条加起来并不复杂,但它们决定了八年之后这份程序还能不能被看懂、被安全地修改。

几个落地动作:

1.动手前先定模板——层次结构、命名前缀、参数表、实例与地址编号表,四项先定下来

2.把编译器的“多次写入”告警当错误处理——不要用“能编译过”当验收标准

3.优先调用认证功能块库——等效性检查、EDM 监控、诊断代码尽量不手写

4.旁路必须可见、可限时、可追溯——程序里的旁路,永远不如一把钥匙可靠

5.程序版本和验证记录一起归档——这是审计里最实在的“证据链”

一句话记住:安全PLC的硬件是认证的,程序不是——结构规范决定了这份程序在被修改之后,还安不安全。

以上内容基于 ISO 13849-1、IEC 61508-3、IEC 62061 及主流厂商安全编程手册整理,各厂商允许的安全编程语言、库块名称与限制条件差异较大以官方最新手册为准,安全要求以标准原文为准。文中程序结构为通用示意,非任何厂商的实际实现。


08参考资料

1.ISO 13849-1:2023 / GB/T 16855.1-2025 — 机械安全 控制系统安全相关部件 第1部分:设计通则(含安全相关应用软件 SRASW 的要求)

2.IEC 61508-3:2010 / GB/T 20438.3 — 电气/电子/可编程电子安全相关系统的功能安全 第3部分:软件要求

3.IEC 62061:2021 / GB/T 28526 — 机械安全 安全相关电气、电子和可编程电子控制系统的功能安全

4.IEC 61131-3 — 可编程控制器 第3部分:编程语言

5.IEC 60204-1 / GB/T 5226.1-2019 — 机械电气安全 机械电气设备 第1部分:通用技术条件(复位与重启动要求)

6.ISO 14118 / GB/T 19670 — 机械安全 防止意外启动

7.IEC 61784-3 — 工业通信网络 行规 第3部分:功能安全通信(PROFIsafe / CIP Safety / FSoE 等)

8.SIEMENS / Pilz / Rockwell / Omron / Beckhoff / Schneider / Mitsubishi / Wieland — 安全PLC 安全编程手册与安全功能块库说明(以各厂商官方最新文档为准)


本文内容基于公开标准文献与行业实践经验整理,以标准原文为准。安全程序设计涉及具体设备的风险评估结果与厂商实现差异,建议结合厂商技术支持和项目实际进行确认;文中提到的程序结构与参数取值均为示意。

相关学习资料