使用“用于隐式检查的 POU”进行错误检查


有时,控制器上的应用程序会神秘地崩溃,并显示“访问冲突”之类的消息。双击 PLC 日志中的“源位置”跳转到代码位置,显示的崩溃位置与问题似乎没有任何关联(例如,简单的 TON 功能块或库)。这些类型的错误的另一个指示是当应用程序更改时,代码位置也会更改。

常见原因是写入超出数组的范围。

例如,这可以通过使用“用于隐式检查的 POU”来检测,特别是使用函数“CheckBounds”。

出于性能原因,调试后应从项目中删除“用于隐式检查的 POU”。重命名它是不够的。

隐式检查仅对项目中的代码执行。 如果要检查库,则必须设置编译器定义checks_in_libs。

例如:

要求

  • 创建一个标准项目并选择 CODESYS ControlWin V3 作为设备。
  • 通过网络扫描连接目标系统

图1

  • 按如下方式 PLC_PRG:

声明

VAR
    iIndex       :    INT;
    astInst      :    ARRAY [1..5] OF INT := [5(101)];
    xActivate    :    BOOL;
END_VAR

实现

IF xActivate THEN
    xActivate := FALSE;
    FOR iIndex := 0 TO 5 DO
        astInst[iIndex] := 234;
    END_FOR
END_IF

下载并启动项目

将项目下载到控制器并启动应用程序。 设置 xActivate 变量后,将显示下图:

图2

预期结果是数组的所有元素都设置为值“234”。

由于数组的下限设置为“1”,计数器变量的内存区域在第一个执行循环中用 234 描述不正确(iIndex 的值为“0”),因为它位于数组之前的内存区域中。

在下一个执行的循环中,检测到满足循环的取消条件,因此不会写入数组的任何元素。

内存中的这些错误可能会产生意想不到的结果,就像控制器崩溃一样严重。

包含“检查边界”函数

将“用于隐式检查的 POU”对象添加到项目中:

图3

将自动打开以下对话框,可在其中选择检查类型。 选择“Bound Checks”选项。

图4

应当只选择一个选项。可能必须使用其他选项重复检查。

使用函数“CheckBounds”

  • 将项目下载到控制器并启动应用程序。
  • 在所需的检查处设置断点。

如果检测到边界冲突,则项目将在断点处停止。

图5

  • 切换到 PLC_PRG 并将 xActivate 变量设置为 TRUE。

项目在有关下限冲突的断点处停止。

图6

  • 通过单步执行退出 CheckBounds 函数(按 F10 两次),调试器将自动跳转到检测到边界冲突的位置:

图7

  • 也可以打开调用堆栈,并从那里跳转到相关位置:

图8