Create Custom CAN Blocks
You can create custom
Transmit blocks to
use with hardware currently not supported by Vehicle Network Toolbox™. Choose one of the following work flows.
Blocks Using Simulink Buses (recommended) — Use Simulink® bus signals to connect blocks. Create functions and blocks with S-Function Builder and S-Function blocks.
Blocks Using CAN Message Data Types — Use CAN message data types to share information. Write and compile your own C++ code to define functions, and MATLAB® code to create blocks.
Blocks Using Simulink Buses
To create custom blocks for Vehicle Network Toolbox that use Simulink CAN buses, you can use the S-function builder. For full instructions on building S-functions and blocks this way, see Use a Bus with S-Function Builder to Create an S-Function (Simulink). The following example uses the steps outlined in that topic.
This example shows you how to build two custom blocks for transmitting and receiving CAN messages. These blocks use a Simulink message bus to interact with CAN Pack and CAN Unpack blocks.
Create a Simulink message bus in the MATLAB workspace for CAN or CAN FD.
Each of these functions creates a variable in the workspace named
CAN_FD_MESSAGE_BUS, respectively. You use this variable later for building your S-functions.
Open a new blank model in Simulink, and add to your model an S-Function Builder (Simulink) block from the block library.
Double-click the S-Function Builder block to open its dialog box. The first function you build is for transmitting.
Among the settings in the dialog box, define a function name and specify usage of a Simulink bus.
Data Properties: Input Ports: Bus:
On, Bus Name:
CAN_MESSAGE_BUS, as shown in the following figure.
For CAN FD, set the bus name to
In your function and block building, use the other tabs in the dialog box to define the code for interaction with your device driver, and remove unnecessary ports.
Click Build. The code files are placed in the current working folder of MATLAB.
Place a new S-Function Builder block in your model, and repeat the steps to build an S-function named CustomCANReceive. Use the same settings, except for input and output ports. The receive block output port uses the same bus name as the transmit function input.
Build the receive function, and remove both S-Function Builder blocks from your model. At this point, you can use the files generated by the S-Function Builder as a set of templates, which you can further edit and compile with your own tools. Alternatively, you can use S-Function (Simulink) blocks to run your functions.
Add two S-Function blocks to your model. Open each block, and set its Model Parameters S-function name field, so you have one each of CustomCANTransmit and CustomCANReceive.
At this point you could create a mask for each block to allow access to parameters for your hardware. This example does not need masks for these blocks.
Add other necessary blocks to your model, including:
Set the block parameters and connections.
Blocks Using CAN Message Data Types
For ease of design and to take advantage or more Simulink features, it is recommended that you use Simulink buses instead of CAN message data types when possible. See Blocks Using Simulink Buses.
To create your own blocks for use with other Vehicle Network Toolbox blocks, can use a custom CAN data type. Register this custom CAN data type in a C++ S-function.
You must use a C++ file type S-function (
.cpp) to create custom
blocks that use CAN message data types. Using a C-file type S-function
.c) might cause linker errors.
To register and use the custom CAN data type, in your S-function:
IMPORT_SCANUTILidentifier that imports the required symbols when you compile the S-function:
can_datatype.hheader located in
at the top of the S-function:
can_datatype.his located in
. See the
can_message.hfile for information on the
Link your S-function during build to the
scanutil.liblocated in the
folder. The shared library
scanutil.dllis located in the
Call this function in
mdlInitializeSizes(Simulink) to initialize the custom CAN data type:
Get custom data type ID using
dataTypeID = ssGetDataTypeId(S,SL_CAN_MESSAGE_DTYPE_NAME);
Do one of the following:
To create a receive block, set output port data type to
To create a transmit block, set the input port type to
- C/C++ S-Function Basics (Simulink)
- Use a Bus with S-Function Builder to Create an S-Function (Simulink)