Из-за ограничений, описанных в Generate Reentrant Code from Subsystems, генератор кода может не использовать сгенерированный код повторно, как вы ожидаете. Чтобы определить, почему код, сгенерированный для подсистемы, не используется повторно:
Проверьте раздел «Подсистемы» отчета о генерации кода.
Сравнение данных контрольной суммы подсистемы.
Если генератор кода не генерирует код для подсистемы как повторно используемый код, и вы сконфигурировали подсистему как повторно используемую, исследуйте раздел Subsystems отчета генерации кода (см. «Генерация отчета генерации кода»). Раздел «Подсистемы» содержит:
Таблица, в которой результирующее описание преобразования невиртуальных подсистем в сгенерированный код.
Диагностическая информация, которая описывает, почему подсистемы не были сгенерированы как повторно используемый код.
Раздел Subsystems также сопоставляет неинлинфицированные подсистемы в модели с функциями или повторно используемыми функциями в сгенерированном коде. Для примера откройте и создайте rtwdemo_atomic
модель.
Можно определить, почему код подсистемы не используется повторно, сравнивая данные контрольной суммы подсистемы. Генератор кода определяет, являются ли подсистемы идентичными, путем сравнения контрольных сумм подсистемы, как отмечено в Ограничениях. Для повторного использования подсистемы между ссылочными моделями эта процедура может не помечать каждое различие.
Рассмотрим модель, rtwdemo_ssreuse
. SS1
и SS2
являются образцами одной и той же подсистемы. В оба образцов параметров блоков подсистемы Function packaging установлено на Reusable function
.
Используйте метод Simulink.SubSystem.getChecksum
для получения контрольной суммы для подсистемы. Проверьте результаты, чтобы определить, почему код не используется повторно.
Откройте модель rtwdemo_ssreuse
. Сохраните копию модели в папке, где у вас есть доступ для записи.
Ассоциируйте подсистемы SS1
и SS2
с gcb
. Для каждой из подсистем в окне модели выберите подсистему. Пока подсистема выбрана, в Командном окне введите:
SS1 = gcb;
SS2 = gcb;
Используйте метод Simulink.SubSystem.getChecksum
для получения контрольной суммы для каждой подсистемы. Этот метод возвращает два выхода значения: значение контрольной суммы и детали о входе, используемой для вычисления контрольной суммы.
[chksum1, chksum1_details] = ... Simulink.SubSystem.getChecksum(SS1); [chksum2, chksum2_details] = ... Simulink.SubSystem.getChecksum(SS2);
Сравните два значения контрольной суммы. Значения должны быть равными на основе строений подсистемы.
isequal(chksum1, chksum2) ans = 1
Использовать Simulink.SubSystem.getChecksum
чтобы определить, почему контрольные суммы двух подсистем различаются, измените режим типа данных выходного порта SS1 так, чтобы он отличался от режима SS2.
Посмотрите под маской SS1
. Щелкните подсистему правой кнопкой мыши. В контекстном меню выберите Mask > Look Under Mask.
На схеме подсистемы дважды кликните блок Lookup Table, чтобы открыть диалоговое окно Параметры.
Нажмите Data Types.
Выберите параметры блоков Saturate on integer overflow и нажатие кнопки OK.
Получите контрольную сумму для SS1
. Сравните контрольные суммы для двух подсистем. На этот раз контрольные суммы не равны.
[chksum1, chksum1_details] = ... Simulink.SubSystem.getChecksum(SS1); isequal(chksum1, chksum2) ans = 0
После того, как вы определите, что контрольные суммы различаются, узнайте, почему. Simulink® Для вычисления контрольных сумм система использует информацию, такую как типы данных сигналов, некоторые значения параметров блоков и информация о связности блоков. Чтобы определить, почему контрольные суммы отличаются, сравните данные, которые вычисляют значения контрольной суммы. Вы можете получить эту информацию из второго значения, возвращенного Simulink.SubSystem.getChecksum
, который является массивом структур с четырьмя полями.
Посмотрите на структуру chksum1_details
.
chksum1_details chksum1_details = ContentsChecksum: [1x1 struct] InterfaceChecksum: [1x1 struct] ContentsChecksumItems: [287x1 struct] InterfaceChecksumItems: [53x1 struct]
ContentsChecksum
и InterfaceChecksum
являются контрольными суммами компонентов контрольной суммы подсистемы. Оставшиеся два поля, ContentsChecksumItems
и InterfaceChecksumItems
, содержат подробные данные контрольной суммы.
Определите, существует ли различие в содержимом подсистемы, интерфейсе или в обоих интерфейсах. Для примера:
isequal(chksum1_details.ContentsChecksum.Value,... chksum2_details.ContentsChecksum.Value) ans = 0 isequal(chksum1_details.InterfaceChecksum.Value,... chksum2_details.InterfaceChecksum.Value) ans = 1
В этом случае в содержимом существуют различия.
Напишите скрипт, подобный этому скрипту, чтобы найти различия.
idxForCDiffs=[]; for idx = 1:length(chksum1_details.ContentsChecksumItems) if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Identifier, ... chksum2_details.ContentsChecksumItems(idx).Identifier)) disp(['Identifiers different for contents item ', num2str(idx)]); idxForCDiffs=[idxForCDiffs, idx]; end if (ischar(chksum1_details.ContentsChecksumItems(idx).Value)) if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Value, ... chksum2_details.ContentsChecksumItems(idx).Value)) disp(['Character vector values different for contents item ', num2str(idx)]); idxForCDiffs=[idxForCDiffs, idx]; end end if (isnumeric(chksum1_details.ContentsChecksumItems(idx).Value)) if (chksum1_details.ContentsChecksumItems(idx).Value ~= ... chksum2_details.ContentsChecksumItems(idx).Value) disp(['Numeric values different for contents item ', num2str(idx)]); idxForCDiffs=[idxForCDiffs, idx]; end end end
Запустите скрипт. Пример принимает, что вы назвали скрипт check_details
.
check_details Character vector values different for contents item 202
Результаты показывают, что различия существуют для элемента 202 индекса в содержимом подсистемы.
Используйте возвращенные значения индекса, чтобы получить подробные данные указателя, идентификатора и значения для каждой найденного различия.
chksum1_details.ContentsChecksumItems(202) ans = Handle: 'rtwdemo_ssreuse/SS1/Lookup Table' Identifier: 'SaturateOnIntegerOverflow' Value: 'on'
Детали идентифицируют Lookup Table параметров блоков Saturate on integer overflow как особое внимание для отладки проблемы повторного использования подсистемы.