Guy on Simulink

Simulink & Model-Based Design

Tips for Working with Simulink Libraries and Data Dictionaries

I came across an interesting feature recently for Simulink® libraries that could be helpful when working with buses and other types associated with them.

The Problem

Let's say we have a library with multiple blocks that use a specific bus on their interfaces, for example, myBus. When generating code for our models I recommend using non-virtual bus definitions so we can have strict control over how these buses appear in the code. This bus has 3 elements, a boolean, sel, and two uint32 values, a1 and a2. As a specific example, one of the blocks from our library uses this bus for a selection operation.
myLibBlock.png
When we want to use these library blocks in one of our models, we'll need to have myBus defined somewhere in the scope of this model. This means that each model that uses blocks from this library must have a setup script or be associated with a Simulink data dictionary. Conceptually, our setup would look like this diagram:
In the above figure, the yellow arrows indicate library block usage and the blue arrows show data dictionary links.

The Desired Situation

This setup works, but it would be better if we could have the definition of myBus come along with the library instead. This would save our library users time and streamline their workflows. Conceptually, we want to follow the guiding principle that the interface for a reusable component is stored with that component. With this in mind, our diagram should look like this:
Here the dictionary containing myBus will automatically be included in any model that uses blocks from the library. We'll show how to do this in the following section.

Associating a Dictionary with a Library

Let's start by creating the required bus definition in a data dictionary. From the Model Explorer, we choose File->New Data Dictionary and provide a file name. We'll call it myLibDict.sldd. Next, we'll select the Design Data section of the dictionary and choose Add->Simulink Bus, and rename the bus to myBus.
We'll add the elements to this bus using the new Type Editor interface:
typeEditor.png
In this interface, we can set up the element names, data type, etc. for our bus elements. Once we're done, we can see the bus definition in the dictionary in the Model Explorer:
myBusDef.png
Now that we have this definition, we associate myLibDict.sldd with myLib.slx. Start by selecting myLib in the left panel of Model Explorer and choosing the External Data tab in the right panel. In the Data Dictionary Field, enter myLibDict.sldd and press apply. Here I've cropped and zoomed in on the relevant panels.
AssocLibLeft.png AssocLibRight.png
Once we've done this, we can see this association in the External Data field in the Model Explorer:
myLibConf.png
Any model that uses the library will now automatically have access the bus definition. Specifically, myModel.slx, which uses the library block, can use the bus definition. In this case, the input is defined to be of type myBus. This is clear when we update the diagram for myModel.
myModel.png

Housekeeping for Library Dictionaries

Occasionally, we may need to restructure the files in a project or share it via archive. When we do this, the library dictionary dependencies will need to be recomputed because they are cached on disk in the user preferences file to increase performance during diagram updates. We'll show examples of how to handle these situations in this section.

Example 1: Reorganizing our Files

Now let's say we want to reorganize our project and move our library to a directory called "Libraries". Initially the files are all in the root folder of the project:
preMoveFolder.png
We create the directory "Libraries" and move myLib.slx and myLibDict.sldd to this directory and add it to our path:
postMoveFolder.png
After this move, we get an error when we try to simulate our model:
simError.png
To fix this error, we need to close the dictionary with Simulink.data.dictionary.closeAll() and refresh the links with Simulink.LibraryDictionary.refresh().
Simulink.data.dictionary.closeAll()
Simulink.LibraryDictionary.refresh('./Libraries')
This will update the cached dictionary dependency analysis and allow us to simulate myModel.

Example 2: Sharing an Archive

As a final example, let's say we want to share our project with a colleague via an archive, let's call it myProject.mlproj. We can prevent the above error when our colleague opens this project and attempts to simulate myModel by adding the following line to a project startup script. Here we can see the script myStartupScript.m in our project and the code in the editor. Note that the Run At Startup icon is set in the Status column (circled in red). We get this by right-clicking on myStartupScript.m in the project window and selecting Run At Startup from the menu.
StartupScript.png
This will allow our colleague to simulate and generate code from the model.

Now It's Your Turn

How do you store your buses and interfaces? Do you find this feature useful? Please let us know in the comments below.
|
  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.