Simulink® PLC Coder™ в настоящее время поддерживает основанные на плагине целевые ИДЫ, такие как Селектрон CAP1131, Studio Omron Sysmac, и так далее. Для ваших основанных на плагине пользовательских целевых ИД, которые не поддерживаются, сгенерируйте PLCOpen XML-или совместимый ASCII код структурированного текста. Настройте сгенерированный код, чтобы удовлетворить ваши целевые требования IDE путем усиления встроенных сменных опций в Simulink PLC Coder.
Сгенерировать код для ваших пользовательских основанных на плагине целевых ИД:
Следуйте блок-схеме, чтобы создать 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
файлы.
Предварительная обработка файла коллбэка. 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
Постобработка файла коллбэка. 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 | Преобразуйте булеву функцию броска типа в если еще присвоение. | Если ваш целевой 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 | Преобразуйте двойные типы данных в один типы данных. | Если ваш целевой 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
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
.