Create Storage Classes by Using the Custom Storage Class Designer - MATLAB & Simulink (original) (raw)

To control the appearance of data in the generated code, you can use built-in storage classes such as ExportToFile (see Organize Parameter Data into a Structure by Using Struct Storage Class). If the built-in storage classes do not meet your requirements, you can create your own storage classes. See Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture.

To define a storage class that you can apply in a model by using the Code Mappings editor, use the Embedded Coder Dictionary. Or, create the storage class in a SimulinkĀ® data class package and refer to the package from the Embedded Coder Dictionary.

A data class package contains storage class and memory section definitions that you can map to model interface elements. A data class package also can defineSignal and Parameter data classes from which you can create data objects that specify values and other characteristics of signals, states, and block parameters. Using data objects, you can make model-wide changes to signal, state, and parameter characteristics by changing only the values of the objects. Data objects that you create from your package can use the storage classes that the package defines. For more information, see Data Objects.

You can use packages that are built into Simulink, such as Simulink and mpt, or you can create your own package by using the Custom Storage Class Designer.

For information about using the Custom Storage Class Designer to create memory sections, see Control Data and Function Placement in Memory by Inserting Pragmas.

Create and Apply Storage Class Defined in User-Defined Package

This example shows how to control code generated from a model by defining a storage class in a user-defined data class package and applying the storage class for data objects.

Explore Example Model

Open the model CustomStorageClasses.

open_system('CustomStorageClasses')

In this example, you export the declarations and definitions of multiple signals and parameters in the model to one declaration header file and one definition file.

Create Data Class Package

To define a storage class in a data class package, create a data class in a MATLAB namespace folder for the package.

  1. Navigate inside the +myPackage folder to the fileSignal.m.
  2. Open Signal.m and edit the definition of theSignal class. Uncomment the methods section that defines the methodsetupCoderInfo. In the call to the functionuseLocalCustomeStorageClasses, replace'packName' with 'myPackage'. The functionuseLocalCustomeStorageClasses allows you to apply the storage classes that myPackage defines to data objects that you create from myPackage.
    methods
    function setupCoderInfo(h)
    % Use custom storage classes from this package
    useLocalCustomStorageClasses(h, 'myPackage');
    end
    end % methods
  3. Save and close Signal.m.
  4. Navigate inside the +myPackage folder to the fileParameter.m.
  5. Open Parameter.m and make the same edits that you did for step 4 in the file Signal.m.
  6. Save and close Parameter.m.

For more information on how to create a data class, see Define Data Classes.

Create Storage Class in Data Class Package

Use the Custom Storage Class Designer to create or edit storage classes that a data class package defines.

  1. Check that your current folder lists MATLAB namespace folder+myPackage.
  2. Open the Custom Storage Class Designer by entering thecscdesigner command with the name of the package that you want to open. For this example, specify 'myPackage'. When specifying the namespace folder for a package in the cscdesigner command, omit the + character.
  3. In the Custom Storage Class Designer, under Custom storage class definitions, select storage class ExportToFile.
  4. For Name, specify ExportToGlobal.
  5. For Header file, select Specify. In the new field that appears, specify header file nameglobal.h.
  6. For Definition file, selectSpecify. In the new field that appears, specify the definition file name global.c.
  7. Click OK. Click Yes to save your changes to package myPackage.

Apply Storage Class to Data Objects

To apply the storage class that you define in a data class package to data objects, create the data objects from your package and configure the objects to use the storage class.

  1. Create data objects to represent some of the signals and parameters in the example model. Create the data objects by using the packagemyPackage.
    % Signals
    tempalarm = myPackage.Signal;
    pressurealarm = myPackage.Signal;
    O2alarm = myPackage.Signal;
    rpmalarm = myPackage.Signal;
    % Parameters
    templimit = myPackage.Parameter(202);
    pressurelimit = myPackage.Parameter(45.2);
    O2limit = myPackage.Parameter(0.96);
    rpmlimit = myPackage.Parameter(7400);
  2. Set the storage class of each object to ExportToGlobal.
    % Signals
    tempalarm.CoderInfo.StorageClass = 'Custom';
    tempalarm.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    pressurealarm.CoderInfo.StorageClass = 'Custom';
    pressurealarm.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    O2alarm.CoderInfo.StorageClass = 'Custom';
    O2alarm.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    rpmalarm.CoderInfo.StorageClass = 'Custom';
    rpmalarm.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    % Parameters
    templimit.CoderInfo.StorageClass = 'Custom';
    templimit.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    pressurelimit.CoderInfo.StorageClass = 'Custom';
    pressurelimit.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    O2limit.CoderInfo.StorageClass = 'Custom';
    O2limit.CoderInfo.CustomStorageClass = 'ExportToGlobal';
    rpmlimit.CoderInfo.StorageClass = 'Custom';
    rpmlimit.CoderInfo.CustomStorageClass = 'ExportToGlobal';
  3. For each signal for which you created an object and specified theExportToGlobal storage class, select the propertySignal name must resolve to Simulink signal object.
    % Signal tempalarm
    portHandles = get_param('CustomStorageClasses/RelOp1','PortHandles');
    outputPortHandle = portHandles.Outport;
    set_param(outputPortHandle,'MustResolveToSignalObject','on')
    % Signal pressurealarm
    portHandles = get_param('CustomStorageClasses/RelOp2','PortHandles');
    outputPortHandle = portHandles.Outport;
    set_param(outputPortHandle,'MustResolveToSignalObject','on')
    % Signal O2alarm
    portHandles = get_param('CustomStorageClasses/RelOp3','PortHandles');
    outputPortHandle = portHandles.Outport;
    set_param(outputPortHandle,'MustResolveToSignalObject','on')
    % Signal rpmalarm
    portHandles = get_param('CustomStorageClasses/RelOp4','PortHandles');
    outputPortHandle = portHandles.Outport;
    set_param(outputPortHandle,'MustResolveToSignalObject','on')
  4. Execute an update diagram to set the values of the parameters for which you created an object and specified the ExportToGlobal storage class.

Generate and Inspect Code

Generate code for the example model.

  1. In the model window, open the Embedded Coder app.
  2. Generate code for the example model.
    slbuild('CustomStorageClasses')
  3. In the Code view, view the generated header file global.h. The file contains the extern declarations for the model signals and parameters that are configured to use the ExportToGlobal storage class.
    /* Declaration for custom storage class: ExportToGlobal */
    extern boolean_T O2alarm;
    extern real_T O2limit;
    extern boolean_T pressurealarm;
    extern real_T pressurelimit;
    extern boolean_T rpmalarm;
    extern real_T rpmlimit;
    extern boolean_T tempalarm;
    extern real_T templimit;
  4. View the generated file global.c. The file contains the definitions of the model signals and parameters that are configured to use theExportToGlobal storage class.
    /* Definition for custome storage class: ExportToGlobal */
    boolean_T O2alarm;
    real_T O2limit = 0.96;
    boolean_T pressurealarm;
    real_T pressurelimit = 45.2;
    boolean_T rpmalarm;
    real_T rpmlimit = 7400.0;
    boolean_T tempalarm;
    real_T templimit = 202.0;

Modify a Built-In Storage Class

You cannot directly modify a built-in storage class, such asExportToFile from the Simulink package, but you can create a copy, and then modify the copy. When you create a new package with nocsc_registration.m file, and then open the Custom Storage Class Designer for the first time, Simulink copies the definitions of the built-in storage classes into the package. Then, in the Custom Storage Class Designer, you can modify the copied definitions. Alternatively, to keep the built-in storage classes available in your package, copy one of them by clickingCopy, then modify the resulting copy.

Control Data Representation by Configuring Storage Class Properties

The Custom Storage Class Designer is a tool for creating and managing storage classes and memory sections. To open the Custom Storage Class Designer for a specific package, for example, mypkg, at the command prompt, use thecscdesigner function:

The MATLABĀ® namespace folder that contains a package begins with a +. When you use the function cscdesigner, omit the + from the package name.

To control the effect that a storage class has on data in a model, specify properties of the storage class in the Custom Storage Class Designer. To determine how to generate a particular kind of data in generated code, use the information in this table.

Allow Users of Storage Class to Specify Property Value

For some properties of a storage class, such as Data scope, instead of specifying a value in the Custom Storage Class Designer, you can allow users of the storage class to specify the value. You can create a single, flexible storage class instead of multiple storage classes that vary only by a few property values.

For example, suppose you create a storage class that yields a global variable in the generated code. You can configure the storage class so that a user can set theData scope property to Exported for a signal in a model and set the property to Imported for a different signal.

In the Custom Storage Class Designer, for each property that you want to configure in this way, set the property value to Instance specific. Then, when a user applies the storage class to a data item, the property appears to the user as a custom attribute for that data item. For information about instance-specific custom attributes, see Storage Class Properties.

Generate a Macro

To create a storage class that yields a macro in the generate code, set Data initialization to Macro and clear For signals.

When you set Data initialization toMacro, Definition file has no meaning. To prevent users of the storage class from specifying a meaningless definition file, in the Custom Storage Class Designer, setDefinition file to Specify and leave the text box empty.

Generate Structured Data

To create a storage class that aggregates data items into a flat structure (similar to the built-in storage class Struct), set Type toFlatStructure. The Structure Attributes tab appears.

Control Assignment of Initial Value in Generated Code

Call Custom Accessor Functions or Macros Instead of Reading and Writing to Variables

Using the built-in storage class GetSet, you can generate code that calls your external, custom functions instead of directly interacting with variables. For general information about GetSet, see Access Data Through Functions with Storage Class GetSet.

To create a similar storage class, set Type toAccessFunction.

Generate Code That Uses Data From External Code

When your external code defines data, to avoid generating a duplicate definition, you must configure the generated code to read and write to the existing data. In the Custom Storage Class Designer, set Data scope toImported. The code generator does not generate a definition for the global variable or macro.

Generate Code Comments with Data Definitions and Declarations

To customize the comments that appear in the generated code, on theComments tab, set Comment rules toSpecify. To specify a comment that appears with the declaration of each data item, use the Declaration comment box. To specify a comment that appears with the definition, use the Definition comment box.

For structured data (you set Type toFlatStructure), to specify a comment that appears with the structure type definition, use the Type comment box.

Avoid Errors During Code Generation by Validating Storage Class Configuration

As you configure a storage class in the Custom Storage Class Designer, to check for possible errors in the configuration, click Validate.

For example, validating the storage class warns you if you accidentally setData initialization to Macro withFor signals selected. A signal cannot appear in the generated code as a macro.

Make Storage Classes Available Outside the Current Folder

To use a storage class that you create, you must make the defining package available. Set your current folder to the namespace folder that contains the package or add the folder containing the package namespace folder to the MATLAB path (see What Is the MATLAB Search Path?). Adding the package namespace folder to the MATLAB path enables you to use the storage classes no matter where you set your current folder.

Make Storage Classes Available in the Code Mappings Editor

To use package-based storage classes in the Code Mappings editor, configure the Embedded Coder Dictionary to refer to the package as explained in Refer to Code Generation Definitions in a Package.

Share Storage Class Between Packages

When you create a package, you can refer to a storage class defined in another package such as the built-in package Simulink or a different package that you created. Then, the defining package and referencing packages can use the storage class. When you want to make a change to the storage class, you make the change only once, in the defining package.

To configure a package to refer to a storage class that another package defines:

  1. In the Custom Storage Class Designer, select the Custom Storage Class tab.
  2. Use Select Package to select the referencing package. The package must be writable.
  3. In the Custom storage class definitions pane, select the existing definition below which you want to insert the reference.
  4. Click New Reference.
    A new reference with a default name and properties appears below the previously selected definition. The new reference is selected and a Reference tab appears that shows the initial properties.
  5. Use Name to specify a name for the new reference. The name must be unique in the importing package, but can duplicate the name in the source package. The name cannot be a TLC keyword.
  6. Set Refer to custom storage class in package to specify the package that contains the storage class that you want to reference.
  7. Set Custom storage class to reference to specify the storage class to be referenced.
  8. Click OK or Apply. To save the changes permanently, click Save.

Control Appearance of Storage Class Drop-Down List

When you apply a storage class to a data item, you select the storage class from a drop-down list.

Protect Custom Storage Class Definitions

When you click Save in the Custom Storage Class Designer, the Designer saves memory section and storage class definitions into thecsc_registration.m file in the package namespace folder. To determine the location of this file, in the Custom Storage Class Designer, inspect the value ofFilename.

You can prevent changes to the storage class definitions of an entire package by converting the csc_registration.m file from a MATLAB file to a P-file. Use the pcode function.

A best practice is to keep csc_registration.m andcsc_registration.p in your package namespace folder. That way, if you modify the storage classes by using the Designer, you can deletecsc_registration.p and later regenerate it after you finish the modifications. Because the P-coded version of the file takes precedence, when both files exist in the package, the storage classes are protected and you cannot modify them in the Custom Storage Class Designer.

Further Customize Generated Code by Writing TLC Code

If creating your own storage class by manipulating the properties in the Custom Storage Class Designer does not meet your requirements, you can finely control the generated code by writing TLC code for your storage class. Use an advanced mode of the Custom Storage Class Designer and, for the storage class, set Type toOther. See Finely Control Data Representation by Writing TLC Code for a Storage Class.