Если у вас есть Embedded Coder® и вы генерируете код для моделей, которые включают Stateflow® объекты, код из потока графика напоминает следующие выборки.
Применяются следующие характеристики:
По умолчанию сгенерированный код использует if-elseif-else
операторы для представления switch
шаблоны. Чтобы преобразовать код в используемый switch-case
инструкции см. в разделе Преобразование кода if-Elseif-Else в операторы Switch-Case.
По умолчанию переменные, которые появляются в график потока, не сохраняют свои имена в сгенерированном коде. Измененные идентификаторы гарантируют отсутствие конфликтов по совпадению имен.
Комментарии трассируемости для переходов появляются между каждым набором /*
и */
маркеры. Дополнительные сведения о трассируемости см. в разделе Трассировка элементов Stateflow в Сгенерированном коде.
Образец кода для логического шаблона принятия решения
if (modelname_U.In1 == 1.0) { /* Transition: '<S1>:11' */ /* Transition: '<S1>:12' */ modelname_Y.Out1 = 10.0; /* Transition: '<S1>:15' */ /* Transition: '<S1>:16' */ } else { /* Transition: '<S1>:10' */ if (modelname_U.In1 == 2.0) { /* Transition: '<S1>:13' */ /* Transition: '<S1>:14' */ modelname_Y.Out1 = 20.0; /* Transition: '<S1>:16' */ } else { /* Transition: '<S1>:17' */ modelname_Y.Out1 = 30.0; } }
Пример кода для итерационного шаблона цикла
for (sf_i = 0; sf_i < 10; sf_i++) { /* Transition: '<S1>:40' */ /* Transition: '<S1>:41' */ modelname_B.y = modelname_B.y + modelname_U.In1; /* Transition: '<S1>:39' */ }
Пример кода для шаблона коммутатора
if (modelname_U.In1 == 1.0) { /* Transition: '<S1>:149' */ /* Transition: '<S1>:150' */ modelname_Y.Out1 = 1.0; /* Transition: '<S1>:151' */ /* Transition: '<S1>:152' */ /* Transition: '<S1>:158' */ /* Transition: '<S1>:159' */ } else { /* Transition: '<S1>:156' */ if (modelname_U.In1 == 2.0) { /* Transition: '<S1>:153' */ /* Transition: '<S1>:154' */ modelname_Y.Out1 = 2.0; /* Transition: '<S1>:155' */ /* Transition: '<S1>:158' */ /* Transition: '<S1>:159' */ } else { /* Transition: '<S1>:161' */ modelname_Y.Out1 = 3.0; } }
If-Elseif-Else
Код для Switch-Case
ОператорыКогда вы генерируете код для встроенных целей в реальном времени, можно выбрать преобразование if-elseif-else
код для switch-case
операторы. Это преобразование может улучшить читаемость кода. Для примера, когда график потока данных содержит длинный список условий, switch-case
структура:
Уменьшает использование круглых скобок и скобок
Минимизирует повторение в сгенерированном коде
If-Elseif-Else
Код для Switch-Case
ОператорыШаг | Задача | Ссылка |
---|---|---|
1 | Проверьте, что ваш график потока следует правилам преобразования. | Проверьте содержимое Графика потока |
2 | Включите преобразование и сгенерируйте код для вашей модели. | Включите преобразование |
3 | Диагностируйте сгенерированный код.
| Поиск и устранение проблем с сгенерированным кодом |
Чтобы преобразование произошло, следуйте этим рекомендациям. LHS и RHS относятся к левой и правой частям условия, соответственно.
Конструкция | Правила, которым необходимо следовать |
---|---|
Блок- график | Должно быть задано значение по умолчанию и два или более уникальных условий. Для получения дополнительной информации см. Раздел «Повторяющиеся условия». |
Каждое условие | Должен проверять только равенство. |
Необходимо использовать ту же переменную или выражение для LHS. Можно сторнировать LHS и RHS. | |
Каждая LHS | Должно быть одной переменной или выражением. |
Не может быть константой. | |
Должен иметь целое число или перечисленный тип данных. | |
Не может иметь никаких побочных эффектов на симуляции. Например, LHS может считать, но не записывать в глобальные переменные. | |
Каждая RHS | Должен быть константой или параметром. |
Должен иметь целое число или перечисленный тип данных. |
Если график потока имеет повторяющиеся условия, преобразование сохраняет только первое условие. Код отбрасывает другие образцы повторяющихся условий.
После удаления дубликатов должны существовать два или более уникальных условия. Если нет, преобразование не происходит, и код содержит все повторяющиеся условия.
Пример сгенерированного кода | Код после преобразования |
---|---|
if (x == 1) { block1 } else if (x == 2) { block2 } else if (x == 1) { // duplicate block3 } else if (x == 3) { block4 } else if (x == 1) { // duplicate block5 } else { block6 } |
switch (x) { case 1: block1; break; case 2: block2; break; case 3: block4; break; default: block6; break; } |
if (x == 1) { block1 } else if (x == 1) { // duplicate block2 } else { block3 } | Никаких изменений, потому что существует только одно уникальное условие |
Switch-Case
ОператорыПредположим, что эта модель содержит один график.
График содержит блок-схему и четыре MATLAB® функций.
Функции MATLAB на графике содержат код, указанный в таблице. В каждом случае Function Inline Option Auto
. Дополнительные сведения о встраивании функции см. в разделе «Задание свойств графических функций (Stateflow)».
Функция MATLAB | Код |
---|---|
stop |
function stop %#codegen coder.extrinsic('disp'); disp('Not moving.') traffic_speed = 0; |
slowdown |
function slowdown %#codegen coder.extrinsic('disp') disp('Slowing down.') traffic_speed = 1; |
accelerate |
function accelerate %#codegen coder.extrinsic('disp'); disp('Moving along.') traffic_speed = 2; |
light |
function color = light(x) %#codegen if (x < 20) color = TrafficLights.GREEN; elseif (x >= 20 && x < 25) color = TrafficLights.YELLOW; else color = TrafficLights.RED; end |
Область выхода color
функции light
использует перечисляемый тип TrafficLights
. Определение перечисленного типа в TrafficLights.m
является:
classdef TrafficLights < Simulink.IntEnumType enumeration RED(0) YELLOW(5) GREEN(10) end end
Для получения дополнительной информации смотрите Задать перечисленные типы данных (Stateflow).
Проверяйте, что графики потока на вашей диаграмме Stateflow следуют правилам в Rules of Conversion.
Конструкция | Как конструкция следует правилам |
---|---|
Блок- график | Существует условие по умолчанию и два уникальных условия:
|
Каждое условие | Каждое условие:
|
Каждая LHS | Каждая LHS:
|
Каждая RHS | Каждая RHS:
|
Откройте диалоговое окно Параметры конфигурации модели (Model Configuration Parameters).
На панели Code Generation выберите ert.tlc
для System target file для целевого объекта на основе ERT для вашей модели.
На панели Code Generation > Code Style установите флажок Convert if-elseif-else patterns to switch-case statements.
Если установлен этот флажок, преобразование применяется к:
Поток графиков во всех графиках модели
Функции MATLAB во всех графиках модели
Все блоки MATLAB Function в этой модели
В модели на вкладке C Code нажмите Build, чтобы сгенерировать исходный код из модели.
Сгенерированный код для графика потока появляется как этот код:
if (sf_color == RED) { /* Transition: '<S1>:11' */ /* Transition: '<S1>:12' */ /* MATLAB Function 'stop': '<S1>:23' */ /* '<S1>:23:6' */ rtb_traffic_speed = 0; /* Transition: '<S1>:15' */ /* Transition: '<S1>:16' */ } else { /* Transition: '<S1>:10' */ /* MATLAB Function 'light': '<S1>:19' */ if (ifelse_using_enums_U.In1 < 20.0) { /* '<S1>:19:3' */ /* '<S1>:19:4' */ sf_color = GREEN; } else if ((ifelse_using_enums_U.In1 >= 20.0) && (ifelse_using_enums_U.In1 < 25.0)) { /* '<S1>:19:5' */ /* '<S1>:19:6' */ sf_color = YELLOW; } else { /* '<S1>:19:8' */ sf_color = RED; } if (sf_color == YELLOW) { /* Transition: '<S1>:13' */ /* Transition: '<S1>:14' */ /* MATLAB Function 'slowdown': '<S1>:24' */ /* '<S1>:24:6' */ rtb_traffic_speed = 1; /* Transition: '<S1>:16' */ } else { /* Transition: '<S1>:17' */ /* MATLAB Function 'accelerate': '<S1>:25' */ /* '<S1>:25:6' */ rtb_traffic_speed = 2; } }
Потому что функция MATLAB light
появляется встроенным, сравнения неравенства появляются в этих строках кода:
if (ifelse_using_enums_U.In1 < 20.0) { .... } else if ((ifelse_using_enums_U.In1 >= 20.0) && (ifelse_using_enums_U.In1 < 25.0)) { ....
Потому что неравенство появляется в теле if-elseif-else
код для графика потока, преобразования в switch-case
операторы не появляются. Выполните одно из следующих действий:
Задайте, что функция light
не отображается встроенным. См. «Изменение свойства Inlining» для функции.
Измените график потока. См. «Изменение Графика потока для обеспечения Операторов Switch-Case».
Измените свойство Inlining для функции. Если вы не хотите изменять график потока, измените свойство inlining для функции light
:
Щелкните правой кнопкой мыши функциональное поле для light
и выберите Properties.
В диалоговом окне свойств для Function Inline Option выберите Function
.
Нажмите кнопку OK, чтобы закрыть диалоговое окно.
Примечание
Вы не должны изменять свойство inlining для других трех функций MATLAB на графике. Поскольку график потока не вызывает эти функции во время оценки условий, свойство inlining для этих функций может остаться Auto
.
Когда вы регенерируете код для модели, код для графика потока теперь появляется как этот код:
switch (ifelse_using_enums_light(ifelse_using_enums_U.In1)) { case RED: /* Transition: '<S1>:11' */ /* Transition: '<S1>:12' */ /* MATLAB Function 'stop': '<S1>:23' */ /* '<S1>:23:6' */ ifelse_using_enums_Y.Out1 = 0.0; /* Transition: '<S1>:15' */ /* Transition: '<S1>:16' */ break; case YELLOW: /* Transition: '<S1>:10' */ /* Transition: '<S1>:13' */ /* Transition: '<S1>:14' */ /* MATLAB Function 'slowdown': '<S1>:24' */ /* '<S1>:24:6' */ ifelse_using_enums_Y.Out1 = 1.0; /* Transition: '<S1>:16' */ break; default: /* Transition: '<S1>:17' */ /* MATLAB Function 'accelerate': '<S1>:25' */ /* '<S1>:25:6' */ ifelse_using_enums_Y.Out1 = 2.0; break; }
Потому что функция MATLAB light
больше не отображается встроенным, преобразование в switch-case
имеют место операторы. Чтобы улучшить читаемость, switch-case
операторы обеспечивают следующие преимущества:
Код сокращает использование круглых скобок и скобок.
Выражение LHS ifelse_using_enums_light(ifelse_using_enums_U.In1)
появляется только один раз, минимизируя повторение в коде.
Измените График потока, чтобы убедиться, что операторы Switch-Case. Если вы не хотите изменять свойство inlining для функции light
, измените свой поток графику:
Добавьте локальные данные графики color_out
с перечисленным типом TrafficLights
.
Замените каждый образец light(intersection)
с color_out
.
Добавьте действие {color_out = light(intersection)}
к переходу по умолчанию график потока.
Теперь график выглядит аналогично этому графику:
Когда вы регенерируете код для модели, код для графика потока операций использует switch-case
операторы.