To generate C++ code that supports message-based communication between Simulink top models and external applications, use the Simulink Messages & Events Library Send and Receive blocks.
Generating code from a top model to facilitate message passing outside of the Simulink environment allows your modeled application to communicate in a distributed system that uses an external message protocol service (for example, DDS, ROS, SOMEIP, or POSIX messages).
Simulink top models pass messages in the following way:
Top models contain message blocks to communicate outside the Simulink environment. If a top model contains a Send block directly connected to a root outport block, the block converts its signals into messages and passes them outside the Simulink environment. If a top model contains a Receive block directly connected to a root import block, the block converts the received messages into signals.
The external message protocol manages the message communication according to its own standard (policies that control capacity, order of delivery, and other quality of service (QoS) behavior).
To understand how to integrate a top model with an external message protocol, this topic covers how to prepare a top model, generate code, and integrate that code with an external protocol.
To generate C++ code from a top model that can integrate with an external message protocol prepare the top model using these steps:
Verify that the top model contains one or more message blocks (for example, Send block connected to a root outport block or Receive block connected to a root inport block).
In the Configuration Parameters dialog box, set these parameters:
In the Code Generation pane, set System target
file to ert.tlc
.
In the Code Generation pane, set the
language to C++
.
In the Interface pane, set Coder interface
packaging to C++ class
.
Select the generate an example main
check box.
A conceptual example of how a top model, HMI, integrates with an external message protocol service, Middleware (for example, POSIX), is shown:
Within the HMI model, the message ports are connected as shown.
To generate C++ code from your top model:
Open your model.
In the Apps gallery, click Embedded Coder.
Generate code. On the C++ Code tab, click Build.
View the generated code. On the C++ Code tab, click View Code.
The generated C++ code provides service classes to send and receive messages and a sample main that you are expected to program with logic to integrate the generated C++ code with your target external message protocol service.
C++ code generation provides these files:
A generated service class to send messages,
SendData_real_T.h
.
A generated service class to receive messages,
RecvData_real_T.h
.
A main file with the service class methods that you are expected to program with logic to integrate with your external message protocol service.
The main file defines and then instantiates the send and receive service classes. The top model constructor then creates an instance of the top model by passing in a reference to each service class.
Example of code integration:
An example of how to implement the logic for the sample main file to integrate the generated code with POSIX messages is the following:
void sendData_real_T(const real_T* data, int32_T length, int32_T* status) { //This is an example of a message send service function struct mq_attr attr; attr.mq_maxmsg = 1024; attr.mq_msgsize = length; mqd_t msgQueue = mq_open("/PosixMQ_Example", O_CREAT | O_WRONLY, 0664, NULL); if (msgQueue == -1) { printf("mq_open failed"); exit(1); } printf("Sending %f\n", *data); mq_send(msgQueue, (char*)data, length, 1); mq_close(msgQueue); } class mHMIHandlerSendData_real_T : public SendData_real_T { public: void SendData(const real_T* data, int32_T* length, int32_T* status) { sendData_real_T(data, length, status); } }; static mHMIHandlerSendData_real_T OutMsgSendData_arg; void RecvData_real_T(real_T* data, int32_T length, int32_T* status) { //This is an example of a receive service function mqd_t msgQueue = mq_open("/PosixMQ_Example, O_RDONLY); if (msgQueue == -1) { printf("mq_open failed"); exit(1); } struct mq_attr attr; mq_getattr(msgQueue, &attr); *status = mq_receive(msgQueue, (char *)data, attr.mq_msgsize, &priority); printf("Received %f", *data); mq_close(msgQueue); } class mHMIHandlerRecvData_real_T: public RecvData_real_T { public: { RecvData_real_T(data, length, status); } }; static mHMIHandlerRecvData_real_T InMsgRecvData_arg;
Code generation support for top model integration with external message protocols is available in C++.
The parameter Generate a sample main must be selected, applications that require a static main are not supported.
Function prototype control (FPC) cannot be configured for a top model that has root message ports.