Если у вас есть лицензия Embedded Coder®, и вы генерируете код для моделей, которые включают объекты Stateflow®, код из блок-схемы напоминает выборки, которые следуют.
Следующие характеристики применяются:
По умолчанию сгенерированный код использует операторы if-elseif-else
, чтобы представлять шаблоны switch
. Чтобы преобразовать код, чтобы использовать операторы switch-case
, смотрите, Преобразовывают Код If-Elseif-Else в Операторов case оператора switch.
По умолчанию переменные, которые появляются в блок-схеме, не сохраняют свои имена в сгенерированном коде. Измененные идентификаторы убеждаются, что никакие конфликты по совпадению имен не происходят.
Комментарии трассируемости для переходов появляются между каждым набором маркерами */
и /*
. Чтобы узнать больше о трассируемости, смотрите Трассировку Элементы 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
. Это преобразование может улучшить удобочитаемость кода. Например, когда блок-схема содержит длинный список условий, структуры switch-case
:
Уменьшает использование круглых скобок и фигурных скобок
Минимизирует повторение в сгенерированном коде
Следующая процедура описывает, как преобразовать сгенерированный код для блок-схемы от if-elseif-else
до операторов switch-case
.
Шаг | Задача | Ссылка |
---|---|---|
1 | Проверьте, что ваша блок-схема следует правилам для преобразования. | Проверьте содержимое блок-схемы |
2 | Включите преобразование. | Включите преобразование |
3 | Сгенерируйте код для своей модели. | Сгенерируйте код для своей модели |
4 | Диагностируйте сгенерированный код.
| Диагностируйте сгенерированный код |
Для преобразования, чтобы произойти, следующие правила должны содержать. 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 } | Никакое изменение, потому что только одно уникальное условие существует |
Предположим, что у вас есть следующая модель с сингл чартом.
График содержит блок-схему и четыре функции MATLAB®:
Функции MATLAB в графике содержат код в следующей таблице. В каждом случае Function Inline Option является Auto
. Для получения дополнительной информации о функциональном встраивании, смотрите Specify Graphical Function Properties (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).
Проверяйте, что блок-схема в вашем графике следует правилам в Правилах Преобразования.
Создать | Как построение следует правилам |
---|---|
Блок-схема | Два уникальных условия существуют, в дополнение к значению по умолчанию:
|
Каждое условие | Каждое условие:
|
Каждый 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 в той модели
В модели выберите Code> C/C++ Code> Build Model, чтобы сгенерировать исходный код из модели.
Сгенерированный код для блок-схемы появляется что-то вроде этого:
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
не кажется встроенным. Смотрите Изменение Свойство Встраивания для Функции.
Измените блок-схему. Смотрите Изменяют Блок-схему, чтобы Гарантировать Операторов case оператора switch.
Измените Свойство Встраивания для Функции. Если вы не хотите изменять свою блок-схему, изменять свойство встраивания для функционального light
:
Щелкните правой кнопкой по функциональному полю для light
и выберите Properties.
Диалоговое окно свойств появляется.
Для Function Inline Option выберите Function
.
Нажмите OK, чтобы закрыть диалоговое окно.
Вы не должны изменять свойство встраивания для других трех функций MATLAB в графике. Поскольку блок-схема не вызывает те функции во время оценки условий, свойство встраивания для тех функций может остаться 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)
появляется только однажды, минимизируя повторение в коде.
Измените Блок-схему, чтобы Гарантировать Операторов case оператора switch. Если вы не хотите изменять свойство встраивания для функционального light
, измените свою блок-схему:
Добавьте график локальные данные color_out
с перечислимым типом TrafficLights
.
Замените каждый экземпляр light(intersection)
с color_out
.
Добавьте действие {color_out = light(intersection)}
в переход по умолчанию блок-схемы.
График должен теперь выглядеть примерно так:
Когда вы регенерируете код для своей модели, код для блок-схемы использует операторы switch-case
.