Чтобы использовать оптимизацию читаемости в коде, вы должны иметь Embedded Coder® лицензия. Эти оптимизации появляются только в коде, который вы генерируете для встроенного реального времени (ert
) цель.
Примечание
Эти оптимизации не применяются к MATLAB® файлы, которые вы вызываете из блока MATLAB Function.
Дополнительные сведения см. в разделе Настройка системного целевого файла.
Когда вы генерируете код для встроенных целей в реальном времени, можно выбрать преобразование if-elseif-else
логика принятия решений в switch-case
операторы. Это преобразование может улучшить читаемость кода.
Для примера, когда блок MATLAB Function содержит длинный список условий, switch-case
структура:
Уменьшает использование круглых скобок и скобок
Минимизирует повторение в сгенерированном коде
Следующая процедура описывает, как преобразовать сгенерированный код для блока MATLAB Function из if-elseif-else
на switch-case
операторы.
Шаг | Задача | Ссылка |
---|---|---|
1 | Проверьте, что ваш блок соответствует правилам преобразования. | Проверка содержимого блока |
2 | Включите преобразование. | Включение преобразования |
3 | Сгенерируйте код для вашей модели. | Генерация кода для вашей модели |
Для выполнения преобразования необходимо соблюдать следующие правила. LHS и RHS относятся к левой и правой частям условия, соответственно.
Конструкция | Правила, которым необходимо следовать |
---|---|
MATLAB Function блок | Должно быть два или более уникальных условия, в дополнение к стандарту по умолчанию. Для получения дополнительной информации смотрите, Как Преобразование Обрабатывает Дублирование Условий. |
Каждое условие | Должен проверять только равенство. |
Необходимо использовать ту же переменную или выражение для LHS. Примечание Можно сторнировать LHS и RHS. | |
Каждая LHS | Должно быть одной переменной или выражением, а не составным оператором. |
Не может быть константой. | |
Должен иметь целое число или перечисленный тип данных. | |
Не должно иметь побочных эффектов на симуляции. Например, LHS может считать, но не записывать в глобальные переменные. | |
Каждая RHS | Должно быть константой. |
Должен иметь целое число или перечисленный тип данных. |
Если блок MATLAB Function имеет повторяющиеся условия, преобразование сохраняет только первое условие. Сгенерированный код отбрасывает другие образцы повторяющихся условий.
После удаления дубликатов должны существовать два или более уникальных условия. В противном случае преобразование не происходит, и сгенерированный код содержит образцы повторяющихся условий.
Следующие примеры показывают, как преобразование обрабатывает дублирование условий.
Пример сгенерированного кода | Код после преобразования |
---|---|
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 Function блоком. Предположим, что тип выходных данных double
и тип входных данных Controller
, перечисленный тип, который вы задаете.
Блок содержит следующий код:
function system = fcn(type) %#codegen if (type == Controller.P) system = 0; elseif (type == Controller.I) system = 1; elseif (type == Controller.PD) system = 2; elseif (type == Controller.PI) system = 3; elseif (type == Controller.PID) system = 4; else system = 10; end
Определение перечисленного типа в Controller.m
является:
classdef Controller < Simulink.IntEnumType enumeration P(0) I(1) PD(2) PI(3) PID(4) UNKNOWN(10) end end
Если вы генерируете код для встроенной цели в реальном времени с помощью настроек по умолчанию, вы видите что-то подобное:
if (if_to_switch_eml_blocks_U.In1 == P) { /* '<S1>:1:4' */ /* '<S1>:1:5' */ if_to_switch_eml_blocks_Y.Out1 = 0.0; } else if (if_to_switch_eml_blocks_U.In1 == I) { /* '<S1>:1:6' */ /* '<S1>:1:7' */ if_to_switch_eml_blocks_Y.Out1 = 1.0; } else if (if_to_switch_eml_blocks_U.In1 == PD) { /* '<S1>:1:8' */ /* '<S1>:1:9' */ if_to_switch_eml_blocks_Y.Out1 = 2.0; } else if (if_to_switch_eml_blocks_U.In1 == PI) { /* '<S1>:1:10' */ /* '<S1>:1:11' */ if_to_switch_eml_blocks_Y.Out1 = 3.0; } else if (if_to_switch_eml_blocks_U.In1 == PID) { /* '<S1>:1:12' */ /* '<S1>:1:13' */ if_to_switch_eml_blocks_Y.Out1 = 4.0; } else { /* '<S1>:1:15' */ if_to_switch_eml_blocks_Y.Out1 = 10.0; }
Переменная LHS if_to_switch_eml_blocks_U.In1
появляется несколько раз в сгенерированном коде.
Примечание
По умолчанию переменные, которые появляются в блоке, не сохраняют свои имена в сгенерированном коде. Измененные идентификаторы предотвращают конфликты по совпадению имен.
Комментарии трассируемости появляются между каждым набором /*
и */
маркеры. Дополнительные сведения о трассируемости см. в разделе Использование трассируемости в блоках MATLAB function.
Проверьте, что блок соответствует правилам в Rules for Conversion.
Конструкция | Как конструкция следует правилам |
---|---|
MATLAB Function блок | Сложение к стандарту по умолчанию существует пять уникальных условий:
|
Каждое условие | Каждое условие:
|
Каждая LHS | Каждая LHS:
|
Каждая RHS | Каждая RHS:
|
Откройте диалоговое окно Параметры конфигурации.
На панели Code Generation выберите ert.tlc
для System target file.
Этот шаг задает встроенную цель в реальном времени для вашей модели.
На панели Code Generation > Code Style установите флажок Convert if-elseif-else patterns to switch-case statements.
Совет
Это преобразование работает на базисе по модели. Если установлен этот флажок, преобразование применяется к:
MATLAB Function блоки в модели
Функции MATLAB в Stateflow® графики этой модели
Поток графиков в диаграммах Stateflow этой модели
Для получения дополнительной информации см. Раздел «Улучшение читаемости кода для Графиков потока».
В окне модели нажмите Ctrl+B.
Код для блока MATLAB Function использует switch-case
операторы вместо if-elseif-else
код:
switch (if_to_switch_eml_blocks_U.In1) { case P: /* '<S1>:1:4' */ /* '<S1>:1:5' */ if_to_switch_eml_blocks_Y.Out1 = 0.0; break; case I: /* '<S1>:1:6' */ /* '<S1>:1:7' */ if_to_switch_eml_blocks_Y.Out1 = 1.0; break; case PD: /* '<S1>:1:8' */ /* '<S1>:1:9' */ if_to_switch_eml_blocks_Y.Out1 = 2.0; break; case PI: /* '<S1>:1:10' */ /* '<S1>:1:11' */ if_to_switch_eml_blocks_Y.Out1 = 3.0; break; case PID: /* '<S1>:1:12' */ /* '<S1>:1:13' */ if_to_switch_eml_blocks_Y.Out1 = 4.0; break; default: /* '<S1>:1:15' */ if_to_switch_eml_blocks_Y.Out1 = 10.0; break; }
The switch-case
операторы обеспечивают следующие преимущества для повышения читабельности:
Код сокращает использование круглых скобок и скобок.
Переменная LHS if_to_switch_eml_blocks_U.In1
появляется только один раз, минимизируя повторение в коде.