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_FUNCTION PLC_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
.