Если у вас есть 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 операторы.