Чтобы создать код C++, поддерживающий обмен сообщениями между моделями верхнего уровня Simulink и внешними приложениями, используйте блоки отправки и получения библиотеки Simulink Messages & Events Library. Создание кода из топовой модели для облегчения передачи сообщений вне среды Simulink позволяет моделируемому приложению взаимодействовать в распределенной системе, использующей службу протокола внешних сообщений, обычно называемую операционной системой или промежуточным программным обеспечением (например, сообщения DDS, ROS, SOMEIP или POSIX).
Топовые модели Simulink передают сообщения следующим образом:
Лучшие модели содержат блоки сообщений для связи вне среды Simulink. Если верхняя модель содержит блок Send, непосредственно соединенный с корневым блоком Outport, блок преобразует свои сигналы в сообщения и передает их за пределы среды Simulink. Если верхняя модель содержит блок приема, непосредственно соединенный с корневым блоком ввода, блок преобразует принятые сообщения в сигналы.
Внешний протокол передачи сообщений управляет передачей сообщений в соответствии со своим собственным стандартом (политиками, которые управляют пропускной способностью, порядком доставки и другим качеством обслуживания (QoS)).
Чтобы создать сообщения C++ для обмена данными между топовыми моделями Simulink и операционной системой или промежуточным программным обеспечением, подготовьте модель, создайте код и интегрируйте этот код с выбранной операционной системой или промежуточным программным обеспечением.
Чтобы настроить модель так, чтобы она могла передавать сообщения с операционной системой или промежуточным программным обеспечением, настройте модель как модель верхнего уровня, которая имеет по крайней мере один блок сообщений (блок отправки, подключенный к корневому блоку исходящего трафика, или блок получения, подключенный к корневому блоку входящего трафика). Затем модель может подключиться к выбранной операционной системе или промежуточному программному обеспечению через блоки сообщений, как показано на рисунке:

В рамках модели порты сообщений подключаются следующим образом:

Чтобы создать код C++ из модели:
В коллекции «Приложения» щелкните Встроенный кодер.
В диалоговом окне «Параметры конфигурации» задайте следующие параметры:
На панели «Создание кода» установите для параметра «Язык» значение C++.
На панели «Интерфейс» установите для параметра «Упаковка интерфейса кода» значение C++ class.
На панели «Шаблоны» выберите Generate an example main program.
Создать код. На вкладке Код C++ нажмите кнопку Создать.
Просмотр созданного кода. На вкладке Код C++ щелкните Просмотреть код.
Чтобы интегрировать созданный код C++ из модели с выбранной операционной системой или промежуточным программным обеспечением, используйте рукописный код для реализации классов отправки и получения сообщений и код приложения, использующего эти классы для передачи сообщений. В частности:
При использовании собственного основного класса создайте конкретные подклассы из сгенерированных абстрактных классов, показанных на RecvData_<T>.h и SendData<T>.h. При использовании созданной основной программы-примера в файле предоставляются конкретные подклассы.
Реализация функций класса SendData и RecvData вызов выбранной операционной системы или промежуточного программного обеспечения для отправки и получения сообщений.
Создайте экземпляр реализованных классов сообщений отправки и получения (объекты отправки и получения).
Создайте экземпляр класса модели, используя экземпляры каждого класса сообщений (объекты отправки и получения) в качестве аргументов в конструкторе модели.
Отправка и получение сообщений в соответствии с требованиями приложения. Ожидается, что вы будете управлять временем жизни очередей сообщений. Необходимо, чтобы очереди находились в состоянии готовности к приему сообщений до первого шага модели.
Для интеграции:
Откройте созданную основную программу-пример (или создайте собственную). При использовании созданной основной программы-примера конкретные подклассы RecvData_real_T и SendData_real_T представлены в файле. При создании собственного основного кода создайте конкретные подклассы в коде приложения:


Для получения сообщений вручную запишите реализацию сгенерированного класса приема. Реализация функции класса RecvData вызов выбранной операционной системы или промежуточного программного обеспечения для получения сообщений.
Показан пример реализации для POSIX:
class mHMIHandlerRecvData_real_T: public RecvData_real_T {
public:
void RecvData(real_T* data, int32_T length, int32_T* status)
{
// Use POSIX API mq_receive to receive messages
unsigned int priority = 1;
*status = mq_receive(msgQueue, (char *)data, length, &priority);
}
};
Создание получаемого объекта.
static mHMIHandlerRecvData_real_T InMsgRecvData_arg;
Для отправки сообщений вручную запишите реализацию созданного класса отправки. Реализация функции класса SendData вызов выбранной операционной системы или промежуточного программного обеспечения для отправки сообщений.
Показан пример реализации для POSIX:
class mHMIHandlerSendData_real_T : public SendData_real_T {
public:
void SendData(const real_T* data, int32_T length, int32_T* status)
{
// Use the POSIX API mq_send to send messages
unsigned int priority = 1;
*status = mq_send(msgQueue, (char*)data, length, priority);
}
};
Создание объекта отправки.
static mHMIHandlerSendData_real_T OutMesgSendData_arg;
Создайте экземпляр класса модели, используя объекты отправки и получения в качестве аргументов в конструкторе модели.
static mHMIHandler mHMI_Obj(InMsgRecvData_arg, OutMsgSendData_arg);
Отправка и получение сообщений в соответствии с требованиями приложения и поддержание срока службы очереди сообщений.
Показан пример реализации для POSIX:
int_T main(int_T argc, const char *argv[])
{
// Unused arguments
(void)(argc);
(void)(argv);
//Initialize model
mHMI_obj.initialize();
// Open POSIX queue
mqd_t msgQueue = mq_open("/PosixMQ_Example", O_RDONLY);
if (msgQueue == -1)
{
printf("mq_open failed\n");
exit(1);
}
// Send and Receive messages
while (rtmGetErrorStatus(mHMI_Obj.getRTM()) == (NULL)) {
//perform application tasks here.
rt_OneStep();
}
// Close POSIX queue
mq_close(msgQueue);
// Terminate model
mHMI_Obj.terminat():
return 0;
}Более сложный пример интеграции POSIX см. в разделе Использование рукописного кода для интеграции сообщений C++ с POSIX.
Рукописный код - единственный поддерживаемый метод интеграции.
Должен быть выбран параметр Generate a example main program. Приложения, для которых требуется статическая магистраль, не поддерживаются.
Управление прототипом функции (FPC) не может быть настроено для модели верхнего уровня, имеющей корневые порты сообщений.