%% ============================================================================
%% $RCSfile: capi.tlc,v $
%% $Revision: 1.1.6.21 $
%%
%% Abstract:
%%      This system file creates C API files model_capi.c and model_capi.h.
%%      The API facilitates Block IO Signal monitoring and/or Parameter Tuning.
%%
%% Copyright 1994-2004 The MathWorks, Inc.
%%

%if EXISTS("_CAPI_") == 0
%assign _CAPI_ = 1

%include "capilib.tlc"

%% Function SLibWriteToCAPIFiles ========================================
%% Abstract :
%%   This function creates model_capi.c and model_capi.h files 
%%     o For ERT based target, the files are written using code generation 
%%       templates. The _capi.c file uses ERTSrcFileBannerTemplate and 
%%       _capi.h file uses ERTHdrFileBannerTemplate
%%     o For non-ERT or ModelRefernce target, the code templates are 
%%       ignored and a lightweight template is used to write
%%       the files to disk
%% 
%function SLibWriteToCAPIFiles() void
  
  %realformat "CONCISE"
  
  %% Put necessary includes in model.h file
  %assign baseHFile = GetBaseFile("SystemHeader")
  %openfile includesBuf
  #include "rtw_modelmap.h"
  %closefile includesBuf
  %<SLibSetModelFileAttribute(baseHFile, "Includes", includesBuf)>

  %% Put necessary includes in model.c(pp) file
  %assign baseCFile = GetBaseFile("SystemBody")
  %openfile includesBuf
  %if ((RTWCAPIStates==1) || (RTWCAPISignals==1)) && ...
    (MatFileLogging || MatFileSignalLogging)
    #include "rt_logging_mmi.h"
  %endif
  #include "%<Name>_capi.h"
  %closefile includesBuf
  %<SLibSetModelFileAttribute(baseCFile, "Includes", includesBuf)>
  
  %% If necessary, add logging utility files to list of model sources 
  %if ((RTWCAPIStates==1) || (RTWCAPISignals==1)) && ...
    (MatFileLogging || MatFileSignalLogging)
    %<LibAddToModelSources("rt_logging_mmi")>
    %<LibAddToModelSources("rtw_modelmap_utils")>
  %endif
  
  %% Generate Interface API (GlobalMemoryMap) for non custom storage class data
  %<SLibMapData()> 
  
  %% Create Source file model_capi.c(pp) to cache Signals/parameters/states
  %% and data maps
  %assign capiCFile = LibCreateSourceFile("Source","Simulink", "%<Name>_capi")
  
  %% Add neccesary includes to model_capi.c - Create the Include Buffer
  %assign baseSysIdx = GetBaseSystemIdx()
  %assign baseName   = SLibGetSystemOutputFileBaseName(System[baseSysIdx])
  %openfile tmpCAPI_C_Includes
    #include "%<baseName>.h"
    #include "rtw_capi.h"
    %% imported signals are declared in model_private.h
    #include "%<Name>_private.h"
  %closefile tmpCAPI_C_Includes
  %<SLibSetModelFileAttribute(capiCFile,"Includes",tmpCAPI_C_Includes)>
  
  %% Decide whether you want to write capi files directly to disk or store   
  %% them in buffers and expand later via code templates.
  %% Code Templates will be used if
  %%      o Target is a ERT target (excluding Model reference targets)
  %%      o WriteCAPIUsingTemplates flag is set via ConfigSet->TLC options
  %%
  %assign isERT = CompiledModel.ConfigSet.IsERTTarget
  %if isERT
    %if IsModelReferenceTarget()
      %assign useTemplates = TLC_FALSE
    %elseif (WriteCAPIUsingTemplates == 0)
      %assign useTemplates = TLC_FALSE
    %else
      %assign useTemplates = TLC_TRUE
    %endif
  %else
    %assign useTemplates   = TLC_FALSE
  %endif
  
  %if (useTemplates)
    %% if using templates, store the CAPI structures in the Functions section
    %% of the model_capi.c file
    %openfile tmpCAPI_Functions
    %<FcnWriteCAPIStructures()>
    %closefile tmpCAPI_Functions
    
    %<SLibSetModelFileAttribute(capiCFile,"Functions",tmpCAPI_Functions)>
    
  %else
    %% if not using templates, write directly to disk
    %assign cFileIdx  = capiCFile.Index
    %assign FileName  = "%<Name>_capi.%<::LangFileExt>"
    %assign FileType  = "source"
    
    %<LibWriteToStandardOutput("### Writing %<FileType> file %<FileName>")>
    %openfile outputFile = FileName
    /*
     * %<FileName>
     *
     %<SLibCommonHeaderInfo()>\
     */
    
     %<tmpCAPI_C_Includes>\
     %<FcnWriteCAPIStructures()>
      
     /* EOF: %<FileName> */
    %closefile outputFile
    %% Set the filter to 1, to prevent re-writing to disk
    %<SLibSetModelFileAttribute(capiCFile, "Filter", 1)>
  %endif

  %% Create Header file model_capi.h and place extern function prototypes
  %assign capiHFile = ...
    LibCreateSourceFile("Header","Simulink", "%<Name>_capi")
  
  %% Include model.h in model_capi.h
  %assign baseSysIdx = GetBaseSystemIdx()
  %assign baseName   = SLibGetSystemOutputFileBaseName(System[baseSysIdx])
  %openfile tmpCAPI_H_Includes
  #include "%<baseName>.h"
  
  %closefile tmpCAPI_H_Includes
  %<SLibSetModelFileAttribute(capiHFile,"Includes",tmpCAPI_H_Includes)>
  
  %% Add a function prototype in model_capi.h
  %openfile tmpCAPI_H_Extern
  
  %assign args = FcnCAPIInitializeFcnArgs()
  %if IsModelReferenceSimTarget()
    extern void %<CompiledModel.Name>_InitializeDataMapInfo(%<tSimStructType> *%<RTMGetModelSS()>
      %<args.bArg>%<args.pArg>%<args.dwArg>%<args.xArg>, void *sysRanPtr, int contextTid);
  %else
    extern void %<CompiledModel.Name>_InitializeDataMapInfo(%<tSimStructType> *%<RTMGetModelSS()>
      %<args.bArg>%<args.pArg>%<args.dwArg>%<args.xArg>);
  %endif
  %closefile tmpCAPI_H_Extern
  %<SLibSetModelFileAttribute(capiHFile,"ExternFcns",tmpCAPI_H_Extern)>
  
  %if (useTemplates)
    %% Do nothing. The buffers are already created
  %else
    %% Write model_capi.h directly yo disk.
    %assign hFileIdx = capiHFile.Index
    %assign FileName = "%<Name>_capi.h"
    %assign FileType = "header"
    %assign FileTag  = LibGetModelFileTag(hFileIdx)
    
    %<LibWriteToStandardOutput("### Writing %<FileType> file %<FileName>")>
    
    %openfile outputFile = FileName
    /*
     * %<FileName>
     *
     %<SLibCommonHeaderInfo()>\
     */
     
     #ifndef _RTW_HEADER_%<FileTag>_
     #define _RTW_HEADER_%<FileTag>_
     
     %<tmpCAPI_H_Includes>\
     %<tmpCAPI_H_Extern>\
     
     #endif /* _RTW_HEADER_%<FileTag>_ */
     
     /* EOF: %<FileName> */
    %closefile outputFile
    %<SLibSetModelFileAttribute(capiHFile, "Filter", 1)>
  %endif
   
%endfunction %% SLibWriteToCAPIFiles()


%% Function FcnWriteCAPIStructures ========================================
%% Abstract:
%%   This function implements the bulk of CAPI functionality. It loops over
%%   signals/parameters/states and creates associated structures.
%%
%function FcnWriteCAPIStructures() Output
    
  %% Create a record for storing the maps.  The record will be accessed and
  %% updated during the generation of Signal/Parameter maps and
  %% DataType/DimensionMap/DimensionArray/DataAddr/FixPt maps. Here is a
  %% brief on what the fields represent
  %%     xyzMap -  buffer array containing elements of xyz Structure
  %%     xyzMapComments - comments on the elements in the xyz structure
  %%     Numfield - Counter to count the number of "fields" for maps
  %%     xyzKeys  - Hash tables for xyz structure
  %% Notes:
  %%     During Initialization
  %%     o bufer arrays and comments are empty
  %%     o counters (Numxxx) are zero except NumFixPoint. NumFixPoint=1 as
  %%       the first element in rtFixPt structure is RESERVED for non-fixed
  %%       point data
  %%     o keys are empty records

  %createrecord                 \
  InstMap {                     \
    DataTypeMap            [];  \
    DimensionMap           [];  \
    AddrMap                [];  \
    AddrMapComments        [];  \
    FixPointMap            [];  \
    LogSignalsBuf          [];  \
    DimArray               [];  \
    DimArrayComments       [];  \
    ElemMap                [];  \
    SampleTimeMap          [];  \
    DoublesMap             [];  \
    NumBlockParams          0;  \
    NumVariableParams       0;  \
    NumBIOSignals           0;  \
    NumBlockStates          0;  \
    NumFixPoint             1;  \
    NumDataTypes            0;  \
    NumDimensionMaps        0;  \
    NumDimArray             0;  \
    NumDataAddr             0;  \
    NumLogSignals           0;  \
    NumElements             1;  \
    NumSampleTimes          0;  \
    NumDoubles              0;  \
    FxpKeys {                   \
    }                           \
    DTypeKeys  {                \
    }                           \
    DimKeys    {                \
    }                           \
    DimArrayKeys {              \
    }                           \
    ElementKeys {               \
    }                           \
    STimeKeys {                 \
    }                           \
    DoubleKeys {                \
    }                           \
  }
  %assign im = InstMap
  %assign loggingInfoStartIdx  = []
  %assign loggingInfoBlockPath = []
  %assign loggingInfoPortIndex = []
  %assign loggingInfoSysNum    = []
  
  %% Multi Instance storage qualifier
  %assign constKeyword =  IsMultiInsatnceERTOrModelReference() ? "" : "const"
  
  %% Check if model Name has to be prefixed to structs
  %assign prefix       =  (::PrefixModelToStructs) ? "%<Name>_" : ""
    
  %% BlockHierarchyMap Loop =============================================
  %% The BlockHierarchyMap provides a in memory representation of the
  %% graphical model.
  %% For details refer to matlabroot/rtw/c/tlc/mw/graphmaplib.tlc
  %% The BlockSignal and BlockTuning structures are produced by looping
  %% through the Block records in BlockHierarchyMap.
  %% Begin BlockHierarchy Loop
  %with CompiledModel.GlobalMemoryMap
    %with BlockHierarchyMap
      %if RTWCAPISignals == 1
	
	%% Internal testing facility
	%if EXISTS("capiSigTestFile")
	  %include "%<capiSigTestFile>"
	%endif
	
	%% Start Signal structure Arrays
	/* Block output signal information */
	static %<constKeyword> %<tBlockSignalsType> %<tBlockSignals>[] = {
	  
	  /* addrMapIndex, sysNum, blockPath,
	   * signalLabel, portNumber, dataTypeIndex, dimIndex, fxpIndex, sampTimeIndex
	   */

	%createrecord portObj { SignalSrc [-1] SignalOffset [-1] Width 1 }
	%foreach subsysIdx = NumSubsystems
	  %with Subsystem[subsysIdx]
	    %foreach blkIdx = NumBlocks
	      %with Block[blkIdx]
		%% Loop through Data Output Ports & write signal data to
		%% BlockIOSignals structure
		%assign virtBlock = (Block[blkIdx].Virtual > 0) 
		%%0:nonvirt 1:virt 2:post comp virt
		%if ((!virtBlock) || (IsModelReferenceTarget()) ...
		  || (MatFileSignalLogging))
		  %foreach portIdx = NumDataOutputPorts
		    %with DataOutputPort[portIdx]
		      %foreach regIdx = NumRegions
			%%
			%% Skip non-testpointed virtual sigs.
			%%
			%if (virtBlock && (TestPoint == 0))
			  %continue
			%endif
			%assign portObj.SignalSrc = Region[regIdx]._Source
			%assign regionOffset      = Region[regIdx].Offset
			%assign regionDimensions  = Region[regIdx].Dimensions
			%assign sigRec = SLibGetSourceRecord(portObj, 0)
			%assign constString = ""		      
			%%
			%% Skip external inputs.
			%%
			%assign idNum = IDNUM(portObj.SignalSrc[0])
			%if idNum[0] == "U"
			  %continue
			%endif
			%% Skip function-call outputs
			%% See geck
			%if !(ISEMPTY(sigRec))
			  %if (RTWCAPITestPtSignals == 1) && ...
			    (sigRec.TestPoint !="yes")
			    %continue
			  %endif
			  %if (sigRec.Invariant == "yes") && ...
			    !IsMultiInsatnceERTOrModelReference()
			    %assign constString = "(void *) "
			  %endif
			  %if TYPE(sigRec.TID) != "Number" && ...
			    TYPE(sigRec.TID) == "String"
			    %% Check for non-sampled signals
			    %if sigRec.TID != "constant" && ...
			      sigRec.TID != "trigger"
			      %% Skip signals other than constant and triggered
			      %continue
			    %endif
			  %endif
			  %if sigRec.MemoryMapIdx[2] == -1
			    %% Skip  Local or reuse data
			    %continue
			  %else
			    %assign structIdx  = sigRec.MemoryMapIdx[0]
			    %assign secIdx     = sigRec.MemoryMapIdx[1]
			    %assign dataIdx    = sigRec.MemoryMapIdx[2]
			    %if secIdx == -1
			      %% Unstructured data
			      %assign data = UnstructuredData.Data[dataIdx]
			      %assign isComplex   = data.IsComplex
			      %assign dataTypeIdx = data.DataTypeIdx
			      %assign dataAccess  = data.Access
			      %assign isPointer   = ...
				dataAccess == "indirect" ? 1 : 0
			    %elseif structIdx == -1
			      %% Custom data
			      %assign data =  CustomData[secIdx].Data[dataIdx]
			      %assign isComplex   = data.IsComplex
			      %assign dataTypeIdx = data.DataTypeIdx
			      %assign dataAccess  = data.Access
			      %assign isPointer   = ...
				dataAccess == "indirect" ? 1 : 0
			      %assign constString = "(void *) "
			    %else
			      %% Structured data
			      %assign section     = ...
				StructuredData[structIdx].Section[secIdx]
			      %assign data        = section.Data[dataIdx]
			      %assign dataTypeIdx = section.DataTypeIdx
			      %assign isComplex   = section.IsComplex
			      %assign isPointer   = TLC_FALSE
			      %assign dataAccess  = "direct" 
			    %endif
			  %endif %% Non-Local Data
			  %if data.Class == "other"
			    %% Skip data of unknown layout
			    %continue
			  %endif
			  %if dataAccess == "unknown"
			    %% Skip data if DataAccess is unknown - R13 CSC's
			    %continue
			  %endif
			  %% Address
			  %assign addrMapIdx        = im.NumDataAddr
			  %if isPointer 
			    %assign sigAddress      = data.BaseAddr
			    %assign im.AddrMapComments = im.AddrMapComments+...
			      "%<im.NumDataAddr>: Signal Pointer"
			  %elseif virtBlock && (regionOffset > 0)
			    %% For virtual Blocks, e.g Demux
			    %% compensate for the offset
			    %if isComplex
			      %assign regionOffset  = regionOffset*2
			    %endif
			    %assign sigAddress      = constString + ...
			      "(%<data.BaseAddr> + %<regionOffset>)"
			    %assign im.AddrMapComments = im.AddrMapComments+...
			      "%<im.NumDataAddr>: Signal"
			  %else
			    %assign sigAddress = constString + data.BaseAddr
			    %assign im.AddrMapComments = im.AddrMapComments+...
			      "%<im.NumDataAddr>: Signal"
			  %endif
			  %assign im.AddrMap        = im.AddrMap + sigAddress
			  %assign im.NumDataAddr    = im.NumDataAddr + 1
			  %% Block Path
			  %assign grBlkIdx = [%<subsysIdx>, %<blkIdx>]
			  %assign blkPath  = SLibMangledGrBlockPath(grBlkIdx)
			  %assign blkPath  = STRING(blkPath)
			  %% Signal Label
			  %if sigRec.SigLabel != ""
			    %assign sigLabel = STRING(sigRec.SigLabel)
			  %else
			    %assign sigLabel = ""
			  %endif
			  %% Data Type
			  %assign dataTypeMapIdx = ...
			    FcnGetDataTypeMapIdx(dataTypeIdx,isComplex,isPointer,im)
			  %% Dimension
			  %if virtBlock
			    %assign dimMapIdx    = ...
			      FcnGetVirtSigDimensionMapIdx(data,regionDimensions,im)
			  %else
			    %assign dimMapIdx = FcnGetDimensionMapIdx(data,im)
			  %endif
			  %% Fixed Point
			  %if data.IsFixedPoint
			    %assign fxpMapIdx = FcnGetFxpMapIdx(data,im)
			  %else
			    %assign fxpMapIdx = 0
			  %endif
			  %% sample time index
			  %if (sigRec.FrameData == "yes")
			    %assign isFrame =  1
			  %else
			    %assign isFrame =  0
			  %endif
			  %if TYPE(sigRec.TID) == "Number"
			    %assign tID      = sigRec.TID
			    %assign sTimeIdx = FcnGetSampTimeIdx(tID,isFrame,im)
			  %elseif sigRec.TID == "constant"
			    %assign tID      = -2
			    %assign sTimeIdx = FcnGetSampTimeIdx(tID,isFrame,im)
			  %elseif sigRec.TID == "trigger"
			    %assign tID      = -1
			    %assign sTimeIdx = FcnGetSampTimeIdx(tID,isFrame,im)
			  %else
			    %assign errTxt = "Unhandled TID type."
			    %<LibReportError(errTxt)>
			  %endif
			  %% get the system number
			  %assign sysNum = sigRec.SysNum
			  %% Write data directly to BlockIOSignal structure
			  {%<addrMapIdx>, %<sysNum>, "%<blkPath>",
			  "%<sigLabel>", %<portIdx>, %<dataTypeMapIdx>, \
			  %<dimMapIdx>, %<fxpMapIdx>, %<sTimeIdx>},
			  %% Construct the loggingInfo to be dumped later
			  %if IsModelReferenceSimTarget()
			    %assign loggingInfoStartIdx  = ...
			      loggingInfoStartIdx + regionOffset
			    %assign loggingInfoBlockPath = ...
			      loggingInfoBlockPath + ...
			      STRING(SLibMangledGrBlockPath(sigRec.GrSrc))
			    %assign loggingInfoPortIndex = ...
			      loggingInfoPortIndex + sigRec.GrSrc[2]
			    %% Figure out the system number
			    %assign loggingInfoSysNum = ...
			      loggingInfoSysNum + %<SLContextSysNum>
			  %endif
			  %assign im.NumBIOSignals = im.NumBIOSignals + 1
			%endif  %% !ISEMPTY(sigRec)
		      %endforeach  %% regIdx = NumRegions
		    %endwith  %% DataOutputPort[portIdx]
		  %endforeach  %% portIdx = NumDataOutputPorts
		%endif  %% Block[blkIdx].Virtual == 0
		%if Block[blkIdx].Type == "Stateflow" && ...
		  ISFIELD(Block[blkIdx],"ChartData")
		  %assign dwRec = CompiledModel.DWorks.DWork[DWork[0]._idx]
		  %with ChartData
		    %foreach chdIdx = NumChartData
		      %assign chartData  = ChartData[chdIdx]
		      %assign structIdx  = chartData.MemoryMapIdx[0]
		      %assign secIdx     = chartData.MemoryMapIdx[1]
		      %assign dataIdx    = chartData.MemoryMapIdx[2]
		      %if secIdx == -1
			%% Unstructured data
			%assign data        = UnstructuredData.Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
			%assign dataAccess  = data.Access
			%assign isPointer   = dataAccess == "indirect" ? 1 : 0
		      %elseif structIdx == -1
			%% Custom data
			%assign data        =  CustomData[secIdx].Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
			%assign dataAccess  = data.Access
			%assign isPointer   = dataAccess == "indirect" ? 1 : 0
		      %else
			%% Structured data
			%assign section     = ...
			  StructuredData[structIdx].Section[secIdx]
			%assign data        = section.Data[dataIdx]
			%assign dataTypeIdx = section.DataTypeIdx
			%assign isComplex   = section.IsComplex
			%assign isPointer   = TLC_FALSE
			%assign dataAccess  = "direct" 
		      %endif
		      %% Address
		      %assign addrMapIdx     = im.NumDataAddr
		      %if isPointer 
			%assign sigAddress   = data.BaseAddr
			%assign im.AddrMapComments = im.AddrMapComments + ...
			  "%<im.NumDataAddr>: Stateflow Chart Data Pointer"
		      %else
			%assign sigAddress   = data.BaseAddr
			%assign im.AddrMapComments = im.AddrMapComments + ...
			  "%<im.NumDataAddr>: Stateflow Chart Data"
		      %endif
		      %assign im.AddrMap     = im.AddrMap + sigAddress
		      %assign im.NumDataAddr = im.NumDataAddr + 1
		      %% Block Path
		      %assign grBlkIdx = [%<subsysIdx>, %<blkIdx>]
		      %assign blkPath  = SLibMangledGrBlockPath(grBlkIdx) + ...
			"/" + chartData.Path
		      %assign blkPath        = STRING(blkPath)
		      %% Signal Label
		      %assign sigLabel       = chartData.SFName
		      %% Data Type
		      %assign dataTypeMapIdx = ...
			FcnGetDataTypeMapIdx(dataTypeIdx,isComplex,isPointer,im)
		      %% Dimension
		      %assign dimMapIdx      = FcnGetDimensionMapIdx(data,im)
		      %% Fixed Point
		      %if data.IsFixedPoint
			%assign fxpMapIdx    = FcnGetFxpMapIdx(data,im)
		      %else
			%assign fxpMapIdx    = 0
		      %endif
		      %% SampleTime
		      %assign tID        = dwRec.TID
		      %if TYPE(tID) != "Number"
			%if tID == "triggered"
			  %assign tID = -1
			%else
			  %assign errTxt = "Unhandled TID type."
			  %<LibReportError(errTxt)>
			%endif
		      %endif  
		      %assign sTimeIdx = FcnGetSampTimeIdx(tID, 0, im)
		      %assign sysNum = 0
		      %% Write data directly to BlockIOSignal structure
		      {%<addrMapIdx>, %<sysNum>, "%<blkPath>",
		      "%<sigLabel>", 0, %<dataTypeMapIdx>, \
		      %<dimMapIdx>, %<fxpMapIdx>, %<sTimeIdx>},
		      %assign im.NumBIOSignals = im.NumBIOSignals + 1
		      %if IsModelReferenceSimTarget()
			%% Need to pad the loggingInfo to keep the same size
			%assign loggingInfoStartIdx  = loggingInfoStartIdx + 0
			%assign loggingInfoBlockPath = loggingInfoBlockPath + ""
			%assign loggingInfoPortIndex = loggingInfoPortIndex + 0
			%assign loggingInfoSysNum    = loggingInfoSysNum + 0
		      %endif
		    %endforeach
		  %endwith %% ChartData
		%endif %% Block[blkIdx].Type == "Stateflow"
	      %endwith  %% Block[blkIdx]
	    %endforeach  %% blkIdx = NumBlocks
	  %endwith  %% Subsystem[subsysIdx]
	%endforeach  %%  subsysIdx = NumSubsystems
	%undef portobj
	{
	  0, 0, NULL, NULL, 0, 0, 0, 0, 0
	}
        };
      %endif  %% RTWCAPISignals == 1

      %if RTWCAPIParams == 1

	%% Internal testing facility
	%if EXISTS("ParameterTuningTestFile")
	  %include "%<ParameterTuningTestFile>"
	%endif

	%if InlineParameters
	  /* Individual block tuning is not valid when inline parameters is *
	   * selected. An empty map is produced to provide a consistent     *
	   * interface independent  of inlining parameters.                 *
	   */
	%else
	  /* Tunable block parameters */
	%endif

	static %<constKeyword> %<tBlockParamsType> %<tBlockParams>[] = {

	  /* addrMapIndex, blockPath,
	   * paramName, dataTypeIndex, dimIndex, fixPtIdx
	   */

	%if !InlineParameters
	  %% Loop through Parameters and add relevant parameter information
	  %% to BlockParams Structure
	  %foreach subsysIdx = NumSubsystems
	    %with Subsystem[subsysIdx]
	      %foreach blkIdx = NumBlocks
		%with Block[blkIdx]
		  %foreach paramIdx = NumParameters
		    %assign mParam  = Parameter[paramIdx]
		    %if mParam._idx < 0 %% post compile virtual blocks
		      %continue
		    %endif
		    %assign param   = ...
		      CompiledModel.ModelParameters.Parameter[mParam._idx]
		    %if (param.MemoryMapIdx[2] == -1) || (param.Tunable == "no")
		      %% Inaccessible data or non tunable parameter
		      %continue
		    %else
		      %assign structIdx  = param.MemoryMapIdx[0]
		      %assign secIdx     = param.MemoryMapIdx[1]
		      %assign dataIdx    = param.MemoryMapIdx[2]
		      %assign section=StructuredData[structIdx].Section[secIdx]
		      %assign data       = section.Data[dataIdx]
		      %assign dataTypeIdx= section.DataTypeIdx
		      %assign isComplex  = section.IsComplex
		      %assign isReadOnly = data.Permission == "ro"
		      %% Skip certain kinds of data - Read only
		      %if isReadOnly
			%continue
		      %endif
		      %if data.Class == "other"
			%% Skip data of unknown layout
			%continue
		      %endif
		      %% Address
		      %assign addrMapIdx     = im.NumDataAddr
		      %assign im.AddrMap = im.AddrMap + data.BaseAddr
		      %assign im.AddrMapComments = im.AddrMapComments + ...
			"%<im.NumDataAddr>: Block Parameter"
		      %assign im.NumDataAddr = im.NumDataAddr + 1
		      %% Block Path
		      %assign grBlkIdx       = [%<subsysIdx>, %<blkIdx>]
		      %assign blkPath        = SLibMangledGrBlockPath(grBlkIdx)
		      %assign blkPath        = STRING(blkPath)
		      %% Parameter Name
		      %assign paramName      = mParam.Name
		      %% Data Type
		      %assign isPointer      = TLC_FALSE
		      %assign dataTypeMapIdx = ...
			FcnGetDataTypeMapIdx(dataTypeIdx,isComplex,isPointer,im)
		      %% Dimensions
		      %assign dimMapIdx = FcnGetDimensionMapIdx(data, im)
		      %% Fixed point
		      %if data.IsFixedPoint
			%assign fxpMapIdx    = FcnGetFxpMapIdx(data,im)
		      %else
			%assign fxpMapIdx    = 0
		      %endif
		      %% Write data directly to model_capi.c(pp)
		      {%<addrMapIdx>, "%<blkPath>",
		      "%<paramName>", %<dataTypeMapIdx>, %<dimMapIdx>, %<fxpMapIdx>},
		      %assign im.NumBlockParams = im.NumBlockParams + 1
		    %endif
		  %endforeach
		%endwith  %% Block[blkIdx]
	      %endforeach  %% blkIdx = NumBlocks
	    %endwith  %% Subsystem[subsysIdx]
	  %endforeach  %%  subsysIdx = NumSubsystems
	%endif  %% !Inline Parameters
	{
	  0, NULL, NULL, 0, 0, 0
	}
        };
      %endif  %% RTWCAPIParams == 1
    
      %if RTWCAPIStates == 1
	/* Block states information */
	static %<constKeyword> %<tBlockStatesType> %<tBlockStates>[] = {
	  
	  /* addrMapIndex, blockPath,
	  * stateName, dWorkIndex, dataTypeIndex, dimIndex, fixPtIdx, sTimeIndex
	  */
	  
	  %foreach subsysIdx = NumSubsystems
	    %with Subsystem[subsysIdx]
	      %foreach blkIdx = NumBlocks
		%with Block[blkIdx]
		  %if Type == "ModelReference"
		    %assert NumDiscStates == 0
		    %continue
		  %endif
		  %if Block[blkIdx].Virtual != 0
		    %continue
		  %endif
		  %% Block Path
		  %assign grBlkIdx       = [%<subsysIdx>, %<blkIdx>]
		  %assign blkPath        = SLibMangledGrBlockPath(grBlkIdx)
		  %assign blkPath        = STRING(blkPath)
		  %foreach dStateIdx = NumDiscStates
		    %assign dWorkIdx = DiscState[dStateIdx]._idx
		    %if dWorkIdx < 0 %% post compile virtual blocks
		      %continue
		    %endif
		    %assert (dWorkIdx < CompiledModel.DWorks.NumDWorks)
		    %assign dWork    = CompiledModel.DWorks.DWork[dWorkIdx]
		    %if dWork.MemoryMapIdx[2] == -1
		      %% Skip  Local or reuse data
		      %continue
		    %else
		      %assign structIdx  = dWork.MemoryMapIdx[0]
		      %assign secIdx     = dWork.MemoryMapIdx[1]
		      %assign dataIdx    = dWork.MemoryMapIdx[2]
		      %if secIdx == -1
			%% Unstructured data
			%assign data        = UnstructuredData.Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
			%assign dataAccess  = data.Access
			%assign isPointer   = dataAccess == "indirect" ? 1 : 0
		      %elseif structIdx == -1
			%% Custom data
			%assign data       =  CustomData[secIdx].Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
			%assign dataAccess  = data.Access
			%assign isPointer   = dataAccess == "indirect" ? 1 : 0
		      %else
			%% Structured data
			%assign section     = ...
			  StructuredData[structIdx].Section[secIdx]
			%assign data        = section.Data[dataIdx]
			%assign dataTypeIdx = section.DataTypeIdx
			%assign isComplex   = section.IsComplex
			%assign isPointer   = TLC_FALSE
			%assign dataAccess  = "direct"
		      %endif
		    %endif
		    %if data.Class == "other"
		      %% Skip data of unknown layout
		      %continue
		    %endif
		    %if dataAccess == "unknown"
		      %% Skip data if DataAccess is unknown - R13 CSC's
		      %continue
		    %endif
		    %% State Address
		    %assign addrMapIdx     = im.NumDataAddr
		    %if isPointer
		      %assign stateAddress       = data.BaseAddr
		      %assign im.AddrMapComments = im.AddrMapComments + ...
			"%<im.NumDataAddr>: Discrete State Pointer"
		    %else
		      %assign stateAddress       = data.BaseAddr
		      %assign im.AddrMapComments = im.AddrMapComments + ...
			"%<im.NumDataAddr>: Discrete State"
		    %endif
		    %assign im.AddrMap     = im.AddrMap + stateAddress
		    %assign im.NumDataAddr = im.NumDataAddr + 1
		    %% State Name
		    %assign stateName      = dWork.Name
		    %% Data Type
		    %assign dataTypeMapIdx = ...
		      FcnGetDataTypeMapIdx(dataTypeIdx, isComplex, isPointer, im)
		    %% Dimension
		    %assign dimMapIdx      = FcnGetDimensionMapIdx(data,im)
		    %% Fixed Point
		    %if data.IsFixedPoint
		      %assign fxpMapIdx    = FcnGetFxpMapIdx(data,im)
		    %else
		      %assign fxpMapIdx    = 0
		    %endif
		    %% SampleTime
		    %if TYPE(dWork.TID) == "Number"
		      %assign tID        = dWork.TID
		      %assign sTimeIdx = FcnGetSampTimeIdx(tID,0,im)
		    %elseif dWork.TID == "triggered"
		      %assign tID      = -1
		      %assign sTimeIdx = FcnGetSampTimeIdx(tID,0,im)
		    %else
		      %assign errTxt = "Unhandled TID type for States: %<dWork.TID>."
		      %<LibReportError(errTxt)>
		    %endif
		    %% Write data directly to BlockStates structure
		    {%<addrMapIdx>, -1, "%<blkPath>",
		    "%<stateName>", 0, %<dataTypeMapIdx>, %<dimMapIdx>, \
		    %<fxpMapIdx>, %<sTimeIdx>},
		    %assign im.NumBlockStates = im.NumBlockStates + 1
		  %endforeach   %% dStateIdx = NumDiscStates
		  %%
		  %% Continuous States
		  %%
		  %assert (NumContStates == NumDerivatives)
		  %foreach cStateIdx = NumContStates
		    %assign cSIdx = ContState[cStateIdx]._idx
		    %assert (cSIdx < CompiledModel.ContStates.NumContStates)
		    %assign contState = CompiledModel.ContStates.ContState[cSIdx]
		    %if contState.MemoryMapIdx[2] == -1
		      %% Skip  Local or reuse data
		      %continue
		    %else
		      %assign structIdx  = contState.MemoryMapIdx[0]
		      %assign secIdx     = contState.MemoryMapIdx[1]
		      %assign dataIdx    = contState.MemoryMapIdx[2]
		      %if secIdx == -1
			%% Unstructured data
			%assign data        = UnstructuredData.Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
		      %elseif structIdx == -1
			%% Custom data
			%assign data       =  CustomData[secIdx].Data[dataIdx]
			%assign isComplex   = data.IsComplex
			%assign dataTypeIdx = data.DataTypeIdx
		      %else
			%% Structured data
			%assign section     = ...
			  StructuredData[structIdx].Section[secIdx]
			%assign data        = section.Data[dataIdx]
			%assign dataTypeIdx = section.DataTypeIdx
			%assign isComplex   = section.IsComplex
		      %endif
		    %endif
		    %% Address
		    %assign addrMapIdx     = im.NumDataAddr
		    %assign im.AddrMap     = im.AddrMap + data.BaseAddr
		    %assign im.AddrMapComments = im.AddrMapComments + ...
		      "%<im.NumDataAddr>: Continuous State"
		    %assign im.NumDataAddr = im.NumDataAddr + 1
		    %% State Name
		    %assign stateName      = "CSTATE"
		    %% Data Type
		    %assign isPointer      = TLC_FALSE
		    %assign dataTypeMapIdx = ...
		      FcnGetDataTypeMapIdx(dataTypeIdx,isComplex,isPointer,im)
		    %% Dimension
		    %assign dimMapIdx      = FcnGetDimensionMapIdx(data,im)
		    %% Fixed Point
		    %if data.IsFixedPoint
		      %assign fxpMapIdx    = FcnGetFxpMapIdx(data,im)
		    %else
		      %assign fxpMapIdx    = 0
		    %endif
		    %% SampleTime
		    %% %if ISFIELD(Block[blkIdx], "TID")
		    %%   %assign tID = Block[blkIdx].TID
		    %% %else
		    %%   %assign bRef   = Block[blkIdx]._blkref
		    %%   %assign sysBlk = CompiledModel.System[bRef[0]].Block[bRef[2]]
		    %%   %assign tID    = sysBlk.TID
		    %% %endif
		    %assign sTimeIdx = FcnGetSampTimeIdx(0, 0, im)
		    %% Write data directly to BlockStates structure
		    {%<addrMapIdx>, %<contState.StartIndex>, "%<blkPath>",
		    "%<stateName>", 0, %<dataTypeMapIdx>, %<dimMapIdx>, \
		    %<fxpMapIdx>, %<sTimeIdx>},
		    %assign im.NumBlockStates = im.NumBlockStates + 1
		  %endforeach %% cStateIdx = NumContStates
		%endwith
	      %endforeach   %% blkIdx = NumBlocks
	    %endwith   %% Subsystem[subsysIdx]
	  %endforeach    %% subsysIdx = NumSubsystems
	  {
	    0, -1, NULL, NULL, 0, 0, 0, 0
	  }
	};
      %endif  %% RTWCAPIStates = 1
    %endwith  %% BlockHierarchyMap
    %% end of BlockHierarchyMap loop ===========================================

    %if RTWCAPIParams ==1
      %% Tunable Variable Parameters
      %%
      /* Tunable variable parameters */
      
      static %<constKeyword> %<tModelParamsType> %<tModelParams>[] = {
      
	/* addrMapIndex, varName, dataTypeIndex, dimIndex, fixPtIndex */
      
      %with ModelParameters
	%foreach paramIdx = NumModelParameters
	  %assign param = ModelParameter[paramIdx]
	  %foreach instIdx = param.NumInstances
	    %assign constString = ""
	    %assign structIdx = param.Instance[instIdx].MemoryMapIdx[0]
	    %assign secIdx    = param.Instance[instIdx].MemoryMapIdx[1]
	    %assign dataIdx   = param.Instance[instIdx].MemoryMapIdx[2]
	    %if secIdx == -1         %% [-1 -1 dataIdx]
	      %% Unstructured data
	      %assign data        = UnstructuredData.Data[dataIdx]
	      %assign dTypeIdx    = data.DataTypeIdx
	      %assign isComplex   = data.IsComplex
	      %assign dataAccess  = data.Access
	      %assign isPointer   = dataAccess == "indirect" ? 1 : 0
	    %elseif structIdx == -1  %% [-1 secIdx dataIdx]
	      %% Custom data
	      %assign data        = CustomData[secIdx].Data[dataIdx]
	      %assign dTypeIdx    = data.DataTypeIdx
	      %assign isComplex   = data.IsComplex
	      %assign dataAccess  = data.Access
	      %assign isPointer   = dataAccess == "indirect" ? 1 : 0
	      %assign constString = "(void *) "
	    %else                    %% [structIdx secIdx dataIdx]
	      %% Structured data
	      %assign section     = StructuredData[structIdx].Section[secIdx]
	      %assign data        = section.Data[dataIdx]
	      %assign dTypeIdx    = section.DataTypeIdx
	      %assign isComplex   = section.IsComplex
	      %assign isPointer   = TLC_FALSE
	      %assign dataAccess  = "direct"
	    %endif
	    %if data.Class == "other"
	      %% Skip data of unknown layout
	      %continue
	    %endif
	    %if dataAccess == "unknown"
	      %% Skip data if DataAccess is unknown - R13 CSC's
	      %continue
	    %endif
	    %if instIdx == 0
	      %% Model Parameter Address
	      %assign addrMapIdx     = im.NumDataAddr
	      %if isPointer
		%assign paramAddress    = data.BaseAddr
		%assign im.AddrMapComments = im.AddrMapComments + ...
		  "%<im.NumDataAddr>: Model Parameter Pointer"
	      %else
		%assign paramAddress    = constString + data.BaseAddr
		%assign im.AddrMapComments = im.AddrMapComments + ...
		  "%<im.NumDataAddr>: Model Parameter"
	      %endif
	      %assign im.AddrMap     = im.AddrMap + paramAddress
	      %assign im.NumDataAddr = im.NumDataAddr + 1
	      %% Variable Name
	      %assign varName       = param.Name
	      %% Data Type
	      %assign dataTypeMapIdx = ...
		FcnGetDataTypeMapIdx(dTypeIdx, isComplex, isPointer, im)
	      %% Dimension
	      %assign dimMapIdx     = FcnGetDimensionMapIdx(data, im)
	      %% Fixed Point
	      %if data.IsFixedPoint
		%assign fxpMapIdx   = FcnGetFxpMapIdx(data,im)
	      %else
		%assign fxpMapIdx   = 0
	      %endif
	      %assign im.NumVariableParams = im.NumVariableParams + 1
	      {%<addrMapIdx>, "%<varName>", %<dataTypeMapIdx>, %<dimMapIdx>, %<fxpMapIdx>},
	    %endif
	  %endforeach  %% Instance
	%endforeach  %% Parameter
      %endwith  %% Model Parameters
      {0, NULL, 0, 0, 0 }
      };
    %endif   %% RTWCAPIParams
  %endwith %% CompiledModel.GlobalMemoryMap    
  
  %% Keep a count of Data Address. Used to allocate memory in RTModel
  %<LibAddToCompiledModel("NumDataAddrInMap", im.NumDataAddr)>
  %%
  %% AddressMap and Initialize function ====================================
  %%
  
  %assign args = FcnCAPIInitializeFcnArgs()
  
  %if !UsingMalloc
    %if !IsMultiInsatnceERTOrModelReference()
      /* Declare Data Addresses statically */
      %if im.NumDataAddr > 0
	static %<tDataAddrType> %<tDataAddrMap>[] = {
	  %foreach idx = im.NumDataAddr-1
	    %<im.AddrMap[idx]>, \
	  /* %<im.AddrMapComments[idx]> */
	  %endforeach
	  %<im.AddrMap[im.NumDataAddr-1]>\
	/* %<im.AddrMapComments[im.NumDataAddr-1]> */
	};
      %else  %% if im.NumDataAddr <=0
	static %<tDataAddrType> *%<tDataAddrMap> = NULL;
      %endif  %% if im.NumDataAddr
    %else   %% if IsMultiInstanceERTorModelReference()
      %if im.NumDataAddr > 0
	/* Initialize Data Address */
	static void %<prefix>InitializeDataAddr(%<args.dArg>%<args.bArg>%<args.pArg>%<args.dwArg>%<args.xArg>) {
	  %foreach idx = im.NumDataAddr
	    dataAddr[%<idx>] = (void*) (%<im.AddrMap[idx]>);
	  %endforeach
	}
      %endif %% im.NumDataAddr > 0
    %endif %% if IsMultiInstanceERTorModelReference()
  %endif %% !UsingMalloc
  
  %%
  %% DataTypeMap ============================================================
  %%
  /* Data Type Map - use dataTypeMapIndex to access this structure */
  static %<constKeyword> %<tDataTypeMapType> %<tDataTypeMap>[] = {
    
    /* cName, mwName, numElements, elemMapIndex, dataSize, slDataId, *
    * isComplex, isPointer */
    
    %if im.NumDataTypes > 0
      %foreach idx = im.NumDataTypes - 1
	%<im.DataTypeMap[idx]>,
      %endforeach
      %<im.DataTypeMap[im.NumDataTypes-1]>
    %else
      {
	"", "", 0, 0, 0, 0, 0, 0
      }
    %endif
  };
  
  %%
  %% Bus Element Map =========================================================
  %%
  /* Structure Element Map - use elemMapIndex to access this structure */
  static %<constKeyword> %<tElementMapType> %<tElementMap>[] = {
    
    /* elementName, elementOffset, dataTypeIndex, dimIndex, fxpIndex */
    
    {NULL, 0, 0, 0, 0},
    %if im.NumElements > 1
      %foreach idx = im.NumElements - 2
	%<im.ElemMap[idx]>,
      %endforeach
      %<im.ElemMap[im.NumElements-2]>
    %endif
  };
  
  %%
  %% DimensionMap ==========================================================
  %%
  /* Dimension Map - use dimensionMapIndex to access elements of ths structure*/
  static %<constKeyword> %<tDimensionMapType> %<tDimensionMap>[] = {
    
    /* dataOrientation, dimArrayIndex, numDims*/
    
    %if im.NumDimensionMaps > 0
      %foreach idx = im.NumDimensionMaps - 1
	%<im.DimensionMap[idx]>,
      %endforeach
      %<im.DimensionMap[im.NumDimensionMaps-1]>
    %else
      {
	rtwCAPI_SCALAR, 0, 0
      }
    %endif
  };
  
  %%
  %% DimensionArray ========================================================
  %%
  /* Dimension Array- use dimArrayIndex to access elements of this array */
  %if  im.NumDimArray > 0
    static %<constKeyword> %<tDimensionArrayType> %<tDimensionArray>[] = {
      %foreach idx = im.NumDimArray - 1
	%<im.DimArray[idx]>,\
	/* %<im.DimArrayComments[idx]> */
      %endforeach
      %<im.DimArray[im.NumDimArray-1]> \
      /* %<im.DimArrayComments[im.NumDimArray-1]> */
    };
  %else
    static %<constKeyword> %<tDimensionArrayType> %<tDimensionArray>[] = {0};
  %endif
  
  %%
  %% Double Values ========================================================
  %%
  /* C-API stores floating point values in an array. The elements of this  *
  * are unique. This ensures that values which are shared across the model*
  * are stored in the most efficient way. These values are referenced by  *
  *           - %<tFixPtMapType>.fracSlopePtr,                            *
  *           - %<tFixPtMapType>.biasPtr,                                 *
  *           - %<tSampleTimeMapType>.samplePeriodPtr,                    * 
  *           - %<tSampleTimeMapType>.sampleOffsetPtr                     */
  
  static const real_T rtcapiStoredFloats[] = {
    %if im.NumDoubles > 0
      %foreach idx = im.NumDoubles - 1
	%<im.DoublesMap[idx]>,\
      %endforeach
      %<im.DoublesMap[im.NumDoubles-1]>
    %else
      0.0
    %endif
  };
  
  %%
  %% Fixed Point Map =======================================================
  %%
  /* Fixed Point Map */
  static %<constKeyword> %<tFixPtMapType> %<tFixPtMap>[] = {
    
    /* fracSlopePtr, biasPtr, scaleType, wordLength, exponent, isSigned */
    
    {NULL, NULL, rtwCAPI_FIX_RESERVED, 0, 0, 0 },
    %if im.NumFixPoint > 1
      %foreach idx = im.NumFixPoint - 2
	%<im.FixPointMap[idx]>,
      %endforeach
      %<im.FixPointMap[im.NumFixPoint-2]>
    %endif
  };
  
  %%
  %% Sample Time Map =====================================================
  %%
  /* Sample Time Map - use sampTimeIndex to access elements of ths structure */
  static %<constKeyword> %<tSampleTimeMapType> %<tSampleTimeMap>[] = {
    
    /* samplePeriodPtr, sampleOffsetPtr, tid, samplingMode */
    
    %if im.NumSampleTimes > 0
      %foreach idx = im.NumSampleTimes - 1
	%<im.SampleTimeMap[idx]>,
      %endforeach
      %<im.SampleTimeMap[im.NumSampleTimes - 1]>
    %else
      {
	NULL, NULL, %<CompiledModel.SampleTime[0].TID>, 0
      }
    %endif
  };
  
  %if RTWCAPISignals
    %assign tempBIOSig    = tBlockSignals
    %assign tempNumBIOSig = im.NumBIOSignals
  %else
    %assign tempBIOSig    = "NULL"
    %assign tempNumBIOSig = 0
  %endif
  %if RTWCAPIParams
    %assign tempBTuning    = tBlockParams
    %assign tempVTuning    = tModelParams
    %assign tempNumBTuning = im.NumBlockParams
    %assign tempNumVTuning = im.NumVariableParams
  %else
    %assign tempBTuning    = "NULL"
    %assign tempVTuning    = "NULL"
    %assign tempNumBTuning = 0
    %assign tempNumVTuning = 0
  %endif
    %if RTWCAPIStates
      %assign tempBStates    = tBlockStates
      %assign tempNumBStates = im.NumBlockStates
    %else
      %assign tempBStates    = "NULL"
      %assign tempNumBStates = 0
    %endif
    %if IsModelReferenceSimTarget()
      %assign tempStaticInfoLogging = "&mmiStaticInfoLogging"
    %else  
      %assign tempStaticInfoLogging = "NULL"
    %endif
    
    %% Define the number of systems
    %assign sysRanDWorkLen  = SIZE(SubsystemRanBC.SysRanDWork, 1)
    %assign tContextSystems = "rtContextSystems"
  %assign loggingInfoLen  = SIZE(loggingInfoStartIdx, 1)
    %%
    %% The following are ModelReference logging specific
    %%
    %if IsModelReferenceSimTarget()
      /* The context systems array */
      static int_T %<tContextSystems>[%<sysRanDWorkLen>];
      
      /* Logging Meta info */
      static rtwCAPI_LoggingMetaInfo loggingMetaInfo[] = {
	%if loggingInfoLen > 0
	  %foreach idx=loggingInfoLen-1
	    {%<idx>, %<loggingInfoStartIdx[idx]>, "%<loggingInfoBlockPath[idx]>",...
	      %<loggingInfoPortIndex[idx]>, %<loggingInfoSysNum[idx]>},
	  %endforeach
	  %assign idx = loggingInfoLen-1
	  {%<idx>, %<loggingInfoStartIdx[idx]>, "%<loggingInfoBlockPath[idx]>",...
	    %<loggingInfoPortIndex[idx]>, %<loggingInfoSysNum[idx]>}
	%else
	  {0, 0, "", 0}
	%endif
      };
    
      /*
      * ModelMapLoggingStaticInfo: 
      *   {numSystems, contextSystems}
      */
      static rtwCAPI_ModelMapLoggingStaticInfo mmiStaticInfoLogging = {
      %<sysRanDWorkLen>, %<tContextSystems>, loggingMetaInfo
      };
    %endif
    
    static rtwCAPI_ModelMappingStaticInfo mmiStatic = { 
    
    /* Signals:{signals, numSignals}, 
     * Params: {blockParameters, numBlockParameters, 
     *          modelParameters, numModelParameters},
     * States: {states, numStates},
     * Maps:   {dataTypeMap, dimensionMap, fixPtMap, 
     *          elementMap, sampleTimeMap, dimensionArray},
     * TargetType: targetType
     */
    
    {%<tempBIOSig>, %<tempNumBIOSig>},
    {%<tempBTuning>, %<tempNumBTuning>, 
    %<tempVTuning>, %<tempNumVTuning>},
    {%<tempBStates>, %<tempNumBStates>},
    {%<tDataTypeMap>, %<tDimensionMap>, %<tFixPtMap>, 
    %<tElementMap>, %<tSampleTimeMap>, %<tDimensionArray>},
    "float", %<tempStaticInfoLogging>
    };

    
    %%
    %% System arrays ========================================================
    %%
    %% Consider the following model:
    %%    
    %%  /------------------------------------------------------\
    %%  |                                                      |
    %%  |   ___________       ___________       ____________   |
    %%  |   |         |       |         |       |          |   |
    %%  |   | Enable1 |       | Enable2 |       |  Model2  |   |
    %%  |   |_________|       |_________|       |__________|   |
    %%  |                                                      |
    %%  \------------------------------------------------------/
    %%
    %%  Where:
    %%  Enable1 : in ---> gain ---> out
    %%  Enable2 : another model block (Model1) with (in ----> gain -----> out)
    %%  Model2  : contains a copy of Enable1 (call it Enable3)
    %%
    %%  Each Model Reference code (in the MMI) will generate arrays that are 
    %%  local to itself.  The root slot is always initialized by the parent 
    %%  at run time but all systems slots are generated.
    %%  
    %%  Hence, Model1 contains only two systems, root and tempModelReference
    %%  i.e the arrays will look as follows
    %%
    %%   <all tid numbers are arbitrary below>
    %%
    %%    system number    0          1
    %%    sysRanPtr   : [ sysRanPtr  NULL ]  sysRanPtr and rootTid are passed
    %%    sysRanTid   : [ rootTid     2   ]  the initilize function of parent
    %%    contextSys  : [   0         0   ]
    %%
    %%  Model2 contains another system that is the enabled subsystem, Enable3
    %%
    %%    system number    0          1          2
    %%    sysRanPtr   : [ sysRanPtr  NULL     dworkPtr ]
    %%    sysRanTid   : [ rootTid     2          4     ]
    %%    contextSys  : [   0         0          2     ]
    %%
    %%  'dworkPtr' is a pointer to the sysRanBC dwork entry that is generated 
    %%  for Model2 and corresponds to the conditiionally executed system 
    %%  Enable3.  Note that its contextSys number is itself 2.  If there was 
    %%  another atomic system inside Enable3, it would get a unique system 
    %%  number but its contextSys number would be 2.
    %%
    %assign sysRanDWork = SubsystemRanBC.SysRanDWork
    %assign baseIdx     = GetBaseSystemIdx()
    
    %if sysRanDWorkLen > 0 && IsModelReferenceSimTarget()
      %assign systemRan = "sysRanDType *systemRan[]"
      %assign systemTid = "int_T systemTid[]"
    
      /* Initialize the system ran breadcrumbs */
      static void %<prefix>InitializeSystemRan(%<systemRan>%<args.dwArg>,
	%<systemTid>, void *rootSysRanPtr, int rootTid) {  
      
      %% systemRan
      %foreach i = sysRanDWorkLen
	%assign  dwIdx = sysRanDWork[i]
	%if (dwIdx > -1)
	  %assign dwRec = CompiledModel.DWorks.DWork[dwIdx]
	  %with System[baseIdx]
	    %assign sysDWork = SLibGetSysRanBCDWork(dwIdx)
	  %endwith
	  %assert (dwRec.Name == "SubsysRanBC")
	  %assign  sigAddr = "&"+ sysDWork
	  systemRan[%<i>] = (sysRanDType *)%<sigAddr>;
	%else
	  %if i==0
	   systemRan[%<i>] = (sysRanDType *) rootSysRanPtr;
	  %else
	    systemRan[%<i>] = NULL;
	  %endif	  
	%endif
      %endforeach
      
      %% systemTid
      %foreach i = CompiledModel.NumSystems
	%with System[i]
	  %if Type == "root"
	    systemTid[0] = rootTid; %% rootTid is an argument to this fcn
	  %else
	    %assign numDescSys = SIZE(DescSysIdx, 1)
	    %foreach j = numDescSys
	      %assign descIdx = DescSysIdx[j]
	      %assign sysTid  = DescSysNonTrigTID[j]
	      %assert (sysTid != -1) %% tid should never be triggered
	      %if sysTid >= 0
		%if MdlRefDisallowSampleTimeInheritance()
		  systemTid[%<descIdx>] = %<FcnGetMdlRefGlobalTIDMap()>[%<sysTid>];
		%else 
		  systemTid[%<descIdx>] = rootTid;
		%endif
	      %else
		%% Fill in constant for constant_tid
		%assert (sysTid == -2)
		systemTid[%<descIdx>] = -2;
	      %endif
	    %endforeach
	  %endif
	%endwith
      %endforeach
      
      %% contextSystem
      %assign contextSysVector = CompiledModel.SubsystemRanBC.ContextSysIdx
      %assign sizeVect         = SIZE(contextSysVector, 1)
      
      %foreach j = sizeVect
	%assign idx = contextSysVector[j]
	%<tContextSystems>[%<j>] = %<idx>;
      %endforeach
    }
  %endif
  
  %% Cache InitializeDataMapInfo Definition
  /* Cache pointers into DataMapInfo substructure of RTModel */
  %if IsModelReferenceSimTarget()
    void %<CompiledModel.Name>_InitializeDataMapInfo(%<tSimStructType> *%<RTMGetModelSS()>
      %<args.bArg>%<args.pArg>%<args.dwArg>%<args.xArg>, void *sysRanPtr, int contextTid) {
  %else
    void %<CompiledModel.Name>_InitializeDataMapInfo(%<tSimStructType> *%<RTMGetModelSS()>
      %<args.bArg>%<args.pArg>%<args.dwArg>%<args.xArg>) {
  %endif       
      
  %assign capiStructId =""
  %%
  %%Top Level RSIM executable is the only known target that
  %%does not set the GenRTModel variable. RTM special access   
  %%functions cannot be used. Instead a text replacement is made  
  
  %if GenRTModel
    %assign capiStructId = RTMGet("DataMapInfo")
  %else 
    %assert isRSim && !IsModelReferenceTarget()
    %assign capiStructId = "(*%<RSimRTWCAPIVarPtr>)"
  %endif  
  
  %if UsingMalloc || CodeFormat == "S-Function"
    /* run-time setup of addresses */
    %assign nParams   = im.NumBlockParams+im.NumVariableParams
    %assign nDataAddr = im.NumDataAddr
    %assign dAddrType = tDataAddrType
    %assign localStr  = CodeFormat == "S-Function" ? "Local" : ""
    %if (nParams) > 0
      %<tParametersType> *%<tParameters> = (%<tParametersType> *) %<RTMGet("%<localStr>DefaultParam")>;
    %endif
    %if im.NumBIOSignals > 0
      %<tBlockIOType> *%<tBlockIO> = (%<tBlockIOType> *) %<RTMGet("%<localStr>BlockIO")>;
    %endif
    %if (nDataAddr > 0)
      %if UsingMalloc
	%<dAddrType> *%<tDataAddrMap>;
	%<tDataAddrMap> = (%<dAddrType>*) malloc(%<nDataAddr> * sizeof(%<dAddrType>));
      %else
	static %<dAddrType> %<tDataAddrMap>[%<nDataAddr>];
      %endif
      
      if((%<tDataAddrMap>) == NULL) {
	%<RTMSetErrStat("RT_MEMORY_ALLOCATION_ERROR")>;
	return;
      }
      
      %foreach idx = nDataAddr
	%<tDataAddrMap>[%<idx>] = %<im.AddrMap[idx]>; 
      %endforeach
    %else
      static %<tDataAddrType> *%<tDataAddrMap> = NULL;
    %endif
  %endif
    
  /* Set C-API version */
  rtwCAPI_SetVersion(%<capiStructId>.mmi, 1);
  
  /* Cache static C-API data into the Real-time Model Data structure */
  rtwCAPI_SetStaticMap(%<capiStructId>.mmi, &mmiStatic);
  
  /* Cache static C-API logging data into the Real-time Model Data structure */
  rtwCAPI_SetLoggingStaticMap(%<capiStructId>.mmi, %<tempStaticInfoLogging>);
  
  /* Cache C-API Data Addresses into the Real-Time Model Data structure */
  %if !IsMultiInsatnceERTOrModelReference()
    rtwCAPI_SetDataAddressMap(%<capiStructId>.mmi, %<tDataAddrMap>);
  %else
    %if im.NumDataAddr > 0
      %<prefix>InitializeDataAddr(%<args.dDecl>%<args.bDecl>%<args.pDecl>%<args.dwDecl>%<args.xDecl>);
      rtwCAPI_SetDataAddressMap(%<capiStructId>.mmi, %<capiStructId>.dataAddress);
    %endif
       
    /* Set Instance specific path */
    rtwCAPI_SetPath(%<capiStructId>.mmi, NULL);
    rtwCAPI_SetFullPath(%<capiStructId>.mmi, NULL);
  %endif
  
  /* Cache the instance C-API logging pointer */
  %if IsModelReferenceSimTarget()
    rtwCAPI_SetInstanceLoggingInfo(%<capiStructId>.mmi, &%<capiStructId>.mmiLogInstanceInfo);
  %else
    rtwCAPI_SetInstanceLoggingInfo(%<capiStructId>.mmi, NULL);
  %endif
  
  /* Set Reference to submodels */
  %if EXISTS(CompiledModel.ModelReferenceBlocks)
    %assign mdlRefBlks    = CompiledModel.ModelReferenceBlocks
    %assign nMdlRefBlks   = SIZE(mdlRefBlks,0)
    rtwCAPI_SetChildMMIArray(%<capiStructId>.mmi, %<capiStructId>.childMMI);
    rtwCAPI_SetChildMMIArrayLen(%<capiStructId>.mmi, %<nMdlRefBlks>);
  %else
    rtwCAPI_SetChildMMIArray(%<capiStructId>.mmi, NULL);
    rtwCAPI_SetChildMMIArrayLen(%<capiStructId>.mmi, 0);
    %if !ISEMPTY(args.dwDecl)
      %% for now suppress compiler warning if dw is not used.
      %if IsModelReferenceTarget()
	(void)localDW;
      %else
	   (void)%<tDWork>;
      %endif
    %endif
  %endif
  
  %if sysRanDWorkLen > 0 && IsModelReferenceSimTarget()
    %<prefix>InitializeSystemRan(%<capiStructId>.systemRan%<args.dwDecl>,
      %<capiStructId>.systemTid, sysRanPtr, contextTid);
    rtwCAPI_SetSystemRan(%<capiStructId>.mmi,%<capiStructId>.systemRan);
    rtwCAPI_SetSystemTid(%<capiStructId>.mmi,%<capiStructId>.systemTid);
  %endif
  
  %% The ModelReference target uses the global timing engine 
  %if IsModelReferenceSimTarget()
    rtwCAPI_SetGlobalTIDMap(%<capiStructId>.mmi, &%<FcnGetMdlRefGlobalTIDMap()>[0]);
  %endif
  }
  %return ""
%endfunction %% FcnWriteCAPIStructures

%% Function FcnCAPIInitializeArgs ===========================================
%% Abstract:
%%   Return arguments to be used in the following functions
%%      o _InitializeDataMapInfo
%%      o _InitializeDataAddressMap 
%function FcnCAPIInitializeFcnArgs() void
  
  %createrecord       \
  CAPI_FunctionArgs { \
           dArg   ""; \
           dDecl  ""; \
	   pArg   ""; \
	   pDecl  ""; \
	   bArg   ""; \
	   bDecl  ""; \
	   dwArg  ""; \
	   dwDecl ""; \
	   xArg   ""; \
	   xDecl  ""  \
	 }
  %assign args = CAPI_FunctionArgs	 
  
  %if !UsingMalloc
    
    %if IsMultiInsatnceERTOrModelReference()
      %assign args.dArg    = "void* dataAddr[]"
      %assign args.dDecl   = "%<RTMGet("DataMapInfo")>.dataAddress"
      %assign reqInsts = LibGetSystemField(rootSystem,"ReqRootPrmHdrDataInsts")
      
      %if RTWCAPIParams == 1
	%if !reqInsts.ParamsInst && ...
	  !SLibPrmBufferIsEmpty("SimulinkGlobal","Instance")
	  %assign args.pArg = ", %<tParametersType> *%<tParameters>"
	  %assign args.pDecl = ", %<tParameters>"
	%endif
      %endif %% Parameters
      
      %if RTWCAPISignals == 1
	%if !reqInsts.BlockIOInst && !LibBlockIOInstanceIsEmpty()
	  %if IsModelReferenceTarget()
	    %assign baseSysIdx = GetBaseSystemIdx()
	    %assign dataType = "rtB%<FcnGetSystemIdentifier(baseSysIdx)> "
	    %assign args.bArg = ", %<dataType> *localB"
	    %assign args.bDecl = ", localB"
	  %else
	    %assign args.bArg = ", %<tBlockIOType> *%<tBlockIO>"
	    %assign args.bDecl = ", %<tBlockIO>"
	  %endif
	%endif
      %endif  %% BlockIO
      
      %% We need this for Stateflow data
      %if !reqInsts.DworkInst && !LibDWorkInstanceIsEmpty()
	%if IsModelReferenceTarget()
	  %assign baseSysIdx = GetBaseSystemIdx()
	  %assign dataType = "rtDW%<FcnGetSystemIdentifier(baseSysIdx)> "
	  %assign args.dwArg = ", %<dataType> *localDW"
	  %assign args.dwDecl = ", localDW"
	%else
	  %assign args.dwArg = ", %<tDWorkType> *%<tDWork>"
	  %assign args.dwDecl = ", %<tDWork>"
	%endif
      %endif %% DWork 
      
      %if RTWCAPIStates == 1
	%if !reqInsts.DworkInst && !LibDWorkInstanceIsEmpty()
	  %if IsModelReferenceTarget()
	    %assign baseSysIdx = GetBaseSystemIdx()
	    %assign dataType = "rtDW%<FcnGetSystemIdentifier(baseSysIdx)> "
	    %assign args.dwArg = ", %<dataType> *localDW"
	    %assign args.dwDecl = ", localDW"
	  %else
	    %assign args.dwArg = ", %<tDWorkType> *%<tDWork>"
	    %assign args.dwDecl = ", %<tDWork>"
	  %endif
	%endif %% Discrete States
	%if !reqInsts.ContStatesInst && !LibContStatesInstanceIsEmpty()
	  %if IsModelReferenceTarget()
	    %assign baseSysIdx = GetBaseSystemIdx()
	    %assign dataType   = "rtX%<FcnGetSystemIdentifier(baseSysIdx)> "
	    %assign args.xArg       = ", %<dataType> *localX"
	    %assign args.xDecl      = ", localX"
	  %else
	    %assign args.xArg  = ", %<tContStateType> *%<tContState>"
	    %assign args.xDecl = ", %<tContState>"
	  %endif
	%endif
      %endif  %% Continuous States
    
    %endif %% if IsMultiInstanceERTorModelReference()
  
  %endif %% !UsingMalloc
  
  %return args
%endfunction
%%
%endif   %% _CAPI_

%% EOF capi.tlc ===============================================================
