Simulink® В настоящее время PLC Coder™ поддерживает целевые IDE на основе плагинов, такие как Selectron CAP1131, Omron Sysmac Studio и так далее. Для пользовательских целевых IDE, основанных на плагине, которые не поддерживаются, сгенерируйте структурированный текстовый код, совместимый с PLCOpen XML или ASCII. Настройте сгенерированный код в соответствии с вашими целевыми требованиями IDE, используя встроенные опции плагина в Simulink PLC Coder.
Чтобы сгенерировать код для пользовательских основанных на плагинах целевых IDE:

Следуйте блок-схеме, чтобы создать plc_custom_ide.m и при необходимости plc_precg_callback_IDEname.m, и plc_postcg_callback_IDEname.m файлы. Чтобы использовать эти файлы для создания и генерации кода для пользовательской целевой IDE, смотрите Сгенерировать код при помощи основанной на плагине целевой IDE.
plc_custom_ide.m файлСоздание plc_custom_ide.m при помощи этого шаблона:
function plc_ide_list = plc_custom_ide % Copyright 2012-2021 The MathWorks, Inc. plc_ide_list(1) = get_ide_info_myplcopen; end function ide_info = get_ide_info_myplcopen ide_info.name = 'myplcopen'; ide_info.description = 'My PLCopen XML'; ide_info.path = ''; % IDE path ide_info.format = 'xml'; % generic|xml ide_info.fileExtension = 'xml'; ide_info.cfg = get_ide_cfg_myplcopen; ide_info.precg_callback = 'plc_precg_callback_myplcopen'; ide_info.postcg_callback = 'plc_postcg_callback_myplcopen'; ide_info.xmltree_callback = PLCCoder.PLCCGMgr.PLC_PLUGIN_CG_CALLBACK_EMPTY; ide_info.pluginVersion = 2.2; ide_info.compatibleBuildVersion = 1.6; end function cfg = get_ide_cfg_myplcopen cfg.fConvertDoubleToSingle = true; cfg.fConvertNamedConstantToInteger = true; cfg.fConvertEnumToInteger = true; cfg.fConvertOutputInitValueToAssignment = true; cfg.fConvertTunableParamToInputVariable = true; cfg.fSimplifyFunctionCallExpr = true; cfg.fConvertOutputInitValueToAssignment = true; end
Установите имя целевой IDE при помощи ide_info.name. Параметр Target IDE строения отображает имя, заданное в ide_info.description.
Если ваша целевая среда IDE соответствует общим стандартам ST, установите ide_info.format = 'generic'. Если целевая среда IDE соответствует стандарту PLCOpen XML, задайте ide_info.format = 'xml'.
Установите место размещения файлов сгенерированного кода при помощи ide_info.path.
Установите расширение для целевых файлов IDE при помощи ide_info.fileExtension.
В function_cfg раздел файла, установите свои опции плагина. Чтобы включить плагин, установите опцию плагина равным true. Для примера, cfg.fArrayInitialValueBrackets = true; включает плагин. Чтобы отключить плагин, установите опцию плагина равным false. Чтобы решить, какие опции плагина вам нужны в plc_custom_ide.m файл, см. «Опции плагина».
Если ваша пользовательская среда IDE требует обработки генерации пред- и посткодов, создайте plc_precg_callback_IDEname.m и plc_postcg_callback_IDEname.m файлы.
Предварительная обработка файла коллбэка. The plc_precg_callback_IDEname.m файл предоставляет доступ к промежуточному представлению сгенерированного кода. Промежуточный код хранится в controller Struct тип данных, который содержит такую информацию, как имя блока подсистемы, входы, выходы, сгенерированный код тело и так далее. Этот коллбэк выполняется перед вызовом специфической для цели функции эмиттера. Как создать plc_precg_callback_IDEname.m файл используйте этот шаблон:
function controller = plc_precg_callback_myplcopen(controller) % Copyright 2012-2020 The MathWorks, Inc. % do modifications to the controller struct here, f.ex.: for i = 1:length(controller.components) controller.components(i).body = sprintf('<<header_placeholder>>\r\n%s',controller.components(i).body); end end
Постобработка файла коллбэка. The plc_postcg_callback_IDEname.m файл обеспечивает доступ к файлу сгенерированного кода. Используйте этот файл, чтобы сгенерированный код совпадал с синтаксическими требованиями для пользовательской целевой IDE. Этот файл считывается и вносит изменения в сгенерированный файл кода, который считывается как строковый файл. Как создать plc_postcg_callback_IDEname.m файл используйте этот шаблон:
function generatedFiles = plc_postcg_callback_myplcopen(fileNames) % Copyright 2012-2020 The MathWorks, Inc. fileName = fileNames{1}; str = fileread(fileName); % do modifications to str here, f.ex.: % str = regexprep(str,'BOOL_TO_LREAL','BOOL_TO_INT'); % str = regexprep(str,'<USINT/>','<INT/>'); % str = regexprep(str, 'END_STRUCT','END_STRUCT;'); [sHeader,eHeader] = regexp(str,'\(\*.*?\*\)'); header = str(sHeader:eHeader); str = regexprep(str,'<<header_placeholder>>',header); sfprivate ('str2file', str, fileName); generatedFiles = {fileName}; end
Сгенерируйте пользовательский код для пользовательской целевой IDE, выбрав из опций плагина, перечисленных в таблице.
| Имя плагина | Назначение плагина | Когда использовать плагин | Эффект плагина на сгенерированный код |
fConvertBooleanCast | Преобразуйте функцию приведения логического типа в назначение if-else. | Если ваша целевая среда IDE не поддерживает логический тип приведения функции или оператора. | Сгенерированный код с отключенным плагином: Out1 := DINT_TO_INT(BOOL_TO_DINT(In1) +... BOOL_TO_DINT(In2)); Сгенерированный код с включенным плагином: IF In1 THEN
temp1 := DINT#1;
ELSE
temp1 := DINT#0;
END_IF;
IF In2 THEN
temp2 := DINT#1;
ELSE
temp2 := DINT#0;
END_IF;
Out1 := DINT_TO_INT(temp1 + temp2); |
fConvertDoubleToSingle | Преобразуйте двойной тип данных в один тип данных. | Если целевая среда IDE не поддерживает двойные типы данных. Сгенерированный код переменных двойного типа данных преобразуется в отдельные типы данных. Во время генерации кода генерируется предупреждающее сообщение о том, что типы данных, которые не поддерживаются, были найдены и преобразованы. Значения в сгенерированном коде могут отличаться от значений симуляции. | Сгенерированный код с отключенным плагином: VAR_INPUT
ssMethodType: SINT;
U: LREAL;
END_VAR
VAR_OUTPUT
Y: LREAL;
END_VARСгенерированный код с включенным плагином: VAR_INPUT
ssMethodType: SINT;
U: REAL;
END_VAR
VAR_OUTPUT
Y: REAL;
END_VAR |
fConvertDoubleToSingleEmitter | Преобразуйте типы данных double в отдельные типы данных. | Если целевая среда IDE не поддерживает двойные типы данных, и необходимо сохранить значения после преобразования. Сгенерированный код переменных двойного типа данных преобразуется в отдельные типы данных. Во время генерации кода генерируется предупреждающее сообщение о том, что типы данных, которые не поддерживаются, были найдены и преобразованы. Значения в сгенерированном коде совпадают с значениями симуляции, если они не превышают | Сгенерированный код с отключенным плагином: VAR_INPUT
ssMethodType: SINT;
U: LREAL;
END_VAR
VAR_OUTPUT
Y: LREAL;
END_VARСгенерированный код с включенным плагином: VAR_INPUT
ssMethodType: SINT;
U: REAL;
END_VAR
VAR_OUTPUT
Y: REAL;
END_VAR |
fConvertEnumToInteger | Преобразуйте типы данных перечисления в целочисленные типы данных. | Если целевая среда IDE не поддерживает типы данных перечисления. | Сгенерированный код с плагином отключен для целевой IDE, которая поддерживает тип данных перечисления: VAR_TEMP
rtb_Switch: myEnum;
in: myEnum;
END_VARСгенерированный код с включенным плагином: VAR_TEMP
rtb_Switch: DINT;
in: DINT;
END_VAR |
fConvertUnsignedIntToSignedInt | Преобразует беззнаковое целое число в знаковое целое. | Если ваша цель не поддерживает беззнаковый целочисленный тип данных. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: UDINT;
In2: UDINT;
END_VAR
VAR_OUTPUT
Out1: UDINT;
END_VARСгенерированный код с включенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: DINT;
In2: DINT;
END_VAR
VAR_OUTPUT
Out1: DINT;
END_VAR |
fInt32AsBaseInt | Устанавливает тип данных int32 как целое число данных по умолчанию. | Установка int32 как внутреннего целочисленного типа данных по умолчанию может уменьшить количество операций приведения типов в сгенерированном коде. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: SINT;
In2: SINT;
END_VAR
VAR_OUTPUT
Out1: SINT;
END_VAR
Out1 := DINT_TO_SINT(SINT_TO_DINT(In1) +...
SINT_TO_DINT(In2));
END_FUNCTION_BLOCKСгенерированный код с включенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: DINT;
In2: DINT;
END_VAR
VAR_OUTPUT
Out1: DINT;
END_VAR
Out1 := In1 + In2));
END_FUNCTION_BLOCK |
fEmitEnumTypeIntegerValue | Отображает значение перечисления и соответствующее целое число в сгенерированном коде. | Чтобы отобразить значения перечисления и их совпадающие целочисленные значения в сгенерированном коде. | Сгенерированный код с отключенным плагином: TYPE PLCCommandState:
(FILL, HOLD, EMPTY, ACTIVATE);
END_TYPE
TYPE PLCVesselState:
(EMPTIED, NOT_FULL, FULL);
END_TYPE
TYPE PLCValveState:
(SHUT, OPEN);
END_TYPEСгенерированный код с включенным плагином: TYPE PLCCommandState:
(FILL:=0, HOLD:=1, EMPTY:=2, ACTIVATE:=3);
END_TYPE
TYPE PLCVesselState:
(EMPTIED:=0, NOT_FULL:=1, FULL:=2);
END_TYPE
TYPE PLCValveState:
(SHUT:=0, OPEN:=1);
END_TYPE |
| Имя плагина | Назначение плагина | Когда использовать плагин | Эффект плагина на сгенерированный код |
fArrayInitialValueBrackets | Заключает инициализацию массива в область объявления в скобках. | Если ваша целевая IDE требует включения инициализации массива в область объявления в скобках. | Сгенерированный код с отключенным плагином: EnableSetpoint_ZCE: ARRAY [0..2] OF USINT:=3,3,3 Сгенерированный код с включенным плагином:: EnableSetpoint_ZCE: ARRAY [0..2] OF USINT:=[3,3,3] |
fConvertAggregateInitValueToAssignment | Преобразует начальные значения для агрегированных типов данных в оператор назначения. | Целевая IDE не поддерживает инициализацию массива в области объявления. | Сгенерированный код с отключенным плагином: ARRAY [0..1] OF LREAL := LREAL#0.0,LREAL#0.0998 Сгенерированный код с включенным плагином: tb_U[0] := 0.0;
tb_U[1] := 0.0998;
|
fConvertAggregateTypeFunctionToFB | Преобразует функции со совокупными типами данных в функциональный блок (FB). | Целевая IDE поддерживает агрегированные типы данных только для функциональных блоков. | Сгенерированный код с отключенным плагином: function foo(...):ARRAY [0..10] OF LREAL Сгенерированный код с включенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT out1: ARRAY [0..10] OF LREAL; END_VAR |
fConvertFunctionToFB | Преобразуйте функцию в функциональный блок (FB). | Целевая среда IDE не поддерживает | |
fConvertOutputInitValueToAssignment | Преобразуйте инициализацию выходной переменной в назначение. | Целевая среда IDE не разрешает определение начальных значений и требует оператора назначения. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT somevalue: DINT := 100; END_VAR Сгенерированный код с включенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT somevalue: DINT; END_VAR somevalue := 100; |
fEmitVarDeclarationBeforeDescription | Переключает отображение описания переменной до или после объявления переменной. | Целевая IDE требует объявления переменной перед описанием переменной. | Сгенерированный код с отключенным плагином: VAR_GLOBAL CONSTANT K3: REAL := 0.3; END_VAR Сгенерированный код с включенным плагином: VAR_GLOBAL CONSTANT K3: REAL := 0.3; END_VAR |
fErrorOnTrailingUS | Генерация кода прекращается, когда она встречается с именами переменных с конечным подчеркиванием. | Целевая среда IDE не поддерживает имена с конечным подчеркиванием. | Генерация кода завершается ошибкой с этим сообщением |
fHoistArrayIndexExprs | Перемещает выражения из индексов массива и создает временную переменную для выражения. | Целевая IDE не поддерживает выражения для индексов массива. | Сгенерированный код с отключенным плагином: EnvCur[TRUNC(j) - 1] Сгенерированный код с включенным плагином: temp1 := TRUNC(j) - 1; EnvCur[temp1] |
fSimplifyFunctionCallExpr | Упрощает вызов функции для простых функций. | Целевая среда IDE не разрешает выражения назначения в вызовах функций. | Сгенерированный код с отключенным плагином: y := simplefunction(u_0 := u); Сгенерированный код с включенным плагином: y := simplefunction(u); |
fUseQualifiedTypeConstant | Добавляет тип данных к постоянному объявлению. | Целевая IDE требует тип данных для констант. | Сгенерированный код с отключенным плагином: a := 11; Сгенерированный код с включенным плагином: a := DINT#11; |
| Имя плагина | Назначение плагина | Когда использовать плагин | Эффект плагина на сгенерированный код |
fConvertTunableParamToInputVariable | Преобразует настраиваемые параметры в входные переменные функционального блока (FB). | Вы хотите преобразовать настраиваемые параметры в входы функциональных блоков. Это позволяет вам вызвать POU с различными наборами параметров. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Tunable_Param_to_Input
24 VAR_INPUT
25 ssMethodType: SINT;
26 Input1: REAL;
27 END_VAR
28 VAR_OUTPUT
29 Output1: REAL;
30 END_VAR
31 VAR
32 DSTATE: REAL;
33 END_VAR
34 'ST'
35 BODY
36 CASE ssMethodType OF
37 0:
40 UnitDelay_DSTATE := 0.0;
41
42 1:
43 Output1 := (Input1 - DSTATE) *
TunableParam;
48 DSTATE := Output1;
50 END_CASE;
52 END_BODY
53 END_FUNCTION_BLOCK
54 TunableParam переменная не объявлена как вход в функциональный блок.Сгенерированный код с включенным плагином: FUNCTION_BLOCK Tunable_Param_to_Input
24 VAR_INPUT
25 TunableParam: LREAL;
26 ssMethodType: SINT;
27 Input1: REAL;
28 END_VAR
29 VAR_OUTPUT
30 Output1: REAL;
31 END_VAR
32 VAR
33 DSTATE: REAL;
34 END_VAR
35 'ST'
36 BODY
37 CASE ssMethodType OF
38 0:
39 DSTATE := 0.0;
42
43 1:
44 Output1 := (Input1 - DSTATE) *
TunableParam;
49 DSTATE := Output1;
51
52 END_CASE;
53 END_BODY
54 END_FUNCTION_BLOCK
55 TunableParam переменная объявлена как вход в функциональный блок. |
fDefineFBExternalConstVariable | Определяет внешние переменные в | Целевая IDE требует объявления внешних переменных константы в | Сгенерированный код с отключенным плагином: VAR_GLOBAL CONSTANT
SS_INITIALIZE: SINT := 0;
K3: LREAL := 0.3;
SS_STEP: SINT := 1;
END_VARСгенерированный код с включенным плагином: VAR_GLOBAL CONSTANT
K3: REAL := 0.3; |
fDefineFBExternalVariable | Задает внешние константы в | Целевая IDE требует объявления внешних констант в | Сгенерированный код с отключенным плагином: VAR
UnitDelay_DSTATE: LREAL;
i0_ExternallyDefinedBlock: ExternallyDefinedBlock;
END_VARСгенерированный код с включенным плагином: VAR_EXTERNAL
K1: REAL;
END_VAR |
fReplaceShiftFunctions | Заменяет целевые функции сдвига IDE функциями, соответствующими поведению функции сдвига Simulink. | Когда количество сдвигов больше, чем длина типа данных, происходит несоответствие между выходом блока сдвига Simulink и целевым блоком сдвига IDE. Используйте этот плагин для замены целевых блоков сдвига IDE блоками сдвига Simulink в сгенерированном коде. | Сгенерированный код с отключенным плагином: Out10 := WORD_TO_INT(SHL(IN:=INT_TO_WORD(In1),... N:=Out2_tmp)); SHL сдвиг.Сгенерированный код с включенным плагином: Out10 := WORD_TO_INT(PLC_SHL(INT_TO_WORD(In1),...
DINT_TO_USINT(Out2_tmp)));
FUNCTION PLC_SHL: WORD
VAR_INPUT
in1: WORD;
in2: USINT;
END_VAR
'ST'
BODY
IF in2 > 16 THEN
PLC_SHL := 16#0;
ELSE
PLC_SHL := SHL(in1, in2);
END_IF;
END_BODY
END_FUNCTIONPLC_SHL, который наследует блок сдвига Simulink в целевой IDE. |
| Имя плагина | Назначение плагина | Когда использовать плагин | Эффект плагина на сгенерированный код |
fSimplifyAllIntrinsicFcn | Упрощает входы всех внутренних функций. | Целевая IDE не разрешает составные выражения как часть внутренних аргументов функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: t1 := x*y; a := SQRT(t1); |
fSimplifyIntrinsicFcn | Упрощает внутренние функции, которые являются аргументами | Целевая IDE не разрешает составные выражения как часть внутренних аргументов функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyIntrinsicFcnNameList = { 'SQRT' \}
cfg.fSimplifyIntrinsicFcn = true;
t1 := x*y;
a := SQRT(t1); |
fSimplifyIntrinsicFcnNameList | Создает список внутренних функций. Входные параметры этих внутренних функций упрощены при помощи | Целевая IDE не разрешает составные выражения как часть внутренних аргументов функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyIntrinsicFcnNameList = { 'SQRT' \}
cfg.fSimplifyIntrinsicFcn = true;
t1 := x*y;
a := SQRT(t1); |
fSimplifyOperator | Упрощает входы перечисленных функций оператора при помощи | Целевая IDE не разрешает составные выражения как часть аргументов функции оператора. | Сгенерированный код с отключенным плагином: a := SHL(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyOperatorNameList = { 'SHL' \}
cfg.fSimplifyOperator = true;
t1 := x*y;
a := SHL(t1); |
fSimplifyOperatorNameList | Создает список функций оператора. Входные параметры этих функций оператора упрощены при помощи | Целевая IDE не разрешает составные выражения как часть аргументов функции оператора. | Сгенерированный код с отключенным плагином: a := SHL(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyOperatorNameList = { 'SHL' \}
cfg.fSimplifyOperator = true;
t1 := x*y;
a := SHL(t1); |
fSimplifyTrunc | Упрощает входы | Целевая IDE не разрешает составные выражения в качестве аргументов для | Сгенерированный код с отключенным плагином: a := TRUNC(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyTrunc = true; t1 := x*y; a := SHL(t1); |
В этом примере показано, как сгенерировать код для пользовательской целевой IDE my PLCopen XMLпри помощи плагинов.
Создайте папку с именем myplcopen. Создайте plc_custom_ide.m файл в папке с помощью этого шаблона:
function plc_ide_list = plc_custom_ide % Copyright 2012-2021 The MathWorks, Inc. plc_ide_list(1) = get_ide_info_myplcopen; end function ide_info = get_ide_info_myplcopen ide_info.name = 'myplcopen'; ide_info.description = 'My PLCopen XML'; ide_info.path = ''; % IDE path ide_info.format = 'xml'; % generic|xml ide_info.fileExtension = 'xml'; ide_info.cfg = get_ide_cfg_myplcopen; ide_info.precg_callback = 'plc_precg_callback_myplcopen'; ide_info.postcg_callback = 'plc_postcg_callback_myplcopen'; ide_info.xmltree_callback = PLCCoder.PLCCGMgr.PLC_PLUGIN_CG_CALLBACK_EMPTY; ide_info.pluginVersion = 2.2; ide_info.compatibleBuildVersion = 1.6; end function cfg = get_ide_cfg_myplcopen cfg.fConvertDoubleToSingle = true; cfg.fConvertNamedConstantToInteger = true; cfg.fConvertEnumToInteger = true; cfg.fConvertOutputInitValueToAssignment = true; cfg.fConvertTunableParamToInputVariable = true; cfg.fSimplifyFunctionCallExpr = true; cfg.fConvertOutputInitValueToAssignment = true; end
Установите опции плагина в function_cfg раздел файла. Чтобы включить плагин, установите опцию плагина равным true. Например, cfg.fArrayInitialValueBrackets = true; включает плагин. Чтобы отключить плагин, установите опцию плагина равным false.
Создание plc_precg_callback_IDEname.m и plc_postcg_callback_IDEname.m файлы при помощи следующих шаблонов:
function controller = plc_precg_callback_myplcopen(controller) % Copyright 2012-2020 The MathWorks, Inc. % do modifications to the controller struct here, f.ex.: for i = 1:length(controller.components) controller.components(i).body = sprintf('<<header_placeholder>>\r\n%s',controller.components(i).body); end end
function generatedFiles = plc_postcg_callback_myplcopen(fileNames) % Copyright 2012-2020 The MathWorks, Inc. fileName = fileNames{1}; str = fileread(fileName); % do modifications to str here, f.ex.: % str = regexprep(str,'BOOL_TO_LREAL','BOOL_TO_INT'); % str = regexprep(str,'<USINT/>','<INT/>'); % str = regexprep(str, 'END_STRUCT','END_STRUCT;'); [sHeader,eHeader] = regexp(str,'\(\*.*?\*\)'); header = str(sHeader:eHeader); str = regexprep(str,'<<header_placeholder>>',header); sfprivate ('str2file', str, fileName); generatedFiles = {fileName}; end
Создайте plc_header_hook.m файл при помощи этого шаблона:
function headerCommentText = plc_header_hook(filePath, blockH, headerCommentText) headerCommentText = [headerCommentText(1:end-7) ... sprintf([' * Plugin Header Copy : Yes \n']) ... headerCommentText(end-6:end)]; end
The plc_header_hook.m файл копирует информацию о заголовке в начале сгенерированного файла кода в каждый образец функционального блока.
Добавьте новую папку и файлы в путь MATLAB.
Щелкните правой кнопкой мыши папку и выберите Add to Path > Selected Folders and Subfolders.
Используйте addpath функция. Для примера, addpath(genpath('path to your folder')).
Выполните эту команду:
plccoderpref('plctargetidepaths','default')
Перезапустите Сеанс работы с MATLAB.
Откройте модель и выберите компонент модели для генерации кода. Откройте PLC Coder приложение. Нажмите Settings. На панели PLC Code Generation, в Target IDE, выберите My PLCopen XML. Нажмите OK.

В приложении PLC Coder, PLC Code вкладке, нажмите Generate PLC Code, чтобы сгенерировать код для пользовательской целевой IDE. Сгенерированные коды помещаются в путь, указанный в ide_info.path = ''; % IDE path.