Введение в Simulink Code Inspector

В этом примере показано, как использовать Inspector™ Simulink ® Code для проверки кода, сгенерированного из моделей, и для достижения целей исходного кода из DO-178C, факторов программного обеспечения в воздушных системах и сертификации оборудования. Можно проверить сгенерированный код как программно с помощью команд MATLAB, так и графически с помощью диалогового окна Simulink Code Inspector. В этом примере показано, как выполнить программную проверку кода. Он иллюстрирует, как:

  • Подготовьте модель для генерации кода.

  • Сгенерируйте код для иерархии модели при помощи Embedded Coder ®.

  • Проверьте сгенерированный код независимо с помощью Simulink Code Inspector.

  • Намеренно внесите ошибку в сгенерированный код и проверьте на отказ.

Настройка временной папки для сгенерированных файлов

Создайте временную папку во временной папке системы для генерации кода и процесса проверки.

currentDir = pwd;
[tempDir, cgDir] = slcidemodir();

Откройте модель примера

Загрузите пример модели slcidemo_roll_orig, сохраните копию модели и переименуйте ее как slcidemo_roll.

load_system('slcidemo_roll_orig')
save_system('slcidemo_roll_orig', 'slcidemo_roll');
open_system('slcidemo_roll');

Это схема верхнего уровня модели. Он представляет собой основной автопилот оси крена с двумя рабочими режимами: удержание положения крена и удержание курса. Логика режима для этих режимов является внешней по отношению к этой модели. Архитектура модели представляет режим удержания заголовка и базовую функцию ориентации крена как модели-ссылки. Функция управления положением крена является ПИД-регулятором, которая использует обратную связь о положении крена и скорости крена для получения команды элерона. Для отслеживания курса входа к контроллеру либо основной угол крена ссылки либо команда крена. Модель включает в себя:

  • Виртуальная подсистема RollAngleReference, который реализует основной угол крена ссылки вычисления. Embedded Coder ® вводит это вычисление непосредственно в основную функцию для slcidemo_roll.

  • Блок Model HeadingMode, ссылка на отдельную модель, которая вычисляет команду roll для отслеживания заголовка.

  • Блок Model BasicRollMode, ссылка на отдельную модель, которая вычисляет функцию управления положением крена.

Подготовьте модель для генерации кода и проверки

Simulink Code Inspector поддерживает ограниченный набор семантики моделирования и оптимизации кода. Чтобы проверить сгенерированный код с помощью Simulink Code Inspector, сконфигурируйте модель перед генерацией кода так, чтобы модель соответствовала этому ограничительному множеству. Можно проверить совместимость модели с Code Inspector с помощью проверки ее совместимости. Проверка совместимости моделей обнаруживает и сообщает о проблемах совместимости на ранних этапах процесса разработки модели. Это раннее обнаружение может значительно сократить время и усилия для достижения удовлетворительных результатов инспекций кода, необходимых для приложений повышенной надежности.

Чтобы подготовить slcidemo_roll модели для генерации кода и контроля установите параметр конфигурации модели AdvancedOptControl к значению -SLCI. Этот параметр ограничивает оптимизацию кода, используемую Embedded Coder, подмножеством, которое совместимо с Code Inspector.

set_param('slcidemo_roll','AdvancedOptControl','-SLCI');

Чтобы создать объект инспекции кода config, используйте slci.Configuration функция. Используйте объект, чтобы сконфигурировать проверку совместимости и инспекцию кода для модели.

config = slci.Configuration('slcidemo_roll'); 

Чтобы запустить проверку совместимости, используйте checkCompatibility функция.

result=config.checkCompatibility('DisplayResults','None');
Updating Model Advisor cache...
Model Advisor cache updated. For new customizations, to update the cache, use the Advisor.Manager.refresh_customizations method.

См. результаты проверок.

for i = 1:length(result)
    fprintf('\nModel ''%s'' passed %d checks with %d issues.',...
        result{i}.system,...
        result{i}.numPass, result{i}.numWarn + result{i}.numFail)
end
Model 'slcidemo_roll' passed 68 checks with 0 issues.

Результаты проверок совместимости можно также увидеть в окне сводного отчета HTML. Чтобы открыть сводный отчет HTML, используйте следующую команду:

ModelAdvisor.summaryReport(result);

Если модель проходит проверку совместимости, она готова к генерации кода и проверке. Подробный отчет о проверках совместимости для каждой проверенной модели можно увидеть, щелкнув ссылки Отчет Model Advisor в HTML. В подробном отчете описывается результат каждой проверки, и если сообщаются какие-либо несовместимости и необходимо исправить модель, предусмотрены рекомендуемые действия.

Сгенерируйте код для модели

После того, как ваша модель пройдет проверку совместимости, сгенерируйте код из модели с помощью Embedded Coder. Модель slcidemo_roll предварительно сконфигурирован для генерации кода при помощи Embedded Coder. Если ваша модель не сконфигурирована предварительно, установите параметр конфигурации модели System target file на ert.tlc, с помощью следующей команды:

 set_param('slcidemo_roll','SystemTargetFile','ert.tlc')

Можно неявно сгенерировать код как часть инспекции кода или выполнить генерацию кода и инспекцию кода как отдельные шаги. Чтобы указать, генерировать ли код перед проверкой, используйте setGenerateCode функция. Этот пример отделяет шаг генерации кода от шага инспекции кода.

% The input argument is false to specify that the code generation and
% inspection are separate steps
 config.setGenerateCode(false);

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

 slbuild('slcidemo_roll');
### Starting serial model reference code generation build
### Starting build procedure for: slcidemo_attitude
### Successful completion of code generation for: slcidemo_attitude
### Starting build procedure for: slcidemo_heading
### Successful completion of code generation for: slcidemo_heading
### Starting build procedure for: slcidemo_roll
### Successful completion of code generation for: slcidemo_roll

Build Summary

Code generation targets built:

Model              Action          Rebuild Reason                       
========================================================================
slcidemo_attitude  Code generated  slcidemo_attitude.c does not exist.  
slcidemo_heading   Code generated  slcidemo_heading.c does not exist.   

Top model targets built:

Model          Action          Rebuild Reason                                    
=================================================================================
slcidemo_roll  Code generated  Code generation information file does not exist.  

3 of 3 models built (0 models already up to date)
Build duration: 0h 0m 51.565s

Просмотрите сгенерированный код в подробном HTML.

web(fullfile(cgDir,'slcidemo_roll_ert_rtw','html','slcidemo_roll_codegen_rpt.html'));

Можно просмотреть сгенерированный код в представлении кода и достичь визуальной двусторонней отслеживаемости между исходной моделью и сгенерированным кодом. Чтобы просмотреть сгенерированный код в представлении кода, откройте приложение Embedded Coder в модели.

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

set_param('slcidemo_roll','UpdateModelReferenceTargets','AssumeUpToDate');
save_system('slcidemo_roll')

Смотрите сгенерированный код

После генерации кода из модели при помощи Embedded Coder можно проверить код с помощью Simulink Code Inspector, чтобы удовлетворить целям исходного кода в DO-178C стандарте. По умолчанию Simulink Code Inspector принимает, что код предварительно генерирован в папки по умолчанию, где Embedded Coder записывает свои файлы. Если необходимо задать альтернативное расположение, используйте функции setCodePlacement и setCodeFolder. В этом примере используйте функцию setReportFolder поместить отчеты инспекции кода в локальную папку отчетов и указать slcidemo_roll как модель верхнего уровня.

% Set top-model
config.setTopModel(true);
% Set code inspection report folder
config.setReportFolder(fullfile('.','report'));
% Inspect the code generated from the model
result = config.inspect('DisplayResults','None');
fprintf('Model %s status: %s\n',result.ModelName, result.Status);
Model slcidemo_roll status: PASSED

Code Inspector просматривает сгенерированный код, чтобы проверить структурную эквивалентность и двустороннюю отслеживаемость между исходной моделью и сгенерированным кодом. После проверки он генерирует подробный сводный отчет HTML. Для получения дополнительной информации об отчетах по инспекции кода смотрите Инспекцию кода Reports

Просмотрите HTML верификации кода.

web(fullfile('.', 'report','slcidemo_roll_report.html'));

Если общим результатом проверки модели является Passed, это означает, что инспекция кода завершена. Если для модели возвращается статус Предупреждение (Warning) или статус Неудача (Failed), исправьте или поработайте вокруг отчетных условий и повторно осмотрите модель. В этом случае пройден общий результат проверки.

Внесите преднамеренную ошибку в код

Simulink Code Inspection сравнивает сгенерированный код со своей исходной моделью, чтобы проверить структурную эквивалентность. Он генерирует неудачный отчет о верификации, если исходная модель и сгенерированный код не являются структурно эквивалентными.

Чтобы сгенерировать неудачный отчет о верификации, вставьте преднамеренную ошибку в сгенерированный код. Измените логический блок Operator внутри RollAngleReference подсистема в сгенерированном коде от операции OR () до операции AND (& &) с помощью служебной функции примера slcidemo_modifycode.

% Copy the example utitity function slcidemo_modifycode to temporary folder
cd(currentDir); 
copyfile( 'slcidemo_modifycode.m' ,tempDir);
cd(tempDir);
% Modify the generated code
cfile = fullfile(cgDir,'slcidemo_roll_ert_rtw','slcidemo_roll.c');
slcidemo_modifycode(cfile,'<S1>/Or','||','&&');
Before:     if ((rtU_Phi >= 6.0F) || (rtU_Phi <= -6.0F)) {
After :     if ((rtU_Phi >= 6.0F) && (rtU_Phi <= -6.0F)) {

Подсветить блок, для которого изменяется соответствующий код, можно с помощью следующей команды:

hilite_system('slcidemo_roll/RollAngleReference/Or');

Повторно проверьте измененный сгенерированный код.

result = config.inspect('DisplayResults','None');
fprintf('Model %s status: %s\n',result.ModelName, result.Status);
Model slcidemo_roll status: FAILED

Simulink Code Inspector не может проверить измененный сгенерированный код, так как он больше не соответствует модели. См. подробный отчет о верификации.

web(fullfile('.','report','slcidemo_roll_report.html'));

Очистка папок и файлов примера

Закройте модели и удалите временные папки и файлы.

close_system('slcidemo_roll_orig',0)
close_system('slcidemo_roll',0)
cd(currentDir);
rmdir(tempDir,'s');