Функциональные блоки Simulink обеспечивают механизм генерации кода C или C++ для моделирования компонентов, представляющих общие ресурсы. Логика определяется как ресурс в блоке Simulink Function, который отделяет интерфейс функции (имя и аргументы) от реализации логики. После этого вызывающие функции (блоки вызывающих функций, функциональные блоки MATLAB и диаграммы Stateflow ®) могут повторно использовать логику функций на различных уровнях иерархии модели.
Функциональные блоки Simulink обеспечивают альтернативу многоразовым подсистемам. Например, для использования блока функции Simulink вместо блока подсистемы необходимо, чтобы блок функции Simulink разделял состояния между вызывающими функциями. Генератор кода производит одну функцию. Если блок Simulink Function содержит блоки с состояниями, такими как задержка или память, эти состояния сохраняются между вызывающими функциями. Порядок вызовов функций является важным фактором.
Многократно используемые функции, создаваемые генератором кода из подсистем, не имеют общих состояний. Генератор кода создает одну функцию для нескольких экземпляров подсистемы в качестве оптимизации. Если эта подсистема содержит блоки с состояниями, генератор кода создает одну функцию, но передает переменную состояния в каждый экземпляр. Экземпляры не имеют общих состояний.
Другие способы использования функциональных блоков Simulink и вызывающих абонентов:
Вложение вызовов функции.
Вызов функции, определенной в одном компоненте моделирования, из другого компонента моделирования.
Создание функций, доступных по всему миру или входящих в область действия.
Создание кода для клиентского и серверного приложения.
Выберите способ реализации функций Simulink ® и вызывающих абонентов в соответствии с требованиями к генерации кода. Соображения включают в себя:
Представление функции и вызывающих абонентов функции в модели
Объем функции
Экспортировать ли функцию из модели (требуется Embedded Coder ®)
Настройки интерфейса кода функции (требуется встроенный кодер)
Требования к созданию кода
Ограничения на создание кода
В этой таблице показан код C для функции, которая умножает входное значение на два, и блок функции Simulink, который может представлять эту функцию в модели Simulink.
| Определение функции | Элемент моделирования |
|---|---|
|
#include "timestwo_sf.h"
#include "ex_slfunc_comp_sf.h"
#include "ex_slfunc_comp_sf_private.h"
void timestwo_sf(real_T rtu_x, real_T *rty_y)
{
*rty_y = 2.0 * rtu_x;
} |
Функциональный блок Simulink
|
Вызывающий абонент функции Simulink вызывает функцию, определенную блоком функции Simulink. В любом месте иерархии модели или диаграммы можно вызвать функцию, определенную блоком функции Simulink, используя один из следующих элементов моделирования:
| Вызов функции | Элемент моделирования |
|---|---|
|
void ex_slfunc_comp_sf_step(void)
{
real_T rtb_FunctionCaller1;
timestwo_sf(ex_slfunc_comp_sf_U.In1, &rtb_FunctionCaller1);
ex_slfunc_comp_sf_Y.Out1 = rtb_FunctionCaller1;
.
.
. |
Функциональный блок вызывающего абонента
|
|
void ex_slfunc_comp_gf_step(void)
{
real_T rtb_y1_l;
timestwo_gf(ex_slfunc_comp_gf_U.In4, &rtb_y1_l);
ex_slfunc_comp_gf_Y.Out4 = rtb_y1_l;
.
.
. |
Переход диаграммы Stateflow
|
|
void ex_slfunc_comp_mf_step(void)
{
real_T rtb_y;
timestwo_mf(ex_slfunc_comp_mf_U.In3, &rtb_y);
ex_slfunc_comp_mf_Y.Out3 = rtb_y;
.
.
. |
Функциональный блок MATLAB
|
Дополнительные сведения о вариантах моделирования см. в разделе Обзор функций Simulink.
Функция, определяемая блоком функции Simulink, может быть глобальной или ограниченной.
Global---Генератор кода помещает код для глобальной функции в исходные и заголовочные файлы, которые отделены от файлов кода модели (например, и function.c) . Отдельные файлы делают код функции доступным для совместного использования вызывающими функциями. function.h
Область - - генератор кода помещает код для функции области в файлы кода модели ( и model.c). Чтобы вызвать функцию в контексте модели, вызывающая функция должна находиться на том же уровне, что и функция в иерархии модели, или на одном или нескольких уровнях ниже.model.h
Чтобы создать библиотеку функций, доступных из любой точки создаваемого кода модели, настройте каждую функцию как блок функции Simulink. Поместите каждую функцию в пределах виртуальной подсистемы на корневом уровне модели.
Дополнительные сведения см. в разделе Обзор функциональных блоков Simulink и глобальных функциональных блоков Simulink.
Несмотря на то, что функциональные блоки Simulink можно использовать в одной конструкции верхней модели, код функции является более многоразовым при создании его как автономных атомных компонентов. Это можно сделать путем проектирования функций в контексте моделей export-function.
Дополнительные сведения см. в разделах Создание исходного кода компонента для экспорта во внешнюю базу кода и Обзор моделей Export-Function.
С помощью встроенного кодера упростите интеграцию сгенерированного кода с внешним кодом путем настройки сгенерированных интерфейсов кода функции для блоков Simulink Function и Function Caller. Функциональные интерфейсы можно настроить для:
Глобальные функциональные блоки Simulink
Функциональные блоки Simulink в области видимости, находящиеся на корневом уровне модели
Дополнительные сведения см. в разделе Настройка функциональных интерфейсов точек входа для блоков Simulink Function и Function Caller.
Если вы используете блок функции Simulink в модели на основе скорости и не вызываете эту функцию, генератор кода рассматривает блок функции Simulink как константу и не создает код функции. Например, это может произойти во время разработки модели, когда вы готовы определить функцию, но не готовы идентифицировать вызывающего абонента.
Чтобы идентифицировать такие блоки в модели на основе скорости, отображайте цвета времени выборки во время моделирования. По умолчанию блоки констант отображаются пурпурными. Поскольку во время моделирования генератор кода учитывает константы блоков Simulink Function, они выглядят пурпурными.
В иерархии модели имена функций уникальны. Если генератор кода находит несколько функций с одинаковым именем, это приводит к ошибке. Измените имя одной из функций и удалите slprj папка.
Сигнатура (например, аргументы и типы данных аргументов) для вызывающих функций и функций должна совпадать.
Если генератор кода находит функцию первым и сигнатура вызывающей функции не совпадает, генератор кода выдает ошибку. Измените сигнатуру вызывающего абонента функции в соответствии с сигнатурой блока функции Simulink или удалите slprj папка.
Если генератор кода находит вызывающую функцию первой и сигнатура функции не совпадает, генератор кода выдает предупреждающее сообщение. Измените сигнатуру вызывающей функции или функции таким образом, чтобы сигнатуры совпадали.
В определении блока Simulink Function не следует определять входные и выходные сигналы для блоков Argument Inport и Argument Outport с классом хранения.
Не указывайте блоки Argument Inport и Argument Outport в качестве контрольных точек.
Если указать тип данных входных и выходных сигналов для блоков Argument Inport и Argument Outport как Simulink.IntEnumType, Simulink.AliasType, или Simulink.Bus, установите DataScope свойство для Imported или Exported.
Интерфейс функции и вызывающие абоненты функции должны согласовывать тип данных, сложность, измерение и количество аргументов.
Чтобы создать код из модели, включающей функции Simulink в области, модель должна быть моделью с функцией экспорта. Генератор кода не поддерживает модели на основе скорости, которые включают функции Simulink в области.
Блок Simulink Function можно использовать для определения функции области в ссылочной модели. Однако нельзя создать код для модели export-function, которая использует блок вызова функции в атомной подсистеме для вызова этой функции.
Можно вызвать функцию C++, созданную генератором кода из блока Simulink Function, с кодом, сгенерированным из диаграммы Stateflow. Из-за текущих ограничений области для сгенерированных функций C++ необходимо вызвать эти функции с кодом, сгенерированным из блока вызывающей функции.
Функции Simulink и вызывающие абоненты функции не соблюдают MaxStackSize параметр.
Генерация кода для интерфейса класса C++ поддерживает только функции Simulink.
В этом примере показано, как использовать блоки Simulink Function и Function Caller для создания многократно используемого кода функции. Генератор кода создает глобальную функцию, которая соответствует требованиям кода, так что существующий внешний код может вызывать функцию и локальную функцию. Генератор кода также вызывает глобальные и локальные функции. Вызов глобальной функции показывает, что глобальная функция используется повторно (совместно).
Требования к кодам для глобальной функции:
Имена функций начинаются с префикса func_.
Имена входных аргументов имеют вид x, где nn является уникальным целым значением.
Имена выходных аргументов имеют вид y, где nn является уникальным целым значением.
Входные и выходные аргументы являются целыми числами (int) и передаются по ссылке. Собственный целочисленный размер целевого оборудования составляет 32 бита.
Создается функция, вызывающая созданный повторно используемый код функции. Затем создается и настраивается модель в соответствии с требованиями кода.
Для некоторых функций, используемых в этом примере, например для наложения псевдонимов и замены типа данных, требуется ПО Embedded Coder.
В корневой папке создания кода создайте файлы call_times2.h и call_times2.c. При желании можно скопировать файлы из matlabroot\help\toolbox\ecoder\examples.
call_times2.h
typedef int my_int;
call_times2.c
#include "call_times2.h"
void call_times2(void)
{
int times2result;
func_times2(x1, &y1);
printf('Times 2 Value:', y1);
}Этот код C вызывает функцию многократного использования func_times2. Функция умножает целочисленное входное значение x1 на 2 и возвращает результат как y1.
Открыть пример модели ex_slfunc_comp, которая доступна в папке matlabroot\help\toolbox\ecoder\examples. Модель включает две функции Simulink, смоделированные как блоки Simulink Function, func_times2 и func_times3и вызов каждой функции. Как указано в модели, видимость блока функции Simulink для func_times2 имеет значение global. Этот параметр видимости делает код функции доступным для другого кода, включая внешний код, который требуется интегрировать с сгенерированным кодом. Видимость для func_times3 имеет значение scoped.

При конфигурировании модели с целевым файлом системы GRT или целевым файлом системы ERT с форматом упаковки файлов, равным Modularгенератор кода создает код функции для модели.
Дополнительные сведения см. в разделе Создание кода для функции Simulink и вызывающей функции.
В примере предполагается, что созданный код выполняется на целевом оборудовании с собственным целым размером 32 бита. Внешний код представляет целые числа с типом данных my_int, который является псевдонимом int. Настройка генератора кода для использования my_int вместо типа данных, используемого генератором кода по умолчанию, который int32_T.
Создание объекта Simulink.AliasType для представления пользовательского типа данных my_int.
my_int = Simulink.AliasType
my_int =
AliasType with properties:
Description: ''
DataScope: 'Auto'
HeaderFile: ''
BaseType: 'double'Задайте свойства типа псевдонима. Введите описание, задайте для области значение Imported, укажите файл заголовка, содержащий определение типа, и свяжите тип псевдонима с базовым типом Simulink int32.
my_int.Description='Custom 32-bit int representation';
my_int.DataScope='Imported';
my_int.HeaderFile='call_times2.h';
my_int.BaseType='int32';
my_int
AliasType with properties:
Description: 'Custom 32-bit int representation'
DataScope: 'Imported'
HeaderFile: 'call_times2.h'
BaseType: 'int32'
Настройка генератора кода для замены экземпляров типа int32_T с my_int. В диалоговом окне «Параметры конфигурации» откройте панель «Code GenerationData Type Replacement».
Выберите Заменить имена типов данных в созданном коде.
В таблице Имена типов данных введите my_int для имени замены для int32.
Чтобы внешний код вызывал глобальную функцию, настройте соответствующий блок функции Simulink таким образом, чтобы он имел глобальную видимость и интерфейс, соответствующий ожидаемому внешним вызывающим абонентам.
Откройте блок, представляющий times2 функция.

Настройте имя функции и видимость, установив параметры блока порта триггера. Например, требования к коду указывают, что имя функции начинается с префикса func_.
Задать для имени функции значение func_times2.
Задать видимость функции как global.
Настройте входные и выходные аргументы функции, задав параметры блока Argument Inport и Argument Outport. Например, требования к коду указывают, что имена аргументов должны иметь форму x и ny. Требования также определяют тип аргументов nmy_int.
На вкладке «Главная» задайте для параметра «Имя аргумента» значение x1 (вход) и y1 (выход).
На вкладке Signal Attributes (Атрибуты сигнала) установите тип данных в значение int32. С помощью замены типа данных, указанной ранее, int32 отображается в сгенерированном коде как myint.
Сконфигурируйте интерфейс кода блока функции Simulink. На верхнем уровне модели щелкните правой кнопкой мыши блок, представляющий глобальную функцию. func_times2. В контекстном меню выберите C/C + + CodeConfigure C/C + + Function Interface.
Задайте для имени функции C/C + + значение func_times2.
Задать для возвращаемого аргумента C/C + + значение void.
Задать имя идентификатора C/C + + для аргументаx1 кому x1.
Задать имя идентификатора C/C + + для аргументаy1 кому y1.
Если в диалоговом окне указан выходной аргумент y1 перед входным аргументом x1, измените порядок аргументов, перетащив строку для x1 над строкой для y1.
Настройте блок функции Simulink, который представляет локальную функцию с видимостью области. На основе требований к коду можно также настроить имя функции, имена и типы входных и выходных аргументов и интерфейс функции.
Откройте блок, представляющий times3 функция.
Настройте имя функции и видимость, установив параметры блока порта триггера. Например, требования к коду указывают, что имя функции начинается с префикса func_.
Задать для имени функции значение func_times3.
Задать видимость функции как scoped.
Настройте входные и выходные аргументы функции, задав параметры блока Argument Inport и Argument Outport. Например, требования к коду указывают, что имена аргументов должны иметь форму x и ny. Требования также определяют тип аргументов nmy_int.
На вкладке «Главная» задайте для параметра «Имя аргумента» значение x1 (вход) и y1 (выход).
На вкладке Signal Attributes (Атрибуты сигнала) установите тип данных в значение int32. С помощью замены типа данных, указанной ранее, int32 отображается в сгенерированном коде как my_int.
Сконфигурируйте интерфейс кода блока функции Simulink. На верхнем уровне модели щелкните правой кнопкой мыши функцию области func_times3. В меню выберите C/C + + CodeConfigure C/C + + Function Interface. В этом случае генератор кода управляет присвоением имени функции и аргументам. Имя функции объединяет имя корневой модели и имя функции, указанное для порта триггера блока Simulink Function. В этом примере имя:ex_slfunc_comp_func_times3.
Можно задать возвращаемый аргумент C/C + + в качестве имени аргумента, указанного для блока Argument Outport илиvoid. В этом примере задайте для него значение void.
Для аргументов генератор кода предваряет rtu_ (вход) или rty_ (вывод) в имя аргумента, указанное для блока ввода аргумента.
Если в диалоговом окне указан выходной аргумент y1 перед входным аргументом x1, измените порядок аргументов, перетащив строку для x1 над строкой для y1.
Для каждого вызывающего абонента функции сконфигурируйте параметры блока вызывающего абонента функции:
Установить прототип функции в y1 = func_times2(x1).
Задайте для параметров входных аргументов значение int32(1).
Задайте для параметров выходного аргумента значение int32(1).
Создайте код для модели.
Глобальный код функции
Исходный код для глобальной функции многократного использования func_times2 находится в папке построения в файле подсистемы, func_times2.c.
#include "func_times2.h"
/* Include model header file for global data */
#include "ex_slfunc_comp.h"
#include "ex_slfunc_comp_private.h"
void func_times2(my_int x1, my_int *y1)
{
*y1 = x1 << 1;
}Код локальной функции
Генератор кода помещает определение для локальной функции (с областью действия). func_times3 в папке построения файла в файле ex_slfunc_comp.c.
void ex_slfunc_comp_func_times3(my_int rtu_x1, my_int *rty_y1)
{
*rty_y1 = 3 * rtu_x1;
}Вызовы созданных функций
Функция выполнения модели (шаг) в файле модели ex_slfunc_comp.c, вызывает две функции Simulink: глобальную функцию func_times2 и локальная функция ex_slfunc_comp_func_times3. Имя ex_slfunc_comp_func_times3 отражает область действия локальной функции путем объединения имени модели и имени функции.
void ex_slfunc_comp_step(void)
{
my_int rtb_FunctionCaller2;
func_times2(ex_slfunc_comp_U.In1, &rtb_FunctionCaller2);
ex_slfunc_comp_Y.Out1 = rtb_FunctionCaller2;
ex_slfunc_comp_func_times3(ex_slfunc_comp_U.In2, &rtb_FunctionCaller2);
ex_slfunc_comp_Y.Out2 = rtb_functionCaller2;
.
.
.Объявление точки входа для локальной функции
Файл заголовка модели ex_slfunc_comp.h включает extern объявление для функции ex_slfunc_comp_func_times3. Этот оператор объявляет точку входа функции.
extern void ex_slfunc_comp_func_times3(my_int rtu_x1, my_int *rty_y1);
Включить операторы для глобальной функции
Файл заголовка модели ex_slfunc_comp.h списки включают операторы для глобальной функцииfunc_times2.
#include "func_times2_private.h" #include "func_times2.h"
Локальные макросы и данные для глобальной функции
Файл заголовка подсистемы func_times2_private.h определяет макросы и включает файлы заголовков, которые объявляют данные и функции для глобальной функции, func_times2.
#ifndef RTW_HEADER_func_times2_private_h_ #define RTW_HEADER_func_times2_private_h_ #ifndef ex_slfunc_comp_COMMON_INCLUDES_ #define ex_slfunc_comp_COMMON_INCLUDES_ #include "rtwtypes.h" #endif #endif
Объявление начальной точки для глобальной функции
Общий файл заголовка func_times2.h, в папке общих утилит slprj/, список общих типов включает для stf/_sharedutilsrtwtypes.h. Файл также включает extern объявление для глобальной функции, func_times2. Этот оператор объявляет точку входа функции.
#ifndef RTW_HEADER_func_times2_ #define RTW_HEADER_func_times2_ #include "rtwtypes.h" extern void func_times2(my_int rtu_x1, my_int *rty_y1); #endif
В этом примере показано, как создать код C для блоков функции Simulink и вызывающей функции, и отображается соответствующий сгенерированный код.
Открыть пример модели rtwdemo_export_functions. В модели используется программное обеспечение Stateflow, но в этом примере рассматривается только код, созданный из ссылочных моделей.

Для просмотра содержимого подсистемы дважды щелкните rtwdemo_functions. Функциональный блок Simulink представляет собой f3 подсистема определена как y = f3(u).

Создать код.
Генератор кода создает rtwdemo_functions.c. Этот файл содержит определение функции и код инициализации функции.
Код инициализации для функции f3:
void f3_Init(void)
{
rtDWork.Delay_DSTATE = 1;
}Код для функции f3:
void f3(real_T rtu_u, real_T *rty_y)
{
rtY.TicToc10 = rtDWork.Delay_DSTATE;
rtDWork.Delay_DSTATE = (int8_T)(int32_T)-(int32_T)rtY.TicToc10;
adder_h(rtB.Subtract, rtU.U2, rtu_u, rtB.FunctionCaller);
*rty_y = rtB.FunctionCaller;
}
void adder_h(real_T rtu_u1,
real_T rtu_u2,
real_T rtu_u3,
real_T *rty_y)
{
*rty_y = (rtu_u1 + rtu_u2) + rtu_u3;
}Общий файл заголовка f3.h содержит объявление точки входа для функции f3.
#include "rtwtypes.h" extern void f3(real_T rtu_u, real_T *rty_y);
В rtwdemo_export_functions модель, двойной щелчок rtwdemo_caller для просмотра содержимого подсистемы вызывающего абонента.
Создать код.
Генератор кода создает файлы rtwdemo_caller.h и rtwdemo_caller.c в папке rtwdemo_caller_ert_rtw.
rtwdemo_caller.h включает в себя общий файл заголовка, f3.h, который содержит объявление точки входа функции.
rtwdemo_caller.c функция вызовов f3.
void rtwdemo_caller_t_10tic(const real_T *rtu_u,
real_T *rty_y)
{
f3(*rtu_u, rty_y);
}