Simulink Functions hit the big time
The release of R2014b brought a time-honored Stateflow feature up to the model level: Simulink Functions. These blocks, analogous to stand-alone MATLAB functions, promote modularity and reuse by allowing you to call the same set of blocks from anywhere in your model – even from inside a Stateflow chart!
A block unlike any other
Simulink Functions are unlike any other Simulink block, even other user-defined functions like Function-Call Subsystems. For starters, the block does not use traditional ports. Instead, like MATLAB functions, you specify arguments.
Inside the Simulink Function, arguments are represented by unique-looking Argument port blocks.
Since they aren’t traditional ports, you won’t find these blocks in the Library Browser. To add or remove arguments, you type right on the block’s mask:
To use a Simulink Function in your model, you employ a Function Caller block.
Simulink associates each instance of this block with a Function by the function name; it requires that every function name in the model hierarchy be unique.
Functions in referenced models
Speaking of hierarchy, one very practical use of Simulink Functions are in a referenced model context. Functions defined in a referenced model are in the scope of its parent. But, the referenced model has to follow some very special design rules, the same as they do when they contain Function-Call Subsystems.
The simplest way to adhere to these rules is to create a model that contains nothing but your collection of Simulink Function blocks, like so:
Now add a Model block to your parent model, point it to this collection, and you can call any of these functions from the parent, or from any other model further up the hierarchy.
Generating code
Code generated from Simulink Functions is as modular and straightforward as you would expect. Each function is defined in its own source file. The function prototype always takes the form of:
void foo(type_T in1, type_T in2, type_T *out1, type_T *out2)
Simulink is smart enough to recognize when you are trying to emulate pass-by-reference, and you name your output the same as your input (like I did in the timestwo example in the images above). When you do, the generated function prototype looks just like this:
void foo(type_T *x)
Now it’s your turn
This opens up a whole new way to model. What kind of design patterns can you create?
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.