您可以显式声明这些方法,以影响功能块变量的初始化以及退出功能块时的行为。
隐式方法的返回值类型是BOOL
。系统不会对该值进行评估,但不应更改其类型。
FB_Init
始终是隐式的,主要用于初始化。对于特定的影响,您也可以明确声明这些方法,并在标准初始化代码中提供附加代码。
FB_Reinit
必须明确执行。如果存在该方法,则在受影响功能块的实例被复制后调用 。这发生在更改功能块声明(签名更改)后的在线更改过程中,以便重新初始化新的实例模块。要重新初始化功能块的基本实现,必须明确调用FB_Reinit
。
FB_Exit
必须明确执行。如果有实现,则在控制器删除功能块实例代码之前调用该方法(隐式调用)。
下面展示了这些方法在不同运行条件下的一些使用案例。
运行条件 "首次下载"
将应用程序下载到带有出厂设置的 PLC 时,必须将所有变量的内存偏移到所需的初始状态。这样,功能块实例的数据区就会被分配所需的值。通过为功能块明确实施FB_Init
,您可以在应用程序代码中对这种情况做出具体反应。通过评估方法参数bInCopyCode
(FALSE
) 和bInitRetains
(TRUE
) 可以清楚地检测到这种运行状况。(参见 "运行条件 "在线更改""和 "运行条件 "重新下载"")。
运行条件 "在线更改
在在线更改范围内,可以通过FB_Exit
、FB_Init
和FB_Reinit
方法影响功能块实例的初始化。在联机更改期间,脱机模式下对应用程序所做的更改会应用到运行中的 PLC 中。正因为如此,功能块的旧实例会尽可能顺利地被新实例取代。如果在登录前应用程序中未对功能块的声明部分进行更改,而只是在执行中进行了更改,则数据区不会被替换。只替换代码块。那么FB_Exit
、FB_Init
和FB_Reinit
方法就不会被调用。
如果您对功能块的声明进行了更改,导致上述复制操作,那么您将在联机更改过程中收到一条信息,说明可能产生的意外影响。在“信息视图的详细信息” 中,您会看到要复制的所有实例列表。
在FB_Init
方法的代码中,可以对参数bInCopyCode
(TRUE
) 进行评估,以检测是否正在执行在线更改。
在线更改期间会连续发生以下调用:
-
FB_Exit
old_inst.FB_Exit(bInCopyCode := TRUE);
您可以在退出旧实例时调用
FB_Exit
,以便在复制操作之前触发特定的清理任务 。这样,您就可以为接下来的复制操作准备数据,并影响新实例的状态。您可以通知应用程序的其他部分有关内存中位置的待定更改。请特别注意POINTER
和REFERENCE
类型的变量。联机更改后,这些位置可能不再指向所需的内存位置。接口变量 (INTERFACE
) 由编译器单独处理,并在在线修改时进行相应调整。外部资源(如套接字、文件或其他句柄)可由新实例应用,在某些情况下保持不变。通常情况下,在线更换时不必对它们进行特殊处理。(请参阅 "操作条件 "重新下载"")。 -
FB_Init
new_inst.FB_Init(bInitRetains := FALSE, bInCopyCode := TRUE);
FB_Init
在复制操作之前被调用,可用于执行在线更改的特定操作。例如,你可以在内存中的新位置对变量进行相应的初始化,或者将内存中特定变量的新位置通知应用程序的其他部分。 -
复制操作:
copy
copy(&old_inst, &new_inst);
现有数值保持不变。为此,会将它们从旧实例复制到新实例中。
-
FB_Reinit
new_inst.FB_Reinit();
该方法在复制操作后调用,应为实例变量设置定义值。例如,你可以在内存中的新位置对变量进行相应的初始化,或者将内存中特定变量的新位置通知应用程序的其他部分。设计独立于在线变更的实施方案。应用程序也可以随时调用该方法,将功能块实例重置为原始状态。
通过{attribute 'no_copy'}
属性,可以防止在对功能块的单个变量进行联机更改时复制该变量。它始终保留初始值。
运行状态 "新下载"
下载应用程序时,PLC 上的现有应用程序可能会被替换。因此,必须对现有功能块的内存供应进行管理。您可以使用FB_Exit
方法来执行所需的步骤。例如,您可以在定义的状态下抵消外部资源(使用套接字和文件句柄)。
您可以通过检查FB_Exit
方法的参数bInCopyCode = FALSE
来检测这种运行状况。
运行条件 "开始应用"
最初的任务分配是在申请任务的第一个周期之前处理的。
示例
T1 : TON := (PT:=t#500ms);
这类赋值只有在调用FB_Init
后才会执行。为了控制这些赋值的效果,可以为功能块或功能块的方法提供{attribute ‘call_after_init‘}
属性。您必须将该属性添加到函数块主体声明部分的上方和相应方法声明部分的上方。扩展另一个使用{attribute 'call_after_init'}
属性的 POU 的 POU 也必须具有该属性。为清晰起见,我们建议用相同的名称、相同的签名和相同的属性覆盖相应的方法。这需要调用SUPER^.MyInit
。方法名称的选择不受限制。(例外:FB_Init
,FB_Reinit
, 和FB_Exit
)。该方法在处理完初始分配后、启动应用任务前被调用。因此,该方法可以对用户输入做出反应。
当使用FB_Init
或{attribute 'call_after_init'}
时,请记住,检测FB_Init
方法或使用{attribute 'call_after_init'}
属性装饰的方法中的错误是很繁琐的,因为断点的设置可能达不到预期效果。




注意

如果在执行过程中到达了显式定义的初始化代码,那么功能块实例已经通过隐式初始化代码完全初始化了。因此,SUPER^.FB_Init
。




注意

FB_Init
取代了CoDeSys V2.3中使用的INI
操作符。这些方法不能与 C#、C++ 或 Java 中的构造函数设计相提并论。这对扩展其他功能块的功能块有影响。(见下文:"派生功能块")
方法的界面 FB_Init
METHOD FB_Init : BOOL VAR_INPUT bInitRetains : BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold) bInCopyCode : BOOL; // TRUE: the instance will be copied to the copy code afterward (online change) END_VAR
您可以在FB_init
方法中声明额外的功能块输入。然后,您必须在功能块实例的声明中设置这些输入。
示例
serialdevice
功能块的方法FB_Init
METHOD PUBLIC FB_Init : BOOL VAR_INPUT bInitRetains : BOOL; // initializing of retain variable bInCopyCode : BOOL; // instance is copied to copy code iCOMnum : INT; // additional input: number of the COM interface, that is to be observed END_VAR
serialdevice
功能块的实例化:
com1: serialdevice(iCOMnum:=1); com0: serialdevice(iCOMnum:=0);
方法的界面 FB_Reinit
METHOD FB_Reinit : BOOL
方法的界面 FB_Exit
必选参数bInCopyCode
。
METHOD FB_Exit : BOOL VAR_INPUT bInCopyCode : BOOL; // TRUE: the exit method is called in order to leave the instance which will be copied afterwards (online change). END_VAR
派生功能块的行为
如果一个功能块是从另一个功能块派生出来的,那么派生功能块的FB_Init
方法必须与基本功能块的FB_Init
方法定义相同的参数。不过,您可以添加更多参数,以便为实例设置特殊的初始化。
示例
功能块MainFB
、SubFB
和SubSubFB
相互派生。因此,SubFB EXTENDS MainFB
和SubSubFB EXTENDS SubFB
。
FB_Exit
和FB_Init
方法的调用顺序 :
-
fbSubSubFb.FB_Exit(...);
-
fbSubFb.FB_Exit(...);
-
fbMainFb.FB_Exit(...);
-
fbMainFb.FB_Init(...);
-
fbSubFb.FB_Init(...);
-
fbSubSubFb.FB_Init(...);