In Simulink^{®}, you can create your own block libraries as a way to reuse the functionality of blocks or subsystems in one or more models. If you want to reuse a set of MATLAB^{®} algorithms in Simulink models, you can encapsulate your MATLAB code in a MATLAB Function block library.
As with other Simulink block libraries, you can specialize each instance of MATLAB Function library blocks in your model to use different data types, sample times, and other properties. Library instances that inherit the same properties can reuse generated code (see Code Reuse with Library Blocks).
For more information about Simulink block libraries, see About Block Libraries and Linked Blocks.
Here is a basic workflow for creating custom block libraries with MATLAB Function blocks. To work through these steps with an example, see Example: Creating a Custom Signal Processing Filter Block Library.
Add polymorphic MATLAB code to MATLAB Function blocks in a Simulink model.
Polymorphic code is code that can process data with different properties, such as type, size, and complexity.
Configure the blocks to inherit the properties you want to specialize.
For a list of properties you can specialize, see Properties You Can Specialize Across Instances of Library Blocks.
Optionally, customize your library code using masking.
Add instances of MATLAB Function library blocks to a Simulink model.
This simple example takes you through the workflow described in How to Create Custom MATLAB Function Block Libraries to show you how to:
Create a library of signal processing filter algorithms using MATLAB Function blocks
Customize one of the library blocks using mask parameters
Convert one of the filter algorithms to sourceprotected Pcode that you can call from a MATLAB Function library block
The MATLAB filter algorithms are:
my_fft. Performs a discrete Fourier transform on an input signal. The input can be a vector, matrix, or multidimensional array whose length is a power of 2.
my_conv. Convolves two input vector signals. Outputs a subsection of
the convolution with a size specified by a mask parameter, Shape
.
my_sobel. Convolves a 2D input matrix with a Sobel edge detection filter.
In Simulink, create a library model by selecting File > New > Library
Drag three MATLAB Function blocks into the model from the UserDefined Functions section of the Simulink Library Browser and name them:
my_fft_filter
my_conv_filter
my_sobel_filter
Save the library model as my_filter_lib
.
Open the MATLAB Function block named my_fft_filter
,
replace the template code with the following code, and save the block:
function y = my_fft(x) y = fft(x);
Replace the template code in my_conv_filter
block
with the following code and save the block:
function c = my_conv(a, b) c = conv(a, b);
Replace the template code in my_sobel_filter
block
with the following code and save the block:
function y = my_sobel(u) %% "my_sobel_filter" is a MATLAB function %% on the MATLAB path. y = my_sobel_filter(u);
The my_sobel
function acts as a wrapper that
calls a MATLAB function, my_sobel_filter
,
on the code generation path. my_sobel_filter
implements
the algorithm that convolves a 2D input matrix with a Sobel edge detection
filter. By calling the function rather than inlining the code directly
in the MATLAB Function block, you can reuse the algorithm
both as MATLAB code and in a Simulink model. You will create my_sobel_filter
next.
In the same folder where you created my_filter_lib
,
create a new MATLAB function my_sobel_filter
with
the following code:
function y = my_sobel_filter(u) % Sobel edge detection filter h = [1 2 1;... 0 0 0;... 1 2 1]; y = abs(conv2(u, h));
Save the file as my_sobel_filter.m
.
In this example, the data in the signal processing filter algorithms must inherit size, type, and complexity from the Simulink model. By default, data in MATLAB Function blocks inherit these properties. To explicitly configure data to inherit properties:
Open a MATLAB Function block and select Edit Data.
In the left pane of the Ports and Data Manager, select the data of interest.
In the right pane, configure the data to inherit properties from Simulink:
To Inherit  What to Specify 

Size  Enter 1 in Size field 
Complexity  Select Inherited from the Complexity menu 
Type  Select Inherit: Same as Simulink from the Type menu 
For example, if you open the MATLAB Function block my_fft_filter and
look at the properties of input x
in the Ports
and Data Manager, you see that size, type, and complexity are inherited
by default.
Note: If your design has specific requirements or constraints, you can enter values for any of these properties, rather than inherit them from Simulink. For example, if your algorithm is not supposed to work with complex inputs, set Complexity to Off. 
See Also.
In this exercise you will modify the convolution filter my_conv
to
use a custom parameter shape
that specifies what
subsection of the convolution to output. To customize this algorithm
for your library, place the my_conv_filter
block
under a masked subsystem and define shape
as a
mask parameter.
Convert the block to a masked subsystem:
Rightclick the my_conv_filter block and select Subsystem & Model Reference > Create Subsystem from Selection.
The my_conv_filter block changes to a subsystem block.
Change the name of the subsystem to my_conv_filter.
Rightclick the my_conv_filter subsystem and select Mask > Create Mask from the context menu.
The Mask Editor appears with the Icon & Ports tab open.
Enter in the Icon drawing commands text box:
disp('my_conv'); port_label('output', 1, 'c'); port_label('input', 1, 'a'); port_label('input', 2, 'b');
Select the Parameters & Dialog tab.
Highlight the Parameters
line item
in the Dialog box pane.
Add a popuptype parameter by clicking Popup under the Parameter list in the Controls pane.
A new parameter will appear in the Dialog box pane.
In the Property editor pane, set the Properties:
Property  Value 

Name  shape 
Value  full 
Prompt  shape 
Type  popup 
Type options  Open the Type Options Editor and enter:full same valid 
Set the Attributes, Dialog, and Layout properties in the Property editor pane:
Attributes, Dialog, and Layout Items  Value 

Attributes 

Dialog 

Layout 

Click OK.
Your subsystem should now look like this:
Set subsystem properties for code reuse:
Rightclick the my_conv_filter subsystem and select Block Parameters (Subsystem) from the context menu.
In the subsystem parameters dialog box, select the Treat as atomic unit check box.
The dialog box expands to display new fields.
To generate a reusable function, select the Code Generation
tab and in the Function packaging field, select Reusable
function
from the dropdown menu.
Note: This is an optional step, required for this example. If you leave the default setting of Auto, the code generation software uses an internal rule to determine whether to inline the function or not. 
Click OK.
Define the shape
parameter in the MATLAB Function my_conv
:
Rightclick the my_conv_filter subsystem and select Mask > Look Under Mask from the context menu.
The block diagram under the masked subsystem opens, containing the my_conv_filter block:
Change the names of the port blocks to match the data names as follows:
Change:  To: 

In1  a 
In2  b 
Out1  c 
Doubleclick the my_conv_filter block to open the MATLAB Function Block Editor.
In the MATLAB Function Block Editor, select Edit Data.
In the Ports and Data Manager, select Add > Data.
A new data element appears selected, along with its properties dialog.
Enter the following properties:
Property  What To Specify 

Name  Enter shape . 
Scope  Select Parameter. 
Tunable  Clear the box. 
Leave Size, Complexity, and Type as inherited (the defaults), as described in Step 2: Configure Blocks to Inherit Properties You Want to Specialize.
Click Apply, close the Ports and Data Manager, and return to the MATLAB Function Block Editor.
Use the shape
parameter to determine
the size of the convolution to output:
In the MATLAB Function Block Editor, modify the my_conv
function
to call conv
with the right shape:
function c = my_conv(a, b, shape) if shape == 1 c = conv(a, b, 'full'); elseif shape == 2 c = conv(a, b, 'same'); else c = conv(a, b, 'valid'); end
Save your changes and close the MATLAB Function Block Editor.
See Also.
In this exercise, you will add specialized instances of the my_conv_filter library block to a simple test model.
Open a new Simulink model.
For purposes of this exercise, set the following configuration parameters for simulation:
Pane  Section  What to Specify 

Solver  Solver options 

Data Import/Export  Save options  Structure for Format 
Drag two instances of the my_conv_filter block
from the my_filter_lib
library into the model.
Add Constant, Outport, and Display blocks. Your model should look something like this:
Both library instances share the same size, type,
and complexity for inputs a
and b
respectively.
Doubleclick each library instance.
The shape
parameter defaults to full for
both instances.
Simulate the model.
Each library instance outputs the same result, the full 2D convolution:
Specialize the second instance, my_conv_filter1 by
setting the value of its shape
parameter to same.
Now simulate the model again.
This time, the outputs have different sizes: my_conv_filter3 outputs
the full 2D convolution, while my_conv_filter1 displays
the central part of the convolution as a 1by2 vector, the same size
as a
:
Now, add a third instance by copying my_conv_filter1. Specialize the new instance, my_conv_filter2, so that it does not inherit the same size inputs as the first two instances:
Simulate the model again.
This time, my_conv_filter1 and my_conv_filter2 each
display the central part of the convolution, but the output sizes
are different because each matches a different sized input a
.
When instances of MATLAB Function library blocks inherit the same properties, they can reuse generated code, as illustrated by an example based on Step 4: Add Instances of MATLAB Library Blocks to a Simulink Model:
In this model, the library instances my_conv_filter and my_conv_filter1 inherit
the same size, type, and complexity for each respective input. For
each instance, input a
is a 1by2 vector and input b
is
a 1by5 vector. By comparison, the inputs of my_conv_filter2 inherit
different respective sizes; both are 1by3 vectors.
In addition, each library instance has a mask parameter called shape that determines what subsection of the convolution to output. Assume that the value of shape is the same for each instance.
To generate code for this example, follow these steps:
Enable code reuse for the library block:
In the library, rightclick the MATLAB Function block my_conv_filter and select Block Parameters (Subsystem) from the context menu.
In the Function Block Parameters dialog box, set these parameters:
Select the Treat as atomic unit check box.
In the Function packaging field,
select Reusable function
from the dropdown
menu.
Configure the model for code generation.
For purposes of this exercise, set the following configuration parameters:
Pane  Section  What to Specify 

Code Generation  Target selection  Enter ert.tlc for System
target file 
Code Generation > Report  Select Create code generation report check box. 
Build the model.
If you build this model, the generated C code reuses logic for
the my_conv_filter
and my_conv_filter1
library
instances because they inherit the same input properties:
/* * Output and update for atomic system: * '<Root>/my_conv_filter' * '<Root>/my_conv_filter1' */ void sp_algorithm_tes_my_conv_filter(const real32_T rtu_a[2], const real32_T rtu_b[5], rtB_my_conv_filter_sp_algorithm *localB) { int32_T jA; int32_T jA_0; real32_T s; int32_T jC; /* MATLAB Function Block: '<S1>/my_conv_filter' */ /* MATLAB Function 'my_conv_filter/my_conv_filter': '<S4>:1' */ /* '<S4>:1:4' */ for (jC = 0; jC < 6; jC++) { if (5 < jC + 2) { jA = jC  4; } else { jA = 0; } if (2 < jC + 1) { jA_0 = 2; } else { jA_0 = jC + 1; } s = 0.0F; while (jA + 1 <= jA_0) { s += rtu_b[jC  jA] * rtu_a[jA]; jA++; } localB>c[jC] = s; } /* end of MATLAB Function Block: '<S1>/my_conv_filter' */ } 
However, a separate function is generated for my_conv_filter2:
/* Output and update for atomic system: '<Root>/my_conv_filter2' */ void sp_algorithm_te_my_conv_filter2(const real_T rtu_a[3], const real_T rtu_b[3], rtB_my_conv_filter_sp_algorit_h *localB) { int32_T jA; int32_T jA_0; real_T s; int32_T jC; /* MATLAB Function Block: '<S3>/my_conv_filter' */ /* MATLAB Function 'my_conv_filter/my_conv_filter': '<S6>:1' */ /* '<S6>:1:4' */ for (jC = 0; jC < 5; jC++) { if (3 < jC + 2) { jA = jC  2; } else { jA = 0; } if (3 < jC + 1) { jA_0 = 3; } else { jA_0 = jC + 1; } s = 0.0; while (jA + 1 <= jA_0) { s += rtu_b[jC  jA] * rtu_a[jA]; jA++; } localB>c[jC] = s; } /* end of MATLAB Function Block: '<S3>/my_conv_filter' */ } 
Note: Generating C code for this model requires a Simulink Coder™ or Embedded Coder^{®} license. 
You debug MATLAB Function library blocks the same way you debug any MATLAB Function block. However, when you add a breakpoint in a library block, the breakpoint is shared by all instances. As you continue execution, the debugger stops at the breakpoint in each instance.
For more information, see Debugging a MATLAB Function Block
You can specialize instances of MATLAB Function library blocks by allowing them to inherit any of the following properties from Simulink:
Property  Inherits by Default?  How to Specify Inheritance 

Type  Yes  Set data type property to Inherit: Same as Simulink. 
Size  Yes  Set data size property to 1. 
Complexity  Yes  Set data complexity property to Inherited. 
Limit range  No  Specify minimum and maximum values as Simulink parameters. For example, if minimum value = aParam and
maximum value = aParam + 3, different instances
of a MATLAB Function library block can resolve to different aParam parameters
defined in their parent mask subsystems. 
Sampling mode (input)  Yes  MATLAB Function block input ports always inherit sampling mode 
Data type override mode for fixedpoint data  Yes  Set data type override property to Inherit. 
Sample time (block)  Yes  Set block sample time property to 1. 