Managing memory with the MicroC profile

The MicroC profile provides a mechanism for incorporating memory segmentation into your application, including the ability to allocate memory to ROM.
Note: This feature is available only when you have specified that your application should use compile-time initialization (see Using compile-time initialization).

Enabling generation of memory segmentation code

Use the C_CG::Configuration::EnableSegmentedMemory property to enable or disable the generation of memory segmentation code for your application.

Assigning attributes to specific memory segments

Attributes are assigned to specific memory segments using the following properties:

Although they are attribute-level properties, the most efficient way to use these properties is as follows:

  1. For each memory segment you want to use, create a stereotype that is applicable to attributes.
  2. Provide values for these properties for the new stereotype that you created.
  3. Apply the stereotype to all attributes that will be assigned to that memory segment.

Use the memory segment properties as follows:

Effect of memory segment properties on the generated code

When you provide a segment name for the MemorySegmentName property, the generated code includes a new struct whose name concatenates the class name and the name of the memory segment. This struct contains all the attributes that have been assigned to this memory segment.

Since attributes will be declared in the relevant memory segment struct, you might have a situation where the attributes you defined in a given class in your model end up distributed among a number of these memory segment structs. The struct generated to represent the type of the class in your model will include pointers to these attributes.

The code entered for the prolog properties (specification and implementation) will be generated before the list of data structures assigned to the memory segment, for example:
#pragma data_seg("ROM")
The code entered for the epilog properties (specification and implementation) will be generated after the list of data structures assigned to the memory segment, for example:
#pragma data_seg(DEFAULT)

Accessing segmented data for a class

Because the attributes defined for a class in your model might end up distributed among different memory segment structs in the generated code, Rational Rhapsody provides macros for accessing this data without having to specify the memory segment it is assigned to. The format used for the macros is determined by the value of the C_CG::Attribute::SegmentedAttributeMacroName property.

For example, if you keep the default value of the property, $class_$attribute, the code generated will resemble: #define file_0_variable_0 file_0_Seg1.variable_0

Note: The provided macros are for use inside the class only. For accessing attributes from outside the class, you can use the Accessor/Mutator operations. In addition, exposing the implementation for the macro externally is not allowed, for example, within a public inline operation.

Assigning relations and flow ports to a specific memory segment

In addition, with the MicroC profile you can assign all relations and flow ports to a specific memory segment.

Note: The assignment of flow ports and relations to a specific memory segment applies only to direct flow ports and direct relations (meaning that the C_CG::Configuration::DirectFlowPorts property and the C_CG::Configuration::DirectRelations property must be set to True.)

To assign relations and flow ports to a specific memory segment:

Example of memory segment usage

This example shows how the values specified for the memory segmentation properties are reflected in the code that is generated by Rational Rhapsody.

Property name Property value
C_CG::Configuration::DefaultROMSegmentName ROM
C_CG::Configuration::FarPointerQualifier far
for first segment (stereotype applied to variable_0 in file_0 model):  
C_CG::Attribute::MemorySegmentName Seg1
C_CG::Attribute::MemorySegmentSpecificationProlog #pragma DATA_SEG $seg
C_CG::Attribute::MemorySegmentSpecificationEpilog #pragma DATA_SEG DEFAULT
C_CG::Attribute::MemorySegmentImplementationProlog #pragma DATA_SEG $seg
C_CG:Attribute:MemorySegmentImplementationEpilog #pragma DATA_SEG DEFAULT
C_CG::Attribute::SegmentedAttributeMacroName $class_$attribute
for second segment (stereotype applied to variable_1 in file_0 in model):  
C_CG::Attribute::MemorySegmentName Seg2
C_CG::Attribute::MemorySegmentSpecificationProlog #pragma DATA_SEG "$seg"
C_CG::Attribute::MemorySegmentSpecificationEpilog #pragma DATA_SEG DEFAULT
C_CG::Attribute::MemorySegmentImplementationProlog #pragma DATA_SEG "$seg"
C_CG:Attribute:MemorySegmentImplementationEpilog #pragma DATA_SEG DEFAULT
C_CG::Attribute::SegmentedAttributeMacroName $class_$attribute

Resulting code

h file:
#ifndef file_0_H
#define file_0_H

/*## auto_generated */
#include "mxf\Ric.h"
/*## auto_generated */
#include "Default.h"
/*## package Default */

/*## class TopLevel::file_0 */
/*#[ ignore */
typedef struct file_0_Seg1_t {
    int variable_0;		/*## attribute variable_0 */
} file_0_Seg1_t;

#define file_0_variable_0 file_0_Seg1.variable_0
typedef struct file_0_Seg2_t {
    int variable_1;		/*## attribute variable_1 */
} file_0_Seg2_t;

#define file_0_variable_1 file_0_Seg2.variable_1

/*#[ ignore */
#pragma DATA_SEG Seg1

/*#]*/
extern struct file_0_Seg1_t file_0_Seg1;
/*#[ ignore */
#pragma DATA_SEG DEFAULT

/*#]*/

/*#[ ignore */
#pragma DATA_SEG "Seg2"

/*#]*/
extern struct file_0_Seg2_t file_0_Seg2;
/*#[ ignore */
#pragma DATA_SEG DEFAULT

/*#]*/
/*#]*/
/***    User explicit entries    ***/

#endif
/******************************************************************
File Path	: DefaultComponent\DefaultConfig\file_0.h
*****************************************************************/
c file:
/*## auto_generated */
#include "file_0.h"
/*## package Default */

/*## class TopLevel::file_0 */
/*#[ ignore */

/*#[ ignore */
#pragma DATA_SEG Seg1

/*#]*/
struct file_0_Seg1_t file_0_Seg1;
/*#[ ignore */
#pragma DATA_SEG DEFAULT

/*#]*/

#pragma DATA_SEG "Seg2"struct file_0_Seg2_t file_0_Seg2;
/*#[ ignore */
#pragma DATA_SEG DEFAULT

/*#]*/
/*#]*/

/*********************************************************************
	File Path	: DefaultComponent\DefaultConfig\file_0.c
*********************************************************************/

Feedback