В этом примере показано, как использовать API для импорта пользовательского кода С для контроллера теплового насоса в Simulink для модульного тестирования. Модульные тесты тестируют одну или несколько функций в изоляции от библиотеки пользовательских кодов. Для модульных тестов импортер кода Simulink Test генерирует тестовую песочницу и библиотеку, содержащую блок C Caller из заданного пользовательского кода.
Полный код для контроллера теплового насоса находится в следующих файлах источника кода С и заголовках:
Исходные файлы находятся в src
директория:
tempController.c
utils.c
Заголовочные файлы находятся в include
директория:
tempController.h
utils.h
controllerTypes.h
The tempController.c
файл содержит алгоритм для пользовательского кода С для модуля теплового насоса. The heatpumpController
функция в этом файле использует комнатную температуру (Troom_in
) и заданную температуру (Tset
) как входы. Выходные выходы pump_control_bus
тип структуры с сигналами, которые управляют вентилятором, тепловым насосом и направлением теплового насоса (тепло или охлаждение). The pump_control_bus
структура имеет следующие поля: fan_cmd
, pump_cmd
, и pump_dir
. The pump_control_bus
тип структуры определяется в controllerTypes.h
файл. Выходные выходы heatpumpController
функция является:
The heatpumpController
функция использует две служебные функции, absoluteTempDifference
и pumpDirection
, которые определены в utils.c
файл. The absoluteTempDifference
функция возвращает абсолютное различие между Tset
и Troom_in
в виде двойника. The pumpDirection
функция возвращает одно из следующих PumpDirection
введите значения перечисления:
The PumpDirection
перечисление type
определяется в controllerTypes.h
файл.
Этот пример использует только tempController.c
для создания и импорта тестовой песочницы в Simulink. Вы используете песочницу для выполнения модульного тестирования только на heatpumpController
функцию, а не полный код. Генерация песочницы автоматически создает заглушки для служебных функций, используемых heatpumpController
функция, absoluteTempDifference
и pumpDirection
. Поскольку служебные функции не определены в tempController.c
файл и utilities.c
файл не включен, импортер кода создает заглушки, поэтому код не ошибается.
CodeImporter
ОбъектСоздайте образец CodeImporter
объект для пользовательского кода контроллера теплового насоса. Установка OutputFolder
свойство к $pwd$
оценивает строку, находящуюся между символами $, как выражение MATLAB. Задайте OutputFolder
на $pwd$
чтобы задать текущую папку как выход папку. Установите SourceFiles
свойство для tempController.c
файл в src
директория. Используйте символы $, чтобы задать расположение файла для CustomCode
свойство тоже.
obj = sltest.CodeImporter('heatpumpController'); obj.OutputFolder = "$pwd$"; obj.CustomCode.SourceFiles = "$fullfile('src','tempController.c')$"; obj.CustomCode.IncludePaths = fullfile('include'); obj.CustomCode.GlobalVariableInterface = true;
Сконфигурируйте CodeImporter
объект с желаемым типом теста и параметрами песочницы.
Чтобы создать тестовую песочницу для заданного heatpumpController
функцию в пользовательском коде, установите TestType
свойства UnitTest
. В данном примере используйте GenerateAggregatedHeader
режим песочницы. Для получения информации о различных режимах песочницы смотрите sltest.CodeImporter.SandboxSettings
.
Настройка SandboxSettings.CopySourceFiles
на true
копирует указанный исходный файл в тестовую песочницу.
Обратите внимание, что можно использовать GenerateAggregatedHeader
режим песочницы только с одним исходным файлом.
obj.TestType = "UnitTest"; obj.SandboxSettings.Mode = "GenerateAggregatedHeader"; obj.SandboxSettings.CopySourceFiles = true;
Создайте песочницу. Эта тестовая песочница изолирована от исходной библиотеки пользовательского кода. Настройка Overwrite
на on
перезаписывает существующий тестовый песочник, если он существует. По умолчанию Overwrite
является off
.
obj.createSandbox('Overwrite','on');
The createSandbox
метод создает heatpumpController_sandbox
директория в указанной выходной папке, которая в этом примере является текущей рабочей папкой.
Директория песочницы содержит следующие подкаталоги:
src: Эта директория содержит скопированный исходный файл, tempController.c
.
include
: Эта директория содержит необходимые файлы включения для компиляции tempController.c
в песочнице src
директория. Эта директория также содержит aggregatedHeader.h
файл, содержащий все необходимые символы для компиляции tempController.c
.
autostub
: Эта директория содержит auto_stub.c
и auto_stub.h
файлы, которые содержат автоматически сгенерированные заглушки для absoluteTempDifference
и pumpDirection
функции утилиты .
manualstub
: Эта директория содержит man_stub.c
и man_stub.h
файлы, которые определяют любые вручную заданные заглушки. По умолчанию эти файлы не определяют никаких функций.
Импортируйте код песочницы в Simulink.
obj.import('Functions','heatpumpController');
The import
функция создает песочницу. Он также создает библиотеку, которая содержит блок C Caller, называемый heatpumpController
, который содержит внутреннюю тестовую обвязку, который можно использовать для выполнения модульного тестирования на heatpumpController
. Библиотека присоединена к словарю данных Simulink, который задает pump_control_bus
и PumpDirection
как Simulink.Bus
объект и сигнал перечисления Simulink, соответственно.
Блок C Caller присоединен внутренней тестовой обвязкой для модульного тестирования heatpumpController
функция.
Потому что вы CustomCode.GlobalVariableInterface
на true
перед импортом import
функция создает заглушки для absoluteTempDifference
и pumpDirection
глобальные переменные в auto_stub.c
и создает для них порты. Для получения дополнительной информации смотрите Включить глобальные переменные как функциональные интерфейсы.
Это блок C Caller, heatpumpController
, сгенерированный из heatpumpController
функция:
Это автоматически сгенерированные глобальные переменные в auto_stub.c
файл для absoluteTempDifference
и pumpDirection:
/*************************************************************************/ /* Generated Global Variables for Stubbed Functions Interface */ /*************************************************************************/ double SLStubIn_absoluteTempDifference_p1; double SLStubIn_absoluteTempDifference_p2; double SLStubOut_absoluteTempDifference; double SLStubIn_pumpDirection_p1; double SLStubIn_pumpDirection_p2; PumpDirection SLStubOut_pumpDirection; double absoluteTempDifference( double absoluteTempDifference_p1, double absoluteTempDifference_p2) { SLStubIn_absoluteTempDifference_p1 = absoluteTempDifference_p1; SLStubIn_absoluteTempDifference_p2 = absoluteTempDifference_p2; return SLStubOut_absoluteTempDifference; } PumpDirection pumpDirection( double pumpDirection_p1, double pumpDirection_p2) { SLStubIn_pumpDirection_p1 = pumpDirection_p1; SLStubIn_pumpDirection_p2 = pumpDirection_p2; return SLStubOut_pumpDirection; }
В автоматически сгенерированных заглушках для absoluteTempDifference
функция, глобальные переменные SLStubIn_absoluteTempDifference_p1
и SLStubIn_absoluteTempDifference_p2
сохраните входные параметры функции. Функция возвращает значение, сохраненное в SLStubOut_absoluteTempDifference
. Точно так же pumpDirection
сохраняет входные параметры и возвращает SLStubOut_pumpDirection
.
Для использования тестовой обвязки, созданного с использованием автоматически созданных заглушек, см. следующий рисунок. Добавьте шины для входов и выходов. Чтобы разрешить соединение сигнала Simulink для симуляции, соедините входы для Tset
, Troom_in
и ожидаемые выходы от глобальных переменных, SLStubOut_absoluteTempDifference
и SLStubOut_pumpDirection
Аналогично соедините выходы как показано на рисунке. Можно использовать входы и выходы, чтобы наблюдать внутренние значения, переданные heatpumpController
на absoluteTempDifference
и pumpDirecton
вызовы субфункций.
В тех случаях, когда, например, требуется сгенерировать предполагаемый выход заглушек как вход в автоматически сгенерированные порты, можно заменить заглушки вручную для заглушек, автоматически сгенерированных при создании песочницы. После переключения на использование ручных заглушек, вы обновляете существующую песочницу и импортируете ее снова.
Можно вручную предоставить определения для автоматически сгенерированных функций-заглушек путем обновления man_stub.c
и man_stub.h
файлы в manualstub
директория.
manualstubpath = fullfile([obj.LibraryFileName.char '_sandbox'],'manualstub'); helperFunctionToUpdateManualStubs(manualstubpath);
The helperFunctionToUpdateManualStubs
функция обновляет файлы заглушки вручную в тестовой песочнице.
Обновленное определение функции absoluteTempDifference
является:
double absoluteTempDifference(double Tset, double Troom_in){ return (double)fabs(Tset - Troom_in); }
Обновленное определение функции pumpDirection
является:
PumpDirection pumpDirection(double Tset, double Troom_in){ return Tset > Troom_in ? HEATING : COOLING; }
Чтобы использовать функции заглушки вручную, обновите песочницу, чтобы отразить ваши изменения. Установка Overwrite
опция для off
сохраняет изменения, внесенные в manualstub
директория в тестовой песочнице.
obj.createSandbox('Overwrite','off');
После обновления тестовой песочницы директория autostub пуста, поскольку вы определили все неопределенные символы в указанном пользовательском коде.
После обновления тестовой песочницы импортируйте код песочницы в Simulink.
obj.import('Functions','heatpumpController');
Библиотека содержит блок C Caller, вызываемый heatpumpController
с обновленными портами и также обновляется внутренняя тестовая обвязка, подключенный к блоку C Caller.
Функция импорта обновляет существующую библиотеку и импортирует heatpumpController
функция. Как и при использовании автоматически сгенерированных заглушек, библиотека присоединена к словарю данных Simulink, который задает pump_control_bus
и PumpDirection
как Simulink.Bus
объект и сигнал перечисления Simulink, соответственно.
Порты блока вызывающего абонента C отражают изменения, внесенные в файлы заглушек. Потому что ручная реализация absoluteTempDifference
и pumpDirection
функции не используют никаких глобальных переменных, блок C Caller имеет только порты для входных параметров и возвращаемого аргумента heatpumpController
функция. Также обновляется внутренняя тестовая обвязка, подключенный к блоку C Caller.
createSandbox
| Simulink.CodeImporter
| Simulink.CodeImporter.CustomCode
| Simulink.CodeImporter.import
| Simulink.CodeImporter.Options
| Simulink.CodeImporter.ParseInfo
| sltest.CodeImporter
| sltest.CodeImporter.SandboxSettings