Определите, почему код подсистемы не снова используется

Из-за ограничений, описанных в, Генерируют Повторно используемый Код от Подсистем (Simulink Coder), генератор кода не может снова использовать сгенерированный код, как вы ожидаете. Чтобы определить, почему код, сгенерированный для подсистемы, не снова используется:

  1. Рассмотрите раздел Subsystems отчета генерации кода.

  2. Сравните данные о контрольной сумме подсистемы.

Рассмотрите раздел подсистем отчета генерации КОДА HTML

Если генератор кода не генерирует код для подсистемы как повторно используемый код, и вы сконфигурировали подсистему как допускающую повторное использование, исследуйте раздел Subsystems отчета генерации кода (см., Генерируют Отчет Генерации кода (Simulink Coder)). Раздел Subsystems содержит:

  • Таблица, которая подводит итог, как невиртуальные подсистемы были преобразованы в сгенерированный код.

  • Диагностическая информация, которая описывает, почему подсистемы не были сгенерированы как повторно используемый код.

Раздел Subsystems также сопоставляет невстроенные подсистемы в модели к функциям или снова использованным функциям в сгенерированном коде. Для примера откройте и создайте rtwdemo_atomic модель.

Сравните данные о контрольной сумме подсистемы

Можно определить, почему код подсистемы не снова используется путем сравнения данных о контрольной сумме подсистемы. Генератор кода определяет, идентичны ли подсистемы путем сравнения контрольных сумм подсистемы, как отмечено в Ограничениях (Simulink Coder). Для повторного использования подсистемы через модели, на которые ссылаются эта процедура не может отметить каждое различие.

Рассмотрите модель, rtwdemo_ssreuse. SS1 и SS2 экземпляры той же подсистемы. В обоих экземплярах параметры блоков подсистемы Function packaging установлен в Reusable function.

Используйте метод Simulink.SubSystem.getChecksum получить контрольную сумму для подсистемы. Рассмотрите результаты определить, почему код не снова используется.

  1. Откройте модель rtwdemo_ssreuse. Сохраните копию в папке модели, где у вас есть доступ для записи.

  2. Сопоставьте подсистемы SS1 и SS2 с gcb. Для каждой из подсистем, в окне модели, выбирают подсистему. В то время как подсистема выбрана в Командном окне, введите:

    SS1 = gcb;
    SS2 = gcb;
  3. Используйте метод Simulink.SubSystem.getChecksum получить контрольную сумму для каждой подсистемы. Этот метод возвращает два выходных значения: значение контрольной суммы и детали о входе использовались для расчета контрольной суммы.

    [chksum1, chksum1_details] = ...
    Simulink.SubSystem.getChecksum(SS1);
    [chksum2, chksum2_details] = ...
    Simulink.SubSystem.getChecksum(SS2);
  4. Сравните два значения контрольной суммы. Значения должны быть равными на основе настроек подсистемы.

    isequal(chksum1, chksum2)
    ans =
         1
  5. Использовать Simulink.SubSystem.getChecksum чтобы определить, почему контрольные суммы двух подсистем отличаются, измените режим типа данных выходного порта SS1 так, чтобы это отличалось от того из SS2.

    1. Посмотрите под маской SS1. Щелкните правой кнопкой по подсистеме. В контекстном меню выберите Mask> Look Under Mask.

    2. В блок-схеме подсистемы дважды кликните блок Lookup Table, чтобы открыть диалоговое окно Subsystem Parameters.

    3. Нажмите Data Types.

    4. Выберите параметры блоков Saturate on integer overflow и нажмите OK.

  6. Получите контрольную сумму для SS1. Сравните контрольные суммы для этих двух подсистем. На этот раз контрольные суммы не равны.

    [chksum1, chksum1_details] = ...
    Simulink.SubSystem.getChecksum(SS1);
    isequal(chksum1, chksum2)
    ans =
         0
  7. После того, как вы решите, что контрольные суммы отличаются, узнают почему. Механизм 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, содержите детали контрольной суммы.

  8. Определите, существует ли различие в содержимом подсистемы, интерфейсе или обоих. Например:

    isequal(chksum1_details.ContentsChecksum.Value,...
            chksum2_details.ContentsChecksum.Value)
    ans =
         0
    isequal(chksum1_details.InterfaceChecksum.Value,...
            chksum2_details.InterfaceChecksum.Value)
    ans =
         1

    В этом случае различия существуют в содержимом.

  9. Запишите скрипт как этот скрипт, чтобы найти различия.

    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
    
  10. Запустите скрипт. Пример принимает, что вы назвали скрипт check_details.

    check_details
    Character vector values different for contents item 202

    Результаты показывают, что различия существуют для пункта 202 индекса в содержимом подсистемы.

  11. Используйте возвращенные значения индекса, чтобы получить указатель, идентификатор и детали значения для каждого найденного различия.

    chksum1_details.ContentsChecksumItems(202)
    
    ans = 
    
            Handle: 'rtwdemo_ssreuse/SS1/Lookup Table'
        Identifier: 'SaturateOnIntegerOverflow'
             Value: 'on'
    

    Детали идентифицируют параметры блоков Lookup Table Saturate on integer overflow как особое внимание для отладки проблемы повторного использования подсистемы.