I started writing this post with the goal of talking about the new Initialize Function, Reset Function and Terminate Function blocks, along with the closely related State Reader and State Writer blocks introduced in R2016b.
However I quickly realized that those new features are very closely related to a type of model architecture I almost never talked about on this blog: Export Function Models.
Let's use the following model as example. It contains a Bias and Unit Delay block executing at 0.001s and a Math Function block executing at 0.01s.
As you all probably know, with Embedded Coder it is possible to generate C code from a Simulink model. Using the default Embedded Coder System Target File, the code you will get will look something like:
As you can see, the code is made of one Initialize function, and a Step function. The step function is designed to be called at the model base rate, 0.001s in our case. Perfect to execute the code in a single-tasking context.
If you prefer, you can ask Simulink to Treat each discrete rate as a separate task.
In this case, the generated code will be composed of one function par sample time. It is then possible for you to implement the scheduler and call each rate the way you want.
Having one function per rate is useful, but what if you want more control over the execution of the code? For example, you could want one rate to be divided into multiple tasks, and assign different priority to each of them.
For that, Embedded Coder offers the possibility to export functions. Exporting functions provides direct control over the generated functions and the ability to simulate their scheduling and prioritization.
To be compatible with the concept of export functions, your model must be built in a specific way: The top level of the system for which you want to export functions must contain only Function Call Subsystems, Inports and Outports. That way, one function per subsystem will be generated.
For our example model, we can rearrange it that way:
For simulation, the scheduling of the different tasks must be done explicitly, for example using Stateflow as in the above image. When time comes to generate code, you can right-click on the subsystem and export the functions:
The code will look like the following:
And you will be able to include this code in your hand-written scheduler. As mentioned above, this would allow you to divide one rate into multiple functions, or tasks.
Export Function Model
For large projects, it is also possible to create Export Function Models.
In this case, the top model will be used for simulation only, and you will generate code for the child model. Simulink will automatically recognize that the model is designed to export function, and the code will be similar to the one generated from the subsystem above.
Next week, we will see how the new Initialize Function, Reset Function and Terminate Function blocks can be used inside export function models to simulate the shutdown and restarting of the function or task.