Из-за ограничений, описанных в разделе Генерировать повторно вводимый код из подсистем (Generate Reentrant Code from 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. Щелкните правой кнопкой мыши подсистему. В контекстном меню выберите «Маска» > «Искать под маской».
На блок-схеме подсистемы дважды щелкните блок «Таблица поиска», чтобы открыть диалоговое окно «Параметры подсистемы».
Щелкните Типы данных.
Выберите параметр блока 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 является фокусом для отладки проблемы повторного использования подсистемы.