4. 旧程序逆向梳理

旧产线升级时,最危险的做法是拿到一个 .ACD 文件就直接打开、改几个标签、下载运行。真正稳妥的第一步,是把旧工程当成一个“黑盒系统”做逆向梳理:先弄清它由哪些任务、程序、例程组成,再弄清标签和 AOI 之间谁引用谁、谁驱动谁。只有把依赖关系画清楚,后续的迁移、替换、重构才有依据,否则很容易在升级后出现“某个输出不动了”“某个联锁失效了”这类难以定位的问题。

一、先建立工程对象的层级认知

RSLogix 5000(及后续 Studio 5000)的工程结构是严格分层的:控制器(Controller)→ 任务(Task)→ 程序(Program)→ 例程(Routine),而标签(Tag)和 AOI(Add-On Instruction)是横跨这些层级的“资源”。理解这一点,是逆向梳理的起点。

  • 任务:决定执行时机,分为连续任务(Continuous)、周期任务(Periodic)和事件任务(Event)。一个控制器只能有一个连续任务,周期任务按设定周期触发,事件任务由特定事件(如 Consumed Tag 更新)触发。
  • 程序:是任务下的调度单元,拥有自己的程序级标签(Program Tags)和例程集合。程序可以配置“主例程”和“故障例程”。
  • 例程:真正写逻辑的地方,类型包括梯形图(RLL)、功能块图(FBD)、顺序功能图(SFC)、结构化文本(ST)。
  • 标签:分为控制器级(Controller Tags)和程序级(Program Tags),作用域不同,引用关系也不同。
  • AOI:可复用的自定义指令,内部由例程实现,对外表现为一个带输入/输出参数的指令块。

逆向梳理的目标,就是把上述对象之间的“包含关系”和“引用关系”全部提取出来,形成一张可追溯的依赖图。

二、用“自顶向下 + 自底向上”两条线交叉梳理

实际操作中,建议同时走两条线,互相校验。

自顶向下:从 Controller Organizer 展开,记录每个 Task 的类型、周期、优先级;记录每个 Program 的主例程、故障例程;记录每个 Routine 的类型和调用关系。这一步得到的是“结构骨架”。

自底向上:从每个例程内部出发,统计它引用了哪些标签、调用了哪些 AOI、又调用了哪些其它例程(JSR)。这一步得到的是“引用网络”。

两条线交叉后,就能发现一些仅看结构看不出来的问题,例如:某个周期任务下的程序,实际引用了另一个程序里的程序级标签(这在 RSLogix 5000 中通常是不允许的,若存在说明工程被异常修改过);或者某个 AOI 被十几个例程调用,一旦修改其内部逻辑,影响面极大。

三、依赖关系的可视化表达

下面这张图把本节要提取的核心依赖关系集中呈现出来:左侧是任务/程序/例程的层级结构,右侧是标签与 AOI 的引用网络,中间用箭头标出“包含”与“引用”两类关系。图中参数为教学示例,用于说明梳理方法,不代表真实产线数值。

旧工程依赖关系提取示意(教学示例) 层级结构(包含关系) Task: MainTask(连续) 优先级 10 · 看门狗 500ms Program: Line1 主例程: MainRLL 故障例程: FaultRLL 程序标签: 12 个 AOI 调用: 3 个 Program: Line2 主例程: MainST 故障例程: 无 程序标签: 8 个 AOI 调用: 2 个 Routine: MainRLL 类型: 梯形图 JSR → SubRLL 调用 AOI: MotorCtl Routine: SubRLL 类型: 梯形图 被 MainRLL 调用 引用: Line1_Start Routine: MainST 类型: 结构化文本 调用 AOI: ValveCtl 引用: Line2_Speed Routine: FaultRLL 类型: 梯形图 故障处理专用 引用: FaultCode 引用网络(标签 / AOI) 控制器级标签(Controller Tags) Line1_Start · Line2_Speed · FaultCode 被多个程序共享引用 AOI: MotorCtl 输入: Start, Stop 输出: Run, Fault 内部例程: 2 个 被调用: 5 次 AOI: ValveCtl 输入: Open, Close 输出: Pos, Alarm 内部例程: 1 个 被调用: 3 次 梳理要点 1. 先记录 Task 类型与周期,判断实时性要求 2. 逐个 Program 记录主/故障例程与标签数量 3. 逐例程统计 JSR 调用链,避免循环调用 4. 统计每个 AOI 的被调用次数,评估影响面 5. 区分控制器级与程序级标签,防止跨域引用 6. 标记“只写不读”或“只读不写”的孤立标签 7. 输出依赖清单,作为迁移与重构的输入

四、具体提取方法与工具手段

在 RSLogix 5000 旧版本中,没有一键导出完整依赖图的功能,需要组合使用几种手段。

方法一:利用 Controller Organizer 逐项记录。展开 Tasks → Programs → Routines,把每个对象的名称、类型、所属关系抄录到表格中。对于周期任务,务必记录周期值(如 10ms、20ms),因为迁移到新控制器后周期设置不当会直接影响逻辑时序。

方法二:使用交叉引用(Cross Reference)窗口。在例程中选中一个标签或 AOI,按 Ctrl+E 或打开 Cross Reference 视图,可以看到它在哪些例程、哪些梯级被引用。把每个关键标签的引用位置记录下来,就能反向构建引用网络。

方法三:导出 L5K/L5X 文件做文本分析。通过 File → Save As,选择 .L5K 或 .L5X 格式导出。L5K 是文本格式,可以用文本编辑器或脚本搜索 ROUTINE、JSR、AOI、TAG 等关键字,快速统计调用次数和引用关系。例如搜索 JSR( 可以找到所有子例程调用,搜索 Add-On Instruction 可以定位 AOI 定义。

示例:在 L5K 文本中检索关键结构
ROUTINE MainRLL (RLL)
  JSR(SubRLL,0)
  XIC(Line1_Start)OTE(Line1_Run)
END_ROUTINE

AOI MotorCtl
  Parameter In: Start, Stop
  Parameter Out: Run, Fault
END_AOI

方法四:打印例程清单与标签清单。通过 File → Print → Routine List 和 Tag List,可以生成纸质或 PDF 清单,便于离线比对。标签清单中会列出每个标签的作用域、数据类型和描述,是判断“哪些标签需要迁移”的重要依据。

五、依赖关系梳理的交付物

梳理完成后,建议形成一份《旧工程依赖关系清单》,至少包含以下字段:任务名称与类型、程序名称、例程名称与类型、例程调用关系(被谁调用、调用了谁)、引用的控制器级标签、引用的程序级标签、调用的 AOI 名称及次数。这份清单是后续章节中“程序迁移映射表”和“AOI 替换方案”的直接输入。

提示:在梳理阶段不要急于修改任何逻辑。旧工程中的“奇怪写法”往往有历史原因,先记录、后判断。对于被多个程序共享的控制器级标签,要特别标注,因为它们在迁移后最容易出现作用域冲突。
注意:如果旧工程中存在跨程序引用程序级标签的情况,RSLogix 5000 通常会在编译时报警。若工程仍能运行,说明可能使用了 Produced/Consumed Tag 或 MSG 指令间接通信,这类“隐式依赖”不会出现在普通交叉引用中,需要单独检查通信配置。

完成本节梳理后,你应当能够回答三个问题:这个旧工程由哪些任务和程序组成?每个例程依赖哪些标签和 AOI?哪些对象的改动会影响面最大?带着这三份答案,才能安全地进入下一步的迁移与重构工作。