图标:
这个命令 (类别 "Composer") 启动一个编译进程自动编译生成CoDeSys中用于应用的模块树以及
⇘
“编译配置”的相关设置。
编译信息和错误将显示在消息窗口中。
所有通过标准编译产生的对象(除了任务对象和应用)都将存储在POU池中中名为“AC_Std”和“AC_FBs”的子文件夹中。如果一个同名的文件夹已经存在,将会添加一个带有标示“-0”的组合名称。
所有通过“编译生成”命令生成的对象都会带有一个蓝色的图标。如果用户尝试删除,移动或者修改这些对象中的某项,一个对话框就会出现,提示可能会因此产生编译错误。如果继续操作,那么它前面的图标就会变成红色(参见上面截图中的功能块“AC_PRG_RMP (PRG)”)。
通过标准的编译生成功能块的接口
对于每个模块实例都将产生一个功能块(文件夹中的“AC_FBs”)。此功能块来自模块的功能块。
功能块包含输入变量
- 用于子模块实例
- 用于变量阵列
- 用于直接的 I/O 连接的缓冲
- 由于阵列的多插槽和参考实例
相应的数组变量的名称由“AC_ARRAY_”前缀加参数各自的指针变量名构成。对于数组的变量索引大小(VarArrays)名称可以被参数VarArray.InstName重写。
功能块的实现部分包含命令SUPER^()将调用模块功能块的实现部分。
示例
模块接口ModuleInstanceA的类型是ModuleA以及其相关的功能块ModuleA_FB。这个实例具有类型为ModuleB的子模块实例。
FUNCTION_BLOCK AC_ModuleInstanceA EXTENDS ModuleA_FB
VAR_INPUT
Inst_Sub1 : AC_ModuleInstanceB ;
END_VAR
功能块的名字是由模块实例路径和前缀“AC_”组成。
子模块实例中变量的名称是由一个各自子模块示例名称构成的前缀创建。
每个功能块被实例化一次,顶端模块的功能块实例位于GVL中 - 其余的位置于父实例功能块有关。
对于每个另一个应用中被引用的模块实例,一个代理功能块的实例将会在一个相关的模块实例的GVL中创建。代理实例的名称为AC_PROXY_<InstanceName>在 "InstanceName" 处是另一个目标系统中目标实例的名称。
特殊的地址分配给所有的模块实例。代理的FB实例由其他地方的应用进行地址管理。
代理实例的方法IBaseInstance.Main通过一个通讯任务进行周期性的调用。
创建的应用程序和任务调度
- 如果一个模块被分配到一个不存在的应用中,这个应用将会被创建。
- 创建不存在的标注任务
- TASK_MODULE_HIGH
- TASK_MODULE_MEDIUM
- TASK_MODULE_LOW
调用优先级和任务的循环时间是根据编译设定进行的设置。此外给予的特殊任务的设置将会被创建。
- 在每个顶层创建一个全局变量列表。在这个列表中,同一个应用中位于顶层模块的模块实例将会被创建。实例的名称是根据模块中的定义确定的。如果没有定义,那么同样的“GVL_MODULE“将会被创建。
针对每个应用创建一个名为”GVL_MODULE_TREE“的全局变量列表。这个列表中包含了用于管理模块树的变量。全局变量类表将在文件夹”AC_Std“中创建。
- 创建代码的初始化将会自动调用并且做在线修改:
- 树形结构将会创建
- 参数值将会被设定
- 参考和子模块实例将会被分配
- 包含变量尺寸的数组将会被填充
- 实例的引用将会被设置
在下载过程中只有不为默认值的参数才会被设置。在在线修改之后所有的参数都将被重置。相应的POUs将会在文件夹“AC_Std”。
- 对每个定义的入口程序,一个相应的POU(ST语言)将会被创建,其中包含顶层模块的调用。这个新的POU的调用将会被添加到任务下。在标准任务下POU名字为:
- MODULE_CALL_<TASKNAME>_START
- MODULE_CALL_<TASKNAME>_END
- 对于POU池中顶层模块的调用将会在所有应用中创建。
创建I/O分配
根据 I/O 的类型不同,分配将按照以下操作进行:
- [I/O 通道]: 在相应的设备通道中,模块I/O实例的名称将会自动的添加。
- [ST 表达式]:将会给所有的模块实例中的表达式分配给在同级模块下相关的输入,输出。根据分配,每个顶级实例将会产生一个名为
- "AC_Io_SetInputs_<Instanzname>" resp.
- "AC_Io_SetOutputs_<Instanzname>"
的函数。
定义输入和输出的任务在模块描述中将被确定标志“UPDATE-IOS”。这个任务被称为以下描述的“I/O 任务”。
对于输入函数的调用将发生在I/O任务中,并且此任务是在模块接口被调用任务之前发生的。(如果 I/O 任务是一个标准任务,在开始方式之前)。输出函数的调用将发生在 I/O 任务中,此任务是在模块实例接口之后发生的。(如果 I/O 任务是一个标准任务,在结束方式之前发生)
- [直接连接到 I/O模块,本地]:在功能块的输入实例中将创建一个兼容类型变量的缓冲区。缓冲区变量的前缀名称为 "AC_Io_Buffer_"。
在应用程序初始化的时候缓冲区域将会初始化当前连接到输出区域的变量值。编译处理过程中分配输入- 输出缓冲区,像在ST编辑器中分配缓冲区域一样(参阅 [ST 表达式]。
- [直接连接模块 I/O,远程]:对于每一个连接到另一个应用中的输入模块实例的输出,一个合适变量的缓冲区将会在适当位置创建并通过 GVL网络变量进行发送。缓冲变量的名称以 "AC_RemoteIo_Buffer_" 开头,并且会从实例路径或者输出变量的路径进行编译。缓冲变量将通过输出变量的初始化表达式进行初始化,如果存在输出变量的初始化。如果在预编译信息中不包含变量的初始化表达式(因为变量是一种特殊形式,比如变量,函数或者内容),那么在此过程中将会产生一个错误。
对于输出单元的处理类似于对缓冲变量的处理。在一个应用程序中对输入变量的处理类似于在应用程序中对NVL变量的处理(参阅 [ST 表达式])。
注意:任务之间的同步,处于其中的网络变量将会被更新,对模块 I/O 任务的调度还没有实现。所以很有可能最变量准备写入的时候正在进行新的 I/O 任务的读取。
创建基本的通信基础
定义:在以下的描述中,如果符合描述,应用 A1 将会发送到应用 A2 (或者 A2 从 A1进行接收):
- 一个模块接口分配给A1一个参考模块接口分配给应用A2一个模块实例或反之。
- 分配到A1的一个输出模块的接口通过直接模块连接的方式分配给应用A2.
以下提到的所有对象都将会在文件夹 "AC_RMP"中针对每个编译创建的应用被创建。
- 一个通讯任务将会被创建(循环时间和根据编译配置创建的属性)。在这个任务中代理接口将会被调用。
- 对于每个设置到当前应用的应用程序,一个(发送) GVL 将会被创建并且相应的网络设置将会被定义。(协议 "UDP",循环传输,校验,根据设置定义的循环周期,通讯任务)。“列表标识符”必须是一个位于1-2^15-1之间的整形变量,在编译初期自动定义并且在每次发送GVL之后都会加1.在有效范围内这个值最少为128。如果在应用中具有模块的变量参考那么一个 RMPExchangeData 类型的变量将会被创建到 GVL中。变量的名称中包含源名称- 以及目标应用。
- 对于每个应用程序 A2,当前的应用程序都会向其中发送数据,一个(接受)NVL将会被创建并且连接到A2相应的发送以及通讯任务中。
- 一个 RMPService 类型的功能块将会在 GVL "AC_RMP" 中实力化并且在定义过程中初始化(属性 "init_on_onlchange")。两个类型 RMPConnection 的数组将会被创建到对应变量类型 RMPExchangeData 到 GVLs 和 NVLs列表中。
- 一个程序 AC_PRG_RMP 将会被创建并且程序中会调用 RMPService类型的功能块。这个程序同时也将添加到通讯任务中。