![]() |
![]() |
![]() |
![]() |
![]() |
Output of Code Generation
This section gives an overview of the code generated by the Cmicro SDL to C Compiler. This is useful, to make it possible to interpret the generated code. To know how the code is generated makes it quite easy to understand the program which is necessary and useful when testing and debugging erroneous executable programs.
Not all the intricate details of the generated code are described here. The depth of description is sufficient to give the reader a reasonable understanding of the code generation algorithms. Explanations will illustrate what the code looks like, but not why.
The generated code contains several places where prefixes are generated, which consists of a prefix and unique numbering. The following prefix is generated for all objects: "z<nnn>_", where nnn is an incremental number.
Allowance for conditional compilation occurs in several places throughout the generated code. The generated C code is conditionally compiled, for example, for dynamic process creation (create symbol). A differentiation is made between conditional compilations generated by the Cmicro SDL to C Compiler (called automatic scaling, prefix XMK_USED_) and conditional compilations which are dependent on header files, which are to be modified by the user (called manual scaling, prefix XMK_USE_).
Generally speaking, the ordering of the following subsections corresponds to the ordering in which the code is generated.
Each compilation unit is compiled either in one a.c file or into two files, a.c and a.h.
Only the differences are shown, when comparing the output of SDL to C Compiler with the Cmicro SDL to C Compiler. The overall differences of the both code generators are described in the section Differences between Cmicro and Cadvanced.
Header of Generated C File
Code generation on the .c file for the current unit is started by generating the following header:
Example 584 : The Head of a Generated C File
/* Program generated by the SDL Suite.Cmicro, version x.y */#define XSCT_CMICRO#define C_MICRO_x_y#define XMK_C_TIME <GenerationTime>#include "ml_typ.h"The XSCT_CMICRO macro can be used by the user to distinguish between the different Code generators, for example within ADT bodies.
The C_MICRO_x_y macro can be used by the user to distinguish between different versions of the Cmicro SDL to C Compiler. This is usually not but might become necessary if the output of the Cmicro SDL to C Compiler is different.
The XMK_C_TIME macro is used internally when compiling and linking and executing with the SDL Target Tester takes place. With this macro, a rough consistency check for the generated files is done. The <GenerationTime> of the different files that are generated is compared in the Library and by the SDL Target Tester. If there is an inconsistency, compilation errors will occur.
The #include "ml_typ.h" is used to include all necessary declarations that the generated C code may use, including automatic scaling from sdl_cfg.h and predefined sorts.
SECTION Types and Forward References
As a difference to SDL to C compiler, this section contains the definitions for the process IDs and the forward declarations used in the generated C code.
Process IDs are generated as #define values in C, like:
#define XPTID_<UniquePrefix>_MyProcess 0where the first process in the system is the value of 0 assigned, the second process gets the value 1, and so on. Please refer to Generation of Identifiers for more information.
The following forward references are generated:
extern XCONST XPDTBL yPDTBL_<UniquePrefix>_MyProcess;Following this, the usual declarations are generated as described in The Cadvanced/Cbasic SDL to C Compiler.
No synonym variables are generated when using Cmicro.
Symbol Tables
Symbol tables are only generated for the SDL Target Tester, and not into the generated C code. The symbol tables generated for the SDL Target Tester are described within The SDL Target Tester.
Tables for Processes
Tables are used to represent the behavior of SDL objects, like processes and timers. It is not absolutely necessary to understand how these tables are generated and how the Cmicro Kernel works with them. The following subsections are only for those readers interested in the nature of the table structure.
Root Process Table
The root process table contains, for each of the defined SDL process types, a reference (i.e. a pointer) to the Process Description Table. The Cmicro Kernel is the main user of the root process table. Via this table, it can access all SDL process types and all SDL process instance data. The location of the generated root process table is directly before the yPAD-functions in the generated C file. The type definitions used in this table are located in the ml_typ.h module.
Example 585 : Code of Root Process Table
C-Type definition (ml_typ.h) :
extern xPDTBL yPDTBL [];/* for the Cmicro Kernel */#define X_END_ROOT_TABLE/* Table-End Marker of yPDTBL*/#define MAX_SDL_PROCESS_TYPES <N>/* <Process-type-id´s> Process Types are numbered *//* from 0 to N-1(see chapter "Generating PID") */#define XPTID_Process1Name 0#define XPTID_Process2Name 1#define XPTID_ProcessnName N-1C code generation for the whole system:
XPDTBL yPDTBL [MAX_SDL_PROCESS_TYPES+1] ={yPDTBL_ Process1Name,yPDTBL_ Process2Name,......yPDTBL_ ProcessnName,X_END_ROOT_TABLE}Symbol Trace Table
In order to reduce the use of dynamic memory allocation, there is a table generated in the code which is used by the SDL Target Tester to store and retrieve test options, like switches, which define the trace.
The table is conditionally compiled and only included if the SDL Target Tester is contained in the target- executable.
The symbol trace table looks like:
Example 586 : Code for Symbol Trace Table
/*************************************************************** Symbol trace table*************************************************************/#ifdef XMK_ADD_TEST_OPTIONSXSYMTRACETBL *xSYMTRACETBL[MAX_SDL_PROCESS_TYPES+1] ={(XSYMTRACETBL_ENTRY *) NULL, /* for first Processtype */(XSYMTRACETBL_ENTRY *) NULL, /* for second Processtype */................(XSYMTRACETBL_ENTRY *) NULL, /* for last Processtype */X_END_SYMTRACE_TABLE /* table end marker */};#endifMore information can be obtained by reading The SDL Target Tester.
Optimized Decision Trace information
An option to reduce the trace information for SDL decisions by showing only the first ten characters of the decision expression during trace. Setting the environment variable CMICRO_SHORT_DECISION_TRACE to any value prior to the Cmicro code generation is started, will have the effect on the generated C code that all xTraceDecision<parameter> statements will contain a parameter that is the first ten characters of the decision expression instead of the complete expression. This will reduce the trace information for systems that contain a lot of decisions.
Instance-Data-Struct
The struct is generated in the header-section of the generated C file.
Example 587 : Code Generation of type definition for each SDL process
typedef struct {PROCESS_VARSTypeName1 FPAR_var1;TypeName2 FPAR_var1;TypeName3 DCL_var1;TypeName4 DCL_var2;TypeName4 yExp_DCL_var2;TypeName5 FPAR_var1;} yVDef_ProcessName;Instances of a given type are represented as a C array. The code generation of variables for each SDL process looks like:
#define X_MAX_INST_ProcessName upperlimitofprocessinstances1static yVDef_ ProcessName
yINSTD_ProcessName[X_MAX_INST_ProcessName];A reference to this array is generated in the Process Description Table which is discussed in the subsection Process Description Table.
Process State Table
This table is generated for each process in the header-section of the generated C file. It contains information about the state of each process instance. The table contains ordinary SDL state values as well as the values XSTARTUP and XDORMANT. XSTARTUP is generated for each instance which is to be statically created (in (x, N) declarations, where x is > 0), XDORMANT is the value which is used to tag a process instance as sleeping. In the case of creation this instance can be reused.
Example 589 : Code for Process State Table
C typedef for the process state table (located in ml_typ.h):
typedef u_char xSTATE; /* see defines below */#define XSTARTUP 0xff /* valid only if xSTATE is *//* u_char else 0xffff */#define XDORMANT 0xfe /* valid only if xSTATE is *//* u_char, else 0xfffe */C code generation for each process:
static xSTATE yPSTATETBL_znn_ProcessName [X_MAX_INST_znn_ProcessName] ={<creation-tag> /* Instance 0 */<creation-tag> /* Instance 1 */<creation-tag> /* Instance M-1 */};where <creation-tag> is either XSTARTUP or XDORMANT.
Code for a process type with 4 instances, 2 of which are to be created at SDL system start:
static xSTATE yPSTATETBL_znn_ProcessName [4] ={XSTARTUP, /* Create at SDL-system-start */XSTARTUP, /* Create at SDL-system-start */XDORMANT, /* Create later */XDORMANT /* Create later */};A reference to this table is created in the Process Description Table, which is discussed in the subsection Process Description Table.
Transition Table
This is generated in the header-section of the generated C file. It contains all transitions of a process, including asterisk states, asterisk inputs and asterisk save.
The C typedef for the transition table (located in ml_typ.h) is as follows:
Example 591 : Code for Transition Table
typedef struct {xINPUT SignalID; /* Input, Asterisk-Input. *//* Input is Timer *//* and/or ordinary Signal */xSYMBOLNR SymbolNr; /* Symbolnumber to be used *//* in yPAD-function */} xTR_TABLE_ENTRY;static XCONST xTR_TABLE_ENTRY yTRTBL_znn_ProcessName [XMAX_TRANS_znn_ProcessName]= {/* state_0-table */input_1, SymbolNr,input_2, SymbolNr,XASTERISK,XSAVEID /* asterisk save */input_N, SymbolNr,/* state_1-table */............................../* state_j-table */input_1, SymbolNr,input_2, SymbolNr,input_N, trans_jN,XASTERISK,XSAVEID /* asterisk save */};The SymbolNr shown above is used to select the right transition in the switch generated in the yPAD function.
XASTERISK is an ID defining all possible SDL Inputs (asterisk Inputs),
XSAVEID is a simple ID defined in ml_typ.h which can be compared by the SDL Kernel to detect signal-save.
#define XASTERISK -1#define XSAVEID xSaveA reference to this table is created in the Process Description Table.
State Index Table
This is generated in the header section of the generated C file.
Example 592 : Code for State Index Table
typedef u_char xSTATE_INDEX;C code generation (header of generated C file):
static xCONST xSITBL xSTATE_INDEX_znn_ProcessName [<count_transitions_of_ProcessName] ={0, /* i.e.a process with 3 states, but no asterisk states *//* state_0 has 2 transitions */2, /* state_1 has 5 transitions */7, /* state_2 has 3 transitions */10 /* table-end-index XI_TABLE_END */};The first value in the above table indicates the beginning of the first state in the Transition Table. If asterisk state definitions are not found in the process, this value is 0.
A reference to this table is created in the Process Description Table.
PID Table
These tables are used to store the values parent and offspring for each process. The reason an extra table is used to store this information is to simplify initialization. The Cmicro Kernel updates the values in the table according to the SDL rules.
Example 593 : Code for PID Table
#ifdef XMK_USE_PID_ADDRESSINGtypedef struct{#ifdef XMK_USE_SDL_PARENTxPID Parent;#endif#ifdef XMK_USE_SDL_OFFSPRINGxPID Offspring;#endif} xPIDTable;#endifC code generation for each process:
/*-----------Process-PID-Values-------------*/#ifdef XMK_USE_PID_ADDRESSINGstatic xPIDTable yPID_TBL_z00_P1[X_MAX_INST_z00_P1];#endifA reference to this table is created in the Process Description Table, which is discussed in the subsection Process Description Table.
Process Description Table
For each SDL process, an automatically initialized C structure is generated called process description table. This table is used in the Root Process Table to enable the Cmicro Kernel to access process type information as well as process instance data.
Inspect the following diagram to see which information is contained in the process description table:
Allocated to each SDL process type is one table yPDTBL_ProcessName.
The type definitions of this table are located in the ml_typ.h module.
Example 594 : Code for Process Description Table
C typedef for the process description table (ml_typ.h):
typedef struct {#ifdef XMK_USE_PID_ADDRESSINGxPIDTable *pPIDTable; /* Table with *//* Parent/OffspringValues */#endifxINSTD *pInstanceData ; /* Pointer to Instancedata*//* Vector */xINSTDLEN DataLength ; /* Length of Instancedata *//* for 1 Instance *//* (used by SDL-BS) */unsigned char MaxInstances ; /* Max.Number of Instances*/#ifdef XMK_USE_TIMESLICE/* Time-Slices can be individually specified by the user*//* The value stored in TimeSlice is measured in ticks *//* The Cmicro Kernel has to be scaled to handle *//* timeslicing */xmk_T_TIMESLICE TimeSlice;#endif#ifdef XMK_USE_PREEMPTIVE/* Process-Priority can be specified with #PRIO on the *//* SDL-Level. It is available only, if the Cmicro *//* Kernel is scaled to handle preemption. */xmk_T_PRIOLEVEL PrioLevel;/*Priority of this processtype*/#endifxmk_T_TRANS_ADDRESS yPAD_Function ; /* Address of the *//* yPADFunction */xTRTBL TransitionTable ; /* Pointer to transition table */xSITBL *StateIndexTable ; /* Pointer to state index table */xSTATE *ProcessStateTable;/* Pointer to process state table */} XPDTBL;C code generation for each process:
#define X_MAX_INST_ProcessName 1xPDTBL yPDTBL_ProcessName ={yPID_TBL_znn_<process:N>,
(xINSTD*) yINSTD_znn_ProcessName,X_MAX_INST_znn_ProcessName,(xmk_T_TRANS_ADDRESS) yPAD_znn_ProcessName,yTRTBL_znn_ProcessName;xSTATE_INDEX_znn_ProcessName,yPSTATETBL_znn_ProcessName;};For each generated process description table, a new entry in the Root Process Table is generated.
Actions by Processes and Procedures
GR References
No code is generated to evaluate the graphical references during run-time of the SDL system. A large amount of memory is required to store and handle such information which normally proves too large for any real target system.
Alternatively, C comments are generated which make it possible to verify and debug the generated code as illustrated in the following example. The PR <position> indicates in which line number of the SDL/PR file the symbol can be found.
For processes :/*************************************************************** PROCESS <process-name>** <<SYSTEM <system-name>/BLOCK <block-name>>** #SDTREF(<reference>)*************************************************************/For signals :/*************************************************************** SIGNAL S1** <<SYSTEM <system-name>/BLOCK <block-name>>** #SDTREF(<reference>)*************************************************************/For yPAD-function/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++** Function for process <process-name>** #SDTREF(<reference>)++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/For output :/*-----** OUTPUT <signal-name>** #SDTREF(<reference>)------*/For nextstate :/*-----** NEXTSTATE <state-name>** #SDTREF(<reference>)------*/Structure of Process and Procedure Functions
The basic structure of the generated C code for process and procedure definitions remains the same as for the SDL to C compiler although some modifications are evident.
The code generation for the PAD function is different compared with Cadvanced, in the way that code that is common in process types is copied into the PAD function for instantiated processes.
Procedures follow the same code generation as processes, with some small exceptions in macro naming conventions for variable declarations.
Each SDL process is represented in C by a C function called yPAD_ProcessName.
Example 595 : yPAD_ProcessName
/* Function for process ProcessName */#ifndef XNOPROTOextern YPAD_RESULT_TYPE yPAD_ProcessName ( YPAD_ANSI_PARAM )#elseextern YPAD_RESULT_TYPE yPAD_ProcessName ( YPAD_KR_PARAM )YPAD_KR_DEF#endif{local variable sectionState-input-selection{start-transition including nextstatetransition-1 including nextstatetransition-2 including nextstate.......transition-n including nextstate}pad-end-section}/* Function for procedure ProcedureName */#ifndef XNOPROTOextern YPRD_RESULT_TYPE yPAD_ProcedureName ( YPRD_ANSI_PARAM )#elseextern YPRD_RESULT_TYPE yPAD_ProcedureName ( YPRD_KR_PARAM )YPRD_KR_DEF#endif{local variable sectionsection representing procedure body}Local Variables Section
The following defines are generated in the local variables section for processes.
YPAD_YSVARP /* used for signal variable pointers */YPAD_YVARP(yVDef_z00_P1)/* used for process variables */YPAD_TEMP_VARS /* used for temporary variables */YPRSNAME_VAR("P1") /* can be used for printf */BEGIN_PAD /* used for some preparations *//* to handle signals, or Integration*//* of any Realtime operating system */After expansion by the C preprocessor:
yVDef_z00_ProcessName *yVarP=(yVDef_z00_ProcessName *)pRunData;unsigned char *yOutputSignal;unsigned char *ySVarP;(void) printf(("PROCESS:%s\n", "ProcessName"));if((P_MESSAGE != ((void *) 0))&& (P_MESSAGE->mess_length > 4)){ySVarP = (unsigned char *) P_MESSAGE->mess_ud.pt_ud;}else{ySVarP = (unsigned char *) P_MESSAGE->mess_ud.ud;}The following defines are generated in the local variables section for procedures:
YPRD_YVARP(yVDef_znnn_ProcedureName)/* used for procedure variables */YPRD_TEMP_VARS/* used for temporary variables */YPRDNAME_VAR("ProcedureName")/* can be used for printf */State - Input Selection
The selection of the appropriate SDL transition which is to be executed in the current state with the current signal in the input port goes in principle over the transition table, described in previous chapters. With this table, the Cmicro Kernel can evaluate a symbol number, which is local to a process, a unique numbering of the different possible transitions. This numbering algorithm begins at 0 (which corresponds to the start symbol) and continues until all symbols for this particular process type have been numbered.
The appropriate transition is selected by the following switch:
switch (XSYMBOLNUMBER) {{case 0:. start-transitionnextstate;case 1: transition-1nextstate;}switch (_xSymbolNumber_ ){.....}Start Transition
The start transition is included into the body of the generated yPAD function and has the same layout as transitions, with the following exceptions:
Assignment of initialization values to all local variables in the processes and procedures (if any) is executed. All DCL variables are filled with their default-values.
The start transition is selected by the special case-value zero in the switch-statement of the yPAD function.
FPARS in dynamic process creation are not contained in this version of the Cmicro Package.
Transitions
The transitions are translated in the order they are found and are only translated to the sequence of actions they consist of. The translation of actions are discussed in the subsection Translation of Actions following a few lines below.
PAD-End-Section
Each yPAD function is finished with:
END_PAD (yPAD_ProcessName);The main reason for this is to make it possible to integrate other real-time operating systems.
Translation of Actions
Translation of Output
SDL output statements are translated to the following basic structure:
- allocate the data area for the parameters of the signal to be output
- assign signal parameters
- send the signal, parameters will be copied
- release the data area for the parameters of the signal.
There are a lot of different output macros generated. The main reason for this is that for each output situation an optimized code is to be generated.
One differentiation is made for signals without parameters and signals with parameters. For a signal without parameters, suffix _NPAR is used for the macro generated and for a signal with parameters, suffix _PAR is used. The relevant output macro can then be expanded to a simpler output C function called xmk_SendSimple, if no signal priority is used.
Another differentiation is made for signals which are sent to the system's environment or which are sent internally in the SDL system. The suffix _ENV is appended to the macros which are shown here, if the signal should go to the system environment.
The different directives which can be used within the SDL Suite to modify outputs are discussed in subsection Modifying Outputs - Directive #EXTSIG, #ALT, #TRANSFER.
The other different output situations which are handled, will be described in the next subsections.
Output without TO and without VIA
If the user specifies output SignalName without TO and VIA in SDL, the Cmicro SDL to C Compiler calculates the receiver of the signal. It is also possible to have more than one receiver for the signal. During execution time, any possible receiver that are alive may be selected otherwise if no receiver can be found, the C function ErrorHandler will be called. The following code is generated:
ALLOC_SIGNAL_ppp(SignalNamewithoutPrefix,SignalNamewithPrefix,SignalParameterTypeStructureName)
- ordinary assignment of Signal Parameters, if there are some...
SDL_OUTP_ppp(Priority,SignalNamewithoutPrefix,SignalNamewithPrefix,TO_PROCESS(ProcessNamewithoutPrefix,ProcessNamewithPrefix),SignalParameterTypeStructureName,"SignalNamewithoutPrefix")
The ppp above stands for either PAR or NPAR for a Signal with or without parameters.
After expansion, the user will find a C function call to the xmk_SendSimple function or the xmk_Send function.
Priority is generated as xDefaultPrioSignal if no priority is specified for the signal with #PRIO.
TO_PROCESS is expanded to a function call if there is at minimum one (x, N) declaration in the system, where N is > 1. This function returns one of the possible receivers of the signal.
TO_PROCESS selects an active instance of the given process type It does not check for different types as receivers.
TO_PROCESS is expanded so that the pid is passed directly to one of the C functions xmk_Send*, if there are only (x,1) declarations in the system.
If the environment is the receiver of the signal, then the following code is generated:
ALLOC_SIGNAL_ppp(SignalNamewithoutPrefix,SignalNamewithPrefix,SignalParameterTypeStructureName)
- ordinary assignment of Signal Parameters, if there are any...
SDL_OUTP_ppp_ENV(Priority,SignalNamewithoutPrefix,SignalNamewithPrefix,ENV,SignalParameterTypeStructureName,"SignalNamewithoutPrefix")
The ppp above stands for either PAR or NPAR for a Signal with or without parameters.
After expansion, the user will find that ENV is passed to one of the C functions xmk_SendSimple or xmk_Send. ENV is a special value used inside the Cmicro Kernel to detect which signals are to be passed to the C function xOutEnv.
Output with TO clause
If the user specifies the output SignalName to pid in SDL, the Cmicro SDL to C Compiler generates the following code:
ALLOC_SIGNAL_ppp(SignalNamewithoutPrefix,SignalNamewithPrefix,SignalParameterTypeStructureName)
- ordinary assignment of Signal Parameters, if there are some...
SDL_OUTP_ppp(Priority,SignalNamewithoutPrefix,SignalNamewithPrefix,pid-variable,SignalParameterTypeStructureName,"SignalNamewithoutPrefix")
The ppp above either stands for PAR or NPAR for a Signal with or without parameters.
Expansion reveals a C function call to the xmk_SendSimple function or the xmk_Send function.
Priority is generated as xDefaultPrioSignal, if no priority is specified for the signal with #PRIO.
Possible generated values for pid variable are SDL_SENDER, SDL_PARENT, SDL_OFFSPRING and SDL_SELF or an SDL pid variable. These values are passed to the xmk_Send* functions. The name of a process as specified in SDL may also be given.
Output with VIA clause
The Cmicro SDL to C Compiler computes the possible receivers in an output with the VIA clause. If there are several possible receivers, an error message is produced.
If there is exactly one receiver, the same code is generated as for SDL output without to.
List of Generated Output Macros
- ALLOC_SIGNAL_NPAR
Allocating memory for signal without parameters- ALLOC_SIGNAL_PAR
same for signals with parameters- TO_PROCESS
Macro used to evaluate a receiver process instance, if necessary in the case of (x, N) declarations, where N > 1.- SDL_OUTP_NPAR
Output internally in the SDL system for signal without parameters- SDL_OUTP_PAR
same for signal with parameters- SDL_OUTP_NPAR_ENV
Output to the system environment for signal without parameters- SDL_OUTP_PAR_ENV
same for signal with parameters- SDL_ALTOUTP_NPAR
#ALT for an output internally in the SDL system for signal without parameters- SDL_ALTOUTP_PAR
same for signal with parameters- SDL_ALTOUTP_NPAR_ENV
#ALT for an output to the system environment for signal without parameters- SDL_ALTOUTP_PAR_ENV
same for signal with parameters- EXT_SignalName
if #EXTSIG is used in output- TRANSFER_SIGNAL
#TRANSFER is used in outputTranslation of Create
The create action in SDL is translated to the following C code:
ALLOC_STARTUP_ppp(ProcessNamewithoutPrefix,ProcessNamewithPrefix,"ProcessNamewithoutPrefix, 0);
- ....assignment of start-up values (cannot be used in this version of the Cmicro Package)
SDL_CREATE(ProcessNamewithoutPrefix,ProcessNamewithPrefix,"ProcessNamewithoutPrefix, 0,VariableofCreatedProcess,PriorityofCreatedProcess,yPAD-functionNameofCreatedProcess);PriorityofCreatedProcess is generated as
xDefaultPrioProcess, if no priority is specified with #PRIO.Translation of Set
The translation of set is restricted in a few areas in order to produce efficient code for a micro controller. For example, the SDL duration expressed by a real value in the context of timers is not implemented. The reason for this is that controllers do not have floating point operations or floating point operations are not used in order to increase the performance. For timers, such a high resolution is not necessary in most applications. The Cmicro Package uses a long value in its standard implementation to represent absolute time.
In order to make the examples below more readable, it is assumed that at least one timer with parameter is used in the system (macro XMK_USED_TIMER_WITH_PARAMS is defined in the generated file sdl_cfg.h). If the macro is not defined, then the handling for timers with parameters is not included.
If the following is specified in SDL/PR:
Timer TimerName;......Set (now + durationvalue, TimerName) ;Set (now + 22222, TimerName) ;then the following code is generated:
SDL_SET_DUR \(xPlus_SDL_Time(SDL_NOW,SDL_DURATION_LIT(22222.0,22222,0)),SDL_DURATION_LIT(22222.0, 22222, 0),TimerName,TimerNamewithPrefix,yTim_timer2,"TimerNamewithoutPrefix")If the following is specified in SDL/PR:
Timer TimerName := TimerGroundValue ;---> see Note:!then the following code is generated:
SDL_SET_TICKS(xPlus_SDL_Time(SDL_NOW, TICKS(SDL_INTEGER_LIT(22222))),TICKS(SDL_INTEGER_LIT(22222)),TimerName,TimerNamewithPrefix,yTim_timer2,"TimerNamewithoutPrefix")The code after expansion then contains a function call to
xmk_TimerSet (TIMEEXPR,TimerNamewithPrefix,0).TIMEEXPR is the result of the evaluation of now plus duration value.
#define SDL_SET_DUR(TIME_EXPR, DUR_EXPR, TIMER_NAME, TIMER_IDNODE, TIMER_VAR, TIMER_NAME_STRING) \xmk_TimerSet(TIME_EXPR, TIMER_IDNODE,0);#define SDL_SET_TICKS(TIME_EXPR, DUR_EXPR, TIMER_NAME, TIMER_IDNODE, TIMER_VAR, TIMER_NAME_STRING) \xmk_TimerSet(TIME_EXPR,TIMER_IDNODE,0);If a timer with parameter is defined in SDL/PR:
Timer TimerName (integer);...set (now+1, TimerName (4711));then the following code is generated:
SDL_SET_DUR_WITH_1IPARA(xPlus_SDL_Time(SDL_NOW,SDL_DURATION_LIT(1.0, 1, 0)),SDL_DURATION_LIT(1.0, 1, 0), TimerName,TimerNamewithPrefix,yPDef_z262_twp1,yTim_TimerName,"TimerName",SDL_INTEGER_LIT(4711))The code after expansion then contains a function call to
xmk_TimerSet (TIMEEXPR,TimerNamewithPrefix,4711).Restrictions in the Use of Timers
- Timers with parameters are restrictively supported in Cmicro. There might be only one parameter of sort "integer". This implementation has been chosen to achieve the highest efficiency.
- Duration values as real values are not supported in this version of the Cmicro Package, i.e. this:
set (now + 5.5, TimerName)Translation of Reset
If the user specifies in SDL/PR:
Reset (TimerName) ;then the following code is generated:
SDL_RESET(TimerNamewithoutPrefix,TimerNamewithPrefix,yTim_TimerName)The code after expansion contains a function call to xmk_TimerReset (TimerNamewithPrefix).
For a timer with one integer parameter, the following macro call is generated:
SDL_RESET_WITH_1IPARA(TimerNamewithoutPrefix,TimerNamewithPrefix,TimerParStruct,yTim_TimerName,TimerValue)
Timers with parameters are supported with the restriction that only one integer parameter is allowed.
Translation of Call
As SDL procedures are implemented with the restrictions explained within subsection SDL Restrictions, the following explanatory C code (to a procedure called ex_proc) is generated:
ex_proc (....C parameters ...);All necessary parameters are routed via the C function call stack.
Translation of Call to a Procedure Returning Value / Operator Diagram
Operator diagrams and procedures returning values are - considering the call - handled in the same way please see the following explanatory example:
TASK i := (call p(1)) + (call Q(i,k));
- is translated to something like:
i = p(1) + Q(i,k);
The value of returning procedure calls are transformed to C functions returning values.
Translation of Nextstate
The nextstate operation is generated at the end of each transition contained in the yPAD function, as follows:
- If the process performs simple nextstate operation:
SDL_NEXTSTATE(State1, z000_State1, "State1")return (z000_State1);- If it performs a nextstate, which is defined as a dash state:
SDL_DASH_NEXTSTATEreturn (XDASHSTATE);Translation of Stop
A stop action is translated to:
SDL_STOPreturn (XDORMANT);which is good code saving. The Cmicro Kernel then enters the new state value into the Process State Table.
Translation of Return
#ifdef XFREEVARSFREE_PROCESS_VARS ()#endifSDL_RETURN#define SDL_RETURN \if (_xxptr != (unsigned char*) NULL) \{ \XMK_MEM_FREE ((unsigned char *)_xxptr); \} \return ;where xxptr is the pointer to the procedure instance data, as given via the C function call parameter list. Note, that the memory previously allocated directly before the procedure call is freed at the end of the procedure, not outside of the procedure.
Translation of SDL Expressions
In this section some of the translation rules for expressions are described. For more information see Translation of Sorts where for example the translation rules for literals and operators in the predefined abstract data types are given.
Now
SDL now is translated to the macro SDL_NOW which is expanded to the C function xmk_NOW. This function is exported by the module mk_stim.c.
Self, Parent, Offspring, Sender
The definitions for self, parent, offspring, sender are:
#ifdef XMK_USED_SELF#define SDL_SELF xRunPID#endif#ifdef XMK_USED_PARENT#define SDL_PARENT pRunPIDTable->Parent#endif#ifdef XMK_USED_OFFSPRING#define SDL_OFFSPRING pRunPIDTable->Offspring#endif#ifdef XMK_USED_SENDER#define SDL_SENDER P_MESSAGE->send#endifAll the variables above are of type xPID. All variables are maintained by the Cmicro Kernel. xRunPID is a global variable which contains the pid of the SDL process which is currently running. P_MESSAGE is a pointer to the signal instance which is currently worked on.
Timer Active
An SDL timer active expression is translated to:
SDL_ACTIVE(TimerName, TimerName,yTim_TimerName)xmk_TimerActive(TimerName)A conditional expression in SDL is translated to a conditional expression in C.
Init Function
An explicit initialization function is not generated by the Cmicro SDL to C Compiler in any case.
The structure of the SDL system is not generated into the C code. What is seen in the generated code, is the behavior of the SDL system. Variables of processes are initialized during the start transition of a process and no information about the structure of the SDL system is available during run-time in the generated code.
An initialization function is generated only in that case if synonyms are used within SDL, which require an initialized C variable.
All this results in a more compact executable.
For example, the following use of an SDL synonym results in a generated initialization function:
synonym a integer := /*#CODE anyUserFunction () */The following C code is then generated within the C function yInit:
yAssF_SDL_Integer(a, anyUserFunction (), XASS);yInit is called by the Cmicro Kernel if the define
XMK_USED_INITFUNCis generated into the file sdl_cfg.h, which is done in the case above.
Initialization of Synonyms
The Cmicro SDL to C Compiler allows SDL synonyms to be implemented as C macros and C variables.
Initialization is implemented within the C function yInit which is conditionally compiled.
Function main
The C function main is not automatically generated by the Cmicro SDL to C Compiler. This is unnecessary because the main function usually is provided from the user or the predefined main function can be used. Instead of an automatically generated main function, the user must supply the function body of main, for target applications. Guidelines can be found in the subsection Implementation of Main Function.
http://www.ibm.com/rational |
![]() |
![]() |
![]() |
![]() |