Можно изучить, как Simulink® двигатель взаимодействует с S-функциями с двух точек зрения:
Перспектива процесса, то есть, в каких точках симуляции двигатель вызывает S-функцию.
Перспектива данных, т.е. как механизм и S-функция обмениваются информацией во время симуляции.
Следующие рисунки показывают порядок, в котором механизм Simulink вызывает методы коллбэка в S-функции. Твердые прямоугольники указывают коллбэки, которые всегда происходят во время инициализации модели или на каждом временном шаге. Пунктирные прямоугольники указывают коллбэки, которые могут происходить во время инициализации и/или в некоторые или все временные шаги во время цикла симуляции. Смотрите документацию для каждого метода коллбэка, чтобы определить точные обстоятельства, при которых механизм вызывает коллбэк.
Примечание
Схема представления процесса представляет выполнение S-функций, которые содержат непрерывные и дискретные состояния, включают обнаружение пересечения нулем и проживают в модели, которая использует решатель с переменным шагом. Другие решатели опускают определенные шаги в схеме. Для лучшего понимания того, как механизм Simulink выполняет вашу конкретную S-функцию, запустите модель, содержащую S-функцию, используя отладчик Simulink. Для получения дополнительной информации смотрите Введение в отладчик.
В следующем цикле инициализации модели механизм Simulink конфигурирует S-функцию для предстоящей симуляции. Двигатель всегда выполняет необходимые вызовы для mdlInitializeSizes и mdlInitializeSampleTime для настройки основных атрибутов S-функции, включая входные и выходные порты, параметры диалога S-функции, рабочие векторы, шаги расчета и т.д.
Двигатель вызывает дополнительные методы, по мере необходимости, чтобы завершить инициализацию S-функции. Например, если S-функция использует рабочие векторы, механизм вызывает mdlSetWorkWidths. Кроме того, если mdlInitializeSizes метод отложил настройку атрибутов входного и выходного портов, механизм вызывает любые методы, необходимые для завершения инициализации порта, такие как mdlSetInputPortWidth, во время распространения сигнала. The mdlStart метод вызывает mdlCheckParameters и mdlProcessParameters методы, если S-функция использует диалоговые параметры.

Примечание
The mdlInitializeSizes метод коллбэка также запускается, когда вы вводите имя скомпилированной S-функции в диалоговое окно Блок S-function Parameters.
После инициализации механизм Simulink выполняет следующий цикл симуляции. Если цикл симуляции прерывается, либо вручную, либо когда возникает ошибка, двигатель перескакивает непосредственно к mdlTerminate способ. Если симуляция была остановлена вручную, двигатель сначала завершает текущий временной шаг перед вызовом mdlTerminate.

Если ваша модель содержит несколько блоков S-Function на заданном уровне иерархии модели, механизм вызывает конкретный метод для каждой S-функции, прежде чем переходить к следующему методу. Например, двигатель вызывает все mdlInitializeSizes методы перед вызовом любого mdlInitializeSampleTimes методы. Механизм использует блок отсортированный порядок, чтобы определить порядок выполнения S-функций. Дополнительные сведения о том, как механизм определяет порядок выполнения блока, см. в разделе Управление и отображение порядка выполнения.
Если вы используете продукт Simulink Coder™, чтобы сгенерировать код для модели, содержащей S-функции, механизм Simulink не выполняет целую последовательность вызовов, описанную выше. Инициализация выполняется так, как описано выше, пока двигатель не достигнет mdlStart способ. Затем двигатель вызывает методы S-функции, показанные на следующем рисунке, где mdlRTW метод уникален для продукта Simulink Coder.

Если S-функция находится в условно выполненной подсистеме, можно, чтобы сгенерированный код перемежал вызовы в mdlInitializeConditions и mdlStart. Рассмотрим следующую модель Simulink.

Модель содержит две невиртуальные подсистемы, условно выполненную включенную подсистему с именем Reset и атомарную подсистему с именем Atomic. Каждая подсистема содержит блок S-Function, который вызывает S-функцию dsfunc.c, который моделирует дискретную систему в пространстве состояний с двумя состояниями. Включенная подсистема Reset сбрасывает значения состояния, когда подсистема включена, и выходные значения, когда подсистема отключена.
Используя общую цель в реальном времени (GRT), сгенерированный код для всей модели Start функция вызывает Start функции двух подсистем перед вызовом общемодельных MdlInitialize функция, как показано на следующем коде:
void MdlStart(void)
{
/* snip */
/* Start for enabled SubSystem: '<Root>/Reset' */
sfcndemo_enablesub_Reset_Start();
/* end of Start for SubSystem: '<Root>/Reset' */
/* Start for atomic SubSystem: '<Root>/Atomic' */
sfcndemo_enablesub_Atomic_Start();
/* end of Start for SubSystem: '<Root>/Atomic' */
MdlInitialize();The Start функция для включенной подсистемы вызывает функцию InitializeConditions функция:
void sfcndemo_enablesub_Reset_Start(void)
{
sfcndemo_enablesub_Reset_Init();
/* snip */
}The MdlInitialize функция, вызываемая в MdlStart, содержит вызов на InitializeConditions функция для атомарной подсистемы:
void MdlInitialize(void)
{
/* InitializeConditions for atomic SubSystem:
'<Root>/Atomic' */
sfcndemo_enablesub_Atomic_Init();
}Поэтому во всей модели Start функция перемежает вызовы к Start и InitializeConditions функций для двух подсистем и S-функций, которые они содержат.
Для получения дополнительной информации о продукте Simulink Coder и о том, как он взаимодействует с S-функциями, смотрите S-Functions и Генерация Кода (Simulink Coder).
Когда вы запускаете модель Simulink во режиме external mode, последовательность вызовов для стандартных программ S-функций изменяется, как показано на следующем рисунке.

Механизм вызывает mdlRTW один раз, когда он входит во режим external mode и снова каждый раз, когда параметр изменяется или когда вы кликаете Update Model на вкладке Modeling.
Примечание
Выполнение модели Simulink во режиме external mode требует продукта Simulink Coder.
Блоки s-function имеют входные и выходные сигналы, параметры и внутренние состояния, плюс другие общие рабочие области. В целом, блочные входы и выходы записываются в вектор ввода-вывода блока и считываются с него. Входные параметры также могут исходить от
Внешние входы через корневые блоки Inport
Заземлите, если входной сигнал не соединен или заземлен
Выходы блоков могут также переходить к внешним выходам через корневые блоки Outport. В дополнение к входным и выходным сигналам S-функции могут иметь
Непрерывные состояния
Дискретные состояния
Другие рабочие области, такие как действительные, целое число или рабочие векторы
Можно параметризовать блоки s-function путем передачи им параметров с помощью диалогового окна Блок S-function Parameters.
Следующий рисунок показывает общее отображение между этими различными типами данных.

S-функции mdlInitializeSizes стандартная программа устанавливает размеры различных сигналов и векторов. Методы S-функции, вызываемые во время цикла симуляции, могут определять размеры и значения сигналов.
Метод S-функции может обращаться к входным сигналам двумя способами:
Через указатели
Использование смежных входов
Во время цикла симуляции получайте доступ к входным сигналам, используя
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,portIndex)
Это возвращает массив указателей для порта входа с индексом portIndex, где portIndex начинается с 0. Для каждого входного порта существует по одному массиву указателей. Для доступа к элементу этого массива необходимо использовать
*uPtrs[element]
Следующий рисунок описывает, как получить доступ к входным сигналам S-функции с двумя входами.

Как показано на предыдущем рисунке, указатели входного массива могут указывать на несмежные места в памяти.
Вы можете извлечь выходной сигнал при помощи этого кода.
real_T *y = ssGetOutputPortSignal(S,outputPortIndex);
mdlInitializeSizes S-функции метод может указать, что элементы его входных сигналов должны занимать смежные области памяти, используя ssSetInputPortRequiredContiguous. Если входы смежны, другие методы могут использовать ssGetInputPortSignal для доступа к входам.
В этом разделе описывается, как получить доступ ко всем входным сигналам конкретного порта и записать их в выходной порт. Предыдущий рисунок показывает, что входной массив указателей может указывать на несмежные значения в векторе ввода-вывода блока. Сигналы выхода конкретного порта образуют смежный вектор. Поэтому правильный способ доступа к входным элементам и записи их в выходные элементы (если входной и выходной порты имеют равные ширины) - использовать этот код.
int_T element;
int_T portWidth = ssGetInputPortWidth(S,inputPortIndex);
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,inputPortIndex);
real_T *y = ssGetOutputPortSignal(S,outputPortIdx);
for (element=0; element<portWidth; element++) {
y[element] = *uPtrs[element];
}
Распространенной ошибкой является попытка получить доступ к входным сигналам через арифметику указателя. Для примера, если бы вы разместили
real_T *u = *uPtrs; /* Incorrect */
чуть ниже инициализации uPtrs и замените внутреннюю часть указанного цикла на
*y++ = *u++; /* Incorrect */
код компилируется, но файл MEX может аварийно завершить работу программного обеспечения Simulink. Это происходит потому, что возможен доступ к недопустимой памяти (которая зависит от того, как вы создаете свою модель). При неправильном доступе к входным сигналам происходит сбой, когда сигналы, входящие в ваш Блок s-function, не смежны. Несмежные данные сигнала возникают, когда сигналы проходят через блоки виртуальных соединений, такие как блоки Mux или Selector.
Чтобы убедиться, что ваша S-функция правильно обращается к широким входным сигналам, передайте реплицированный сигнал к каждому входному порту вашей S-функции. Для этого создайте блок Mux с количеством входа портов, равным ширине необходимого сигнала, входящего в вашу S-функцию. Затем подключите ведущий источник к каждому входному порту S-функции, как показано на следующем рисунке. Наконец, запустите свою S-функцию, используя этот входной сигнал, чтобы убедиться, что он не падает и выдает ожидаемые результаты.

Level-2 MATLAB S-Function | MATLAB Function | S-Function | S-Function Builder