Из-за ограничений, описанных в, Генерируют Повторно используемый Код от Подсистем (Simulink Coder), генератор кода не может снова использовать сгенерированный код, как вы ожидаете. Чтобы определить, почему код, сгенерированный для подсистемы, не снова используется:
Рассмотрите раздел Subsystems отчета генерации кода.
Сравните данные о контрольной сумме подсистемы.
Если генератор кода не генерирует код для подсистемы как повторно используемый код, и вы сконфигурировали подсистему как допускающую повторное использование, исследуйте раздел Subsystems отчета генерации кода (см., Генерируют Отчет Генерации кода (Simulink Coder)). Раздел Subsystems содержит:
Таблица, которая подводит итог, как невиртуальные подсистемы были преобразованы в сгенерированный код.
Диагностическая информация, которая описывает, почему подсистемы не были сгенерированы как повторно используемый код.
Раздел Subsystems также сопоставляет невстроенные подсистемы в модели к функциям или снова использованным функциям в сгенерированном коде. Для примера откройте и создайте модель rtwdemo_atomic
.
Можно определить, почему код подсистемы не снова используется путем сравнения данных о контрольной сумме подсистемы. Генератор кода определяет, идентичны ли подсистемы путем сравнения контрольных сумм подсистемы, как отмечено в Ограничениях (Simulink Coder). Для повторного использования подсистемы через модели, на которые ссылаются эта процедура не может отметить каждое различие.
Рассмотрите модель, 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, чтобы открыть диалоговое окно Subsystem Parameters.
Нажмите 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'
Детали идентифицируют параметры блоков Интерполяционной таблицы Saturate on integer overflow как особое внимание для отладки проблемы повторного использования подсистемы.