Table of Contents Previous Chapter 45 The Cmicro Library

45 The Cmicro Library

The Cmicro Library is a collection of C functions and C modules, which consists of a configurable SDL kernel (the so called virtual SDL machine) and all functions which are necessary to handle SDL data. The Cmicro Library can be used in combination with the C code, which is generated by the Cmicro Generator. Please view chapter 44, The Cmicro Generator. The scaling facilities make it useful for the application in micro controllers and real-time applications. The Cmicro Tester offers the capability of target testing and debugging. Please view chapter 46, The Cmicro Tester.

Introduction

The Cmicro Library is a collection of C functions and C modules, which consists of:

In this chapter, the C source code of the Cmicro Library and the generated C code of an application are described. The Cmicro Tester is dedicated an extra chapter (see chapter 46, The Cmicro Tester), although some features are outlined here. The following topics are discussed here.

  1. The sections "File Structure" on page 2732, "SDL Symbol Information" on page 2737 and "The SDL Model" on page 2742 describe the run-time model for programs which are generated by the Cmicro Generator. It is mainly the data structure, which is of most concern in these chapters. The description caters for the static, and the dynamic point of view.
  2. The section "Structure of Generated C-Code" on page 2775 gives an overview of the code generated by the Cmicro Generator in order to make it possible to interpret the generated code. Knowing how the code is generated makes it quite easy to understand the program, which is necessary to test and debug erroneous executables.
  3. The section "Technical Data" on page 2813 gives some help to estimate the performance and required memory.
  4. The sections "Compilation Flags" on page 2817, "Creating a New Library" on page 2836 and "Adaptation to Compilers" on page 2842 show, how to create new compilations of the Cmicro Library.
  5. The section:"Differences between Cmicro and Cadvanced" on page 2846 helps in implementation.
  6. An example of generated code is given in the section "Example of Generated C Code" on page 2850. The example should be inspected first, before reading the detailed descriptions.
Pay extra attention to the subsection "Automatic Scaling" on page 2833, which contains important changes to the SDT Master Library.

The section "Adaptation to Compilers" on page 2842 deals with the introduction of new compilers and machine platforms.

If examples of generated code are given, they are always shown in ANSI style. In addition, only the important parts of the code are shown, to increase readability in the examples.

File Structure

Description of Files

The Cmicro Library Functions and Definitions

sdl_cfg.h

This file is automatically generated by the Cmicro Generator into the directory which is currently active. It contains compilation flags used for the automatic scaling of the Cmicro Library and the generated C code. The file must not be edited by the user.

-----------------------------------------------------------------------
Caution!                                                                 
The file sdl_cfg.h always carries the same name, for each SDL            
system generated and is stored in the currently active directory (use    
pwd to determine). Inconsistencies arise, if several systems are to be   
generated in the same directory. To avoid this situation, use differ     
ent working directories for each SDL system, otherwise, unpredict        
able results at run-time could be observed, as some required auto        
matic scalable features may/may not have been compiled.                  
-----------------------------------------------------------------------

ml_typ.h

This file is the central header file in the Cmicro Package. It contains

ml_pred.h and ml_pred.c

These files contain all definitions necessary to handle SDL data, for example predefined sorts. ml_pred.h is included in ml_typ.h.

ml_err.h

This header file defines all error numbers used by Cmicro Kernel, Cmicro Library and Cmicro Tester.

ml_*.h

Other header files which contain extern declarations of modules of the Cmicro Library. The contents and details of the various header files only need to be known if the user wishes to modify parts of the Cmicro Library.

ml_mem.c

This file contains an example, which implements dynamic memory management using among others the C functions malloc, calloc, free. Possible reasons to use this the ml_mem.c module are:

ml_mon.c

This file contains some help functions, which are useful in producing screen outputs. It contains C functions for buffer printouts, SDL PId printouts, and display of the current scalings used in the executable.

ml_err.c

This file exports one C function xmk_err_text, which either can be used to display error messages on the screen, translate the error codes into readable text or as a mechanism for the classification of fatal errors, warning or information.

The Cmicro Kernel

mk_main.c

This file represents the main-interface to the SDL user. It contains functions which are to be called by the SDL user to integrate the Cmicro Kernel in his application.

mk_user.c

This module contains function templates or examples which are to be filled out by the user:

xInitEnv
Initializing the environment, the hardware (a serial link used for communication.)

xInEnv
Receiving signals from the environment. This is the connection between the SDL system and its environment, direction environment into the SDL system.

xOutEnv
Sending signals to the environment. This is the direction from SDL system into the environment.

xCloseEnv
Closing the environment, the counterpart to xInitEnv.

ErrorHandler
Central error handling routine, is called each time an errors occurs.

MemError
Central error handling routine only for malloc in the ml_mem-module.

WatchdogTrigger  
Handling of a hardware watchdog.

mk_sche.c

This file is the heart of the Cmicro Kernel. It exports those functions, which are used in the mk_main-module, and it uses those functions of other modules, which represent the SDL model. The module serves with all the different scheduling policies described later in the subsection "Scheduling" on page 2749.

mk_outp.c

This file contains the SDL-operation output, which is represented by a few functions. There is a C function xmk_Send representing the SDL output operation. In addition, there is a C function xmk_SendSimple, which is used when a signal contains no parameters and has no explicitly defined priority. This results in a more compact argument list thus reducing the generated C Code.

mk_queu.c

This module contains the data type "SDL queue" and defines all operations on the SDL queue. The queue handling covers all the aspects of the SDL semantics as far as signals are concerned.

mk_tim1.c

This file contains the SDL operations on timers such as set, reset, active, and some help functions used by the Cmicro Kernel for the timer model 1, which is described within the subsection "Timer Model 1" on page 2747. The Cmicro Kernel has to initialize all timers, test for expiration, and reset all timers of a process, when a process instance type stops.

mk_tim2.c

This file contains the SDL operations on timers like set, reset, active, and some help functions used by the Cmicro Kernel for the timer model 2.

The file is not contained in this version of the Cmicro Package.

mk_stim.c

This file contains some functions, which are to be filled up by the user. They are used by the Cmicro Kernel to get the system time used in SDL. The contents of this file should be seen as a template. No provision for the connection to hardware timers is provided in the delivered source, as the timer used is application dependent. The user is required to fill out the appropriate functions, for the provision of SDL system time.

----------------------------------------------------------------------
Note:                                                                   
If difficulties arise in adapting the Cmicro Package to your compiler   
or target, please contact your SDT distributor.                         
----------------------------------------------------------------------

mk_cpu.c

This file also contains some hardware specific functions, which should be seen as templates. In the case of an interrupt driven environment, the C functions enable and disable are used by the Cmicro Kernel to enable and disable interrupts along critical paths of the Cmicro Kernel.

The flag XMK_USE_IRQ should be set to notify the Cmicro Kernel of the need to lock critical paths.

mk_*.h

Other header files contain extern declarations of modules of the Cmicro Library. The contents and details of the various header files only need to be known if the user wishes to modify parts of the Cmicro Library.

SDL Symbol Information

The structure of an SDL system can be represented by a tree diagram. In SDL, the root of the tree is represented by the SDL system, followed by blocks, block substructures, processes and procedures (*1). Channels, channel substructures and signal routes are also represented in the tree. This tree is static, that means, it cannot be modified during the run-time of an SDL system.

The SDT Code-Generator generates code, so that this static structure is present in the generated code. This is good for debugging purposes.

The Cmicro Generator generates code, so that this static structure is not present in the generated code, in order to spare memory. To enable debugging of the generated code, C comments are generated. Please consult the subsection "GR References" on page 2795.

(*1) In SDL`92 several SDL systems can exist in parallel.

Numbering of SDL-Objects

Processes and Process IDs (PID)

SDL process types, as well as SDL process instances are numbered consecutively beginning with zero. The ordering of these numbers is the same as the ordering of the processes in the SDL-PR file.

The values 250 to 255 are reserved for internal purposes, and must not be used for process type numbering. For small systems no hindrance is incurred.

The Cmicro Kernel assumes the above definitions.

In the generated code, the SDL values self, sender, parent and offspring, and variables of this type are represented by the typedef xPID. The intention is to have an SDL systemwide unique numbering of processes and their instances. This becomes necessary because of the Cmicro Code no longer containing the structure of the SDL system (system, block...). The typedef xPID is defined as

or

There are a few macros defined to extract the process type number or the process instance number from a variable of the type xPID, and to build an xPID variable from a process type number and a process instance number, the users don't have to think about the internal representation:

Example 329   
processtype     = EPIDTYPE(xPID_variable)
processinstance = EPIDINST(xPID_variable)
xPID_variable   = GLOBALPID(processtype, 
processinstance)
  

Signals and Timers

SDL signals and timers are numbered automatically by the Cmicro Generator, so that they have a systemwide unique number. Timers are represented by the values 1, 2, 3.... MT to the last timer of the MT timers in the system. Thereafter directly follow ordinary SDL signal numbers beginning with MT+1, MT+2, MT+3... MT + MS.

When using the standard Cmicro Package, as delivered, then the values 0 and 250 to 255 are reserved for internal purposes. If the upper limit of 249 signals and timers is not enough, then the signal ID type has to be changed from unsigned char to unsigned int, thus allowing more than 60000 signals/timer to be handled. The user will have to redefine some fixed values used for internal purposes in the Cmicro Package when using more than these 249 signals and timers, too.

----------------------------------------------------------------------
Caution!                                                                
The Cmicro Generator doesn't check for the upper limit of 249 sig       
nals being reached for a generated SDL system. The user will get no     
warning if, i.e.250 signals are used. Normally, SDL systems grow        
through their development and maintenance phases, and the user          
must secure, that this upper limit isn't reached. If more than 250 sig  
nals (timers + SDL signals) are required, set the signal ID type from   
unsigned char to unsigned int as described above.                       
----------------------------------------------------------------------
Example 330 : Code generated for signals and timers   
#define znnn_SignalName 1
#define znnn_SignalName 2
  
where znnn_ is the automatically generated prefix, required to cope with the SDL scope rules. Remember, that processes in SDL can have the same name as signals, states etc. Prefixing, however, ensures uniquely named SDL objects in the generated C Code.

Example 331 :
A system with 2 signals S1 and S2, and a timer TIMER1 #define z049_TIMER1 1 #define z050_S1 2 #define z051_S2 3
When it comes to connecting the environment to the SDL system, the automatic numbering of signal IDs and timer IDs may not be required. If you want to prevent the automatic numbering of signals, then it is possible to #include a file containing all the signal and timer numbers. The file may contain something like:

#undef  SignalOrTimerName
#define SignalOrTimerName AnyValueAccordingToKernelRules

Numbering SDL Objects by Hand

Normally, all the objects in the SDL system are automatically numbered by the Cmicro Generator, i.e. by an incremental numbering algorithm in the case of states, signals, timers and process types.

For some purposes, it may be necessary to give signals and timers and process types a fixed, user defined identification. This makes it possible, for example to identify such objects in the environment handling C functions xInEnv and xOutEnv. For processes, manual numbering is normally not necessary.

Firstly the user has to ensure, that no prefixes are generated for these objects. This can be done object by object, when using the #NAME directive in SDL as follows:

Example 332 : Using #NAME directive  
signal ThisismySignal /*#NAME `ThisisaSignal' */
The following line appears in the generated code.
#define ThisisaSignal  <anydecimalnumber>
  
Another possibility for the non augmentation of prefixes to SDL objects is to modify the option settings in the Analyzer menu.

Secondly, for environment signals, (i.e. signals that are swapped between the SDL system and the environment) which are to be used in the module containing the C functions xInEnv and xOutEnv, the user has to include the generated environment header file in the module which contains the necessary definitions of the SDL entities at the system level. The generated environment header file is automatically named <systemname>.ifc by the analyzer.

States

SDL states are consecutively numbered from 1 through to N for each process type. The values 0, and 250 to 255 are reserved for internal purposes in the Cmicro Package. This restriction normally incurs no foreseeable difficulty as processes should never have more than 50 States.

The following C code generation is supplied for the header-section of the generated C-file(s).

For each SDL-process:

#define znnn_State1Name 1
#define znnn_State2Name 2
....
#define znnn_State3Name 3
Example 333  For a process with 2 states S1 and S2:   
#define z020_S1
#define z021_S2
  
These values are used in the state-index-table and in the generated C-functions, whereever a nextstate is referenced.

The SDL Model

In this section, the functionality of the Cmicro Library is outlined, with particular emphasis on Basic SDL, the handling of the queue, scheduling, signals, timers, states etc. To obtain information about data in SDL, especially ADTs, please consult chapter 44, The Cmicro Generator. Here both predefined and user defined ADTs are outlined.

Signals Timers, and Start-up-signals

Data Structure for Signals and Timers

Each signal, that is either an ordinary SDL signal, or a timer, or the start-up signal used for the dynamic process creation, is represented by three structures:

The first and the second is defined in ml_typ.h, the third is defined in the generated code as yPDef_SignalName. Some structure components are conditionally compiled, which is used to scale the system. Please view the following C structure:

typedef struct
{
   #ifdef XMK_USE_RECEIVER_PID_IN_SIGNAL
       xPID          rec;   /* Receiver process     */
   #endif
   xmk_T_SIGNAL  signal;    /* Signalcode           */
   #ifdef XMK_USE_SIGNAL_PRIORITIES
      xmk_T_PRIO  prio;     /* Priority         */
   #endif
   #ifdef XMK_USE_SIGNAL_TIME_STAMP
      xmk_T_TIME time_stamp;/* Timestamp        */
   #endif
   #ifdef XMK_USE_SENDER_PID_IN_SIGNAL
       xPID         send    /* Sender process   */
   #endif
   #ifdef XMK_USED_SIGNAL_WITH_PARAMS
     xmk_T_MESS_LENGTH mess_length;
     union
     {
        void          *ParPtr;
        #if (XMK_MSG_BORDER_LEN > 0)                     
          unsigned char ParCopy[XMK_MSG_BORDER_LEN];  
        #endif
     } ParUnion;
   #endif
} xmk_T_MESSAGE;
Three different cases are to be considered concerning signals with parameters:

The second structure, which encapsulates the above one, is used to administrate the signals in the queue, concerning the FIFO handling and SDL save construct:

typedef struct _T_E_SIGNAL
{
  xmk_T_MESSAGE       Signal;
  struct _T_E_SIGNAL *next;
#ifdef XMK_USED_SAVE
  xmk_T_STATE         SaveState; 
#endif /* XMK_USED_SAVE */
} T_E_SIGNAL ;
As already mentioned, the above structure is used for ordinary SDL signals, timers and the start-up signal for the dynamic process creation.

No differentiation is made between signals and timers, except that signals and timers have a different identification (signal in the xmk_T_SIGNAL structure).

When a process is to be created, a start-up signal is sent. The start-up signal is tagged by a special priority value and a special id.

Dynamic Memory Allocation for Signals and Timers

Dynamic memory allocation is in principle not necessary in the Cmicro Package, if so desired by the user. In the standard version of the Cmicro Package, there is a 4 byte margin of parameters for signals. Dynamic memory allocation only occurs, if a signal carries more than XMK_MSG_BORDER_LEN bytes, where the latter is defined as 4.

If you define XMK_MSG_BORDER_LEN as 0, then for each signal, which has parameters, the C function malloc is called.

If you define XMK_MSG_BORDER_LEN to 127, then

Overview for Output and Input of signals

Output and input of signals is performed according to the rules of SDL. To get detailed information about the implementation of output and input, please consult the subsection "Output and Input of Signals" on page 2756.

Signal instances are sent using the C function xmk_Send or xmk_SendSimple. That function takes a signal and puts it into the input port of the receiving process instance.

Figure 573 : Queueing - Sending side 
-----
(fig)  
       
-----
There is no process ready queue. Physically, the queues of the different processes of the system are represented by one queue implemented as a C array scalable by XMK_MAX_SIGNALS. This define sets the upper limit of signals to be possible to queue at once. The array is used to build a linked list of signals currently in the system's queue. From an abstract point of view, this has no effect on SDL users, and is conform to the semantic rules of SDL. The scheduling simply depends on the ordering of signals in the queue. In the case of a so scaled preemptive Cmicro Kernel, there is one linked list of signals per priority level all using the array mentioned above. See the subsection "Scheduling" on page 2749 for details.

Figure 574 : Queueing - Receiving side 
-----
(fig)  
       
-----
When working on a signal, the Cmicro Kernel decides between four different constellations:

In any case, except when being saved, the signal will be removed from the queue and returned to the list of free signals.

After performing the nextstate operation, the input port is scanned, according to the rules of SDL to find the next signal which would cause an implicit or explicit transition.

There is no specific input function. This functionality is contained in the Cmicro Kernel.

Timers and Operations on Timers

A few timer models are defined in the Cmicro Package. This has been done to cover the various situations, where one timer handling can have disadvantages with respect to another. This is strongly dependent upon on the generated application. The timer model to be implemented is at the users discretion.

Timer Model 1

With timer model 1, all timer management entities are fully conform to SDL. This means, that more memory is required to implement this timer.

For each timer, there is a C structure defined in ml_typ.h.

typedef struct _TIMER        
{
  struct _TIMER *next ;      
  xmk_T_SIGNAL   Signal   ;  
  xmk_T_TIME     time     ;  
  xPID           OwnerProcessPID ; 
} TIMER ;
xmk_T_TIME is defined as a long value.
Figure 575 : Handling of Timers (Timer Model 1) 
-----
(fig)  
       
-----
The component

As can be seen above, timers are implemented as a forward linked list.

Timer Model 2

The timer model 2 is an suggested extension of the Cmicro Library and not contained in this release.

Processes

Data Structure for Processes

Each process is represented by structures and tables containing SDL information, for example, tables containing transition definitions and a structure representing the variables of the process. The typedef for variables is generated in the generated code and named as yVDef_ProcessName. For each process instance, there is one array element defined statically during compile time.

The structures and tables for processes are described in detail in the subsection "Tables for Processes" on page 2785.

Scheduling

The Cmicro Kernel supports in principle the following scheduling policies:

General Scheduling Rules

Further explanation of the scheduling is the next subsections' aim.

Non Preemptive Scheduling

The Cmicro Kernel takes the first signal from the queue and, if not to be saved, the appropriate SDL transition is executed until a nextstate operation is encountered. Outputs in SDL transitions as well as SDL create operations are represented by signals, where create signals are given priority treatment, no matter if signal priorities are used or not. In this way it is guaranteed to cause no problems when sending a signal to a process just before dynamically created.

The ordering of signals in the queue can be affected by using signal priorities (#PRIO directive for signals).

Whenever an output takes place, the Cmicro Kernel inserts the signal into the queue according to their priority. High priority signals are inserted at the queue's head, low priority signals at the queue's end. Create signals are still given priority treatment.

---------------------------------------------------------------------------
Note:                                                                        
The priority of a create signal in the standard delivery is set to one.      
This, as well as all the default signal priority, is user-definable in the   
file ml_mcf.h. In this way it is possible to define signals with a high      
er priority as the create signal. The user should keep in mind not to        
do so!                                                                       
---------------------------------------------------------------------------
Figure 576 : Non preemptive scheduling 
-----
(fig)  
       
-----
Figure 577 : Scheduling for create 
-----
(fig)  
       
-----
A signal (this is either an ordinary SDL signal, a timer signal, or the internal start-up signal in the event of SDL create) with the highest priority is always put in front of the SDL queue, a signal with the lowest priority is always put at the end of the SDL queue.

Figure 578 Signal Priorities 
-----
(fig)  
       
-----
For applications, which do not have time critical requirements, the non preemptive scheduling policy is the correct one to implement. The Cmicro Kernel memory requirements are also reduced when the non-preemptive scheduling policy is implemented. For example, for an interface with a very high transmission rate, the preemptive scheduling policy is better suited in order to increase the reaction time on external signals coming from the environment.

On starting the SDL system, processes are statically created according to their order of priority.

Preemptive Scheduling with Process Priorities

Figure 579 Preemptive Scheduling 
-----
(fig)  
       
-----
SDL assumes the start transitions of all statically created processes already finished at system start-up (a transition takes no time according to SDL semantics). To simulate this, the Cmicro Kernel starts all statically created processes in the order of their priority before working on any signal. Preemption is disabled during the start-up phase of the system. There are two C functions namely xmk_DisablePreemption and xmk_EnablePreemption which can be used by the user, too, to prevent the Cmicro Kernel from performing a context switch. In this way it is possible to affect the scheduling from within the SDL system (using the #CODE directive).

The preemptive scheduling policy is absolutely necessary if an application consists of a mixture of processes, some having to react very quickly to external events, others having enough time for processing. The Cmicro Kernel does all things necessary to schedule such a mixture of processes.

Users only have to specify a high priority for processes which have to react after a short time. This can be done with the #PRIO directive for processes. If no #PRIO directive is specified, then a process is given the default value, which is specified by the user in the file ml_mcf.h (please view the subsection "Configurations / the File ml_mcf.h" on page 2762).

The highest priority is represented by the value zero, the numbering has to be consecutive with the priority decreasing with increasing numbers. Processes with the same priority are on the same priority level. The default process priority must be in the range of zero to lowest priority value used in the system. Assume the following priority levels:

Figure 580 Priority levels 
-----
(fig)  
       
-----
In the figure above there are signals queued for processes on four different priority levels. These would be worked on in this order:

According to their priorities the signals on priority level zero are consumed first, afterwards those of level one, two and last three. This is relevant only, if no signals are sent during the transitions executed because of the signals.

Rules

Restrictions

In order to produce portable C code, this version of the Cmicro Kernel uses recursive C function calls. A few C compilers available on the market do not support recursion. If such a C compiler is required, the user cannot use preemptive scheduling with process priorities.

Create and Stop Operations

No dynamic memory allocation occurs, if an SDL create operation is performed. No freeing of memory occurs, if an SDL stop operation is performed.

Data of a process instance is represented by the following typedef structs:

The reason for using such a structure is to make it possible for the Cmicro Kernel to operate on the PID structure and the table with SDL states, so that no code needs to be generated in the application to update such variables.

An array of N elements for each of these typedef structs is generated, where N is the maximum number of process instances. The maximum number is to be specified in the process declaration header in the SDL diagram.

After performing a stop action, old PID values might exist in variables of other processes. The synchronization between processes to prevent situations, where signals are sent to dead processes, is left to the discretion of the user. If a process sends a signal to a non existent process, where non-existent means either "never created", or "is dead", the ErrorHandler is called and the signal is discarded (SDL conform).

When the Cmicro Kernel stops a process, the input queue assigned to the process stopped will be removed. No interpretation error occurs for the signals which existed in the queue before the process was stopped.

---------------------------------------------------------------------
Note:                                                                  
It is also possible for the user to implement dynamic memory allo      
cation for process instance data. Some C-Defines are to be redefined   
in this case.                                                          
---------------------------------------------------------------------

Output and Input of Signals

The actions to perform an output in the generated code are as follows:

Within the xmk_Send*- functions there are a few checks performed. For example, if the receiver is a NULL-PID, then the ErrorHandler is called.

Next, the environment C function xOutEnv is called. This function is to be filled out by the user. The function decides, if the signal should be sent to the environment (*1). The information necessary can be extracted from the signal ID, the priority, or the receiver of the signal. If xOutEnv has "consumed" the signal, xmk_Send* returns immediately.
xOutEnv has to copy the parameters of the signal to the receiver of the signal in the environment, because after returning, the parameters will no longer exist.

If the signal not environment bound, then the signal is sent to an internal SDL system process, and xmk_Send* inserts the signal into the queue. This is done according to the priority of the signal (see subsection "Assigning Priorities Directive #PRIO" on page 2684 in chapter 44, The Cmicro Generator).

If the signal carries no parameters, or if the signal parameters are represented by less than or equal to XMK_MSG_BORDER_LEN bytes, no dynamic memory allocation occurs and possible parameters are transferred directly by copying them into the signal header.

If more than XMK_MSG_BORDER_LEN bytes parameters are to be transferred dynamic memory allocation occurs. A pointer in the signal header then points to this allocated memory area. Freeing is done after consumption of the signal at the receiver process, after executing the nextstate operation or after the signal was consumed by the environment.

In order to implement this strategy, each signal carries a field "data length" in its header, to detect, if a pointer is transferred, or a copy of the parameters.

-------------------------------------------------------------------
Note:                                                                
 *1) There are several possibilities to send signals to the environ  
ment, by not using xOutEnv. Look to the #EXTSIG, #ALT and            
#TRANSFER-Directives, which can be used in SDL-Output. The           
most SDL-fashion like, however is the one which simply uses the C    
function xOutEnv.                                                    
-------------------------------------------------------------------
At the receiver's side, when the input operation is to be performed, it is checked, if the signal is to be saved, or discarded. In the case of save, the next signal contained in the queue is checked and worked on. If on the other hand the signal is to be discarded in the case of an "implicit transition", i.e. no definition is present to handle that signal in the current state the signal is then deleted from the input port of the process and, using the Cmicro Tester, the user is notified.

Otherwise, the signal leads to the execution of the transition. After performing the nextstate operation, the signal is deleted from the input port of the process, and scheduling continues according to the rules of the scheduler again.

In the case of a so scaled preemptive Cmicro Kernel, the signal remains active in the input port, until the nextstate operation is executed, although other processes can interrupt the running one (preemption).

Nextstate Operation

The nextstate operation is implemented by a return (return value) statement in the generated code. Several return values are possible to control the action to be taken by the Cmicro Kernel. The PAD function representing the SDL process can return any of the following (PAD means "Process Activity Description").

The return-value either expresses

After recognizing the action to be taken, the Cmicro Kernel either writes the process state variable, or stops the SDL process.

The signal which was currently worked on, is deleted from the input port. This includes the freeing of the memory area allocated for the signal, if memory was previously allocated.

Decision and Task Operations

No action is to be performed by the Cmicro Kernel for decisions and tasks, except those to trace these actions for the Cmicro Tester.

For SDL decisions and for SDL tasks, C assignments and C function calls are implemented. Function calls are used in the case of having an ADT, or where simple C data operations (i.e.=, >, >=, ==) cannot represent the SDL operation wanted.

----------------------------------------------------------------------
Note:                                                                   
Function calls, however, are not necessarily generated, i.e. if you de  
fine C macros/defines instead of C functions for an ADT. Please         
consult the subsection "Abstract Data Types" on page 2622 in chap       
ter 44, The Cmicro Generator.                                           
----------------------------------------------------------------------

Procedures

There are some special topics regarding procedures in SDL. The most important are

However, procedures with states and remote procedure calls are not supported within the Cmicro Package.

It is possible to use global procedures (SDL'92), which makes it possible to specify a procedure once, by allowing several processes to call it.

Recursion is allowed, but should be introduced only if an algorithm cannot be designed alternatively. In most cases, algorithms and recursivity are subject for an ADT.

Procedures returning values are implemented also. The return value in SDL is mapped to a return value in C. Procedures not returning values are mapped to C functions returning void.

The remaining part is the location of procedure data and the access to procedure data. Here another restriction exists, namely that it is not possible to access data of the father procedure of a procedure.

Data, which belongs to a process, is always located as a global array in C (for x, N process declarations, where N is >1). Data, which belongs to a procedure, is always allocated on C stack for the called procedure.

Procedure Calls

An SDL procedure call is implemented as an direct function call in C. Each formal parameter is passed as an C parameter to the function. Access to global data of the calling process is possible only, if the procedure is not a global procedure. The C code generated for a local procedure uses global C variables of the surrounding process.

Data, which is declared locally within a procedure is also allocated on the C stack.

No dynamic memory allocation is performed, as procedures with states are not handled.

The following example shows the mapping for procedures returning values.

Example 334 : Procedure Call  
TASK i := (call p(1)) + (call Q(i,k));
is translated to something like:
i = p(1) + Q(i,k);
  
-------------------------------------------------------------------
Note:                                                                
The value returning procedure calls are transformed to C functions   
returning values.                                                    
-------------------------------------------------------------------
An SDL procedure can be called more than once. No conflicts occur if using a preemptive Cmicro Kernel.

Procedure Body

For each SDL procedure, there is one C function generated. The Procedure body can contain the same SDL actions as the process body. The same code generation is performed, with the exception of a few statements declaring temporary variables.

Within global procedures, no objects of the calling process can be used without declaring them via formal parameters. As another restriction, each output in a global procedure must be specified with to pid.

Channels and Signal Routes

No C code is generated for channels and signal routes, except the C comment, which tells the C reader the location of processes and their signal routes.

Functions to be Filled up by the User

This section deals with functions that must be adapted by the user, in order to connect the SDL system to the environment i.e. connection to target hardware, and the environment. If it is required to perform a tight integration of the Cmicro Library with a real time operating system, please ask your SDT distributor.

Implementation of Main () Function

In any case, the user must supply a main function body when it comes to target application. That is the reason, why no C function main is generated by the Cmicro Generator. Another reason is the flexibility in adapting different real-time operating systems (if there is one to be used for the micro controller).

To implement a first main function, is possible by simply writing:

Example 335   
main ()
{
  xmk_InitSDL ();
  xmk_RunSDL (0xff);
}
  
Of course, this example does nothing in order to start the Cmicro Tester. The only possibility to get a very simple trace output is to define:

#define XMK_ADD_PRINTF
e.g., in ml_mcf.h. This inserts the C function printf at some places in the generated C code and the Cmicro Library.

In order to implement a trace output, please view the subsection "Example to set Trace Options" on page 3055 in chapter 46, The Cmicro Tester.

Configurations / the File ml_mcf.h

This file is to be filled up by the user in order to do manual scalings, buffer dimensioning and to select conditional compilations. The different possibilities are described in

Integrating Hardware Drivers, Functions and Interrupts

There is no extra handling for hardware drivers, hardware functions and interrupt service routines. One interface is necessary to implement in the users application. Hardware drivers, hardware functions and interrupt service routines are seen from the SDL system as the environment. The user has to implement the interface between the SDL system and the environment, as it is described in the following subsections.

Critical Paths in the Cmicro Library

As with every real time application the Cmicro Library has to deal with critical paths.

Figure 581 : Critical paths. 
-----
(fig)  
       
-----
These are well defined in the source code using two macros namely XMK_BEGIN_CRITICAL_PATH and XMK_END_CRITICAL_PATH (see file ml_typ.h).

The macros are expanded to calls to the C functions enable and disable if the flag XMK_USE_IRQ is set. The calls are counted using an internal variable, thus after having called XMK_BEGIN_CRITICAL_PATH n-times XMK_END_CRITICAL_PATH has to be called n-times, too, to enable the interrupts again.

In the Cmicro Library only these macros are used to disable/enable interrupts. The application should take care not to handle interrupts without using these macros or at least evaluating the internal counter.

The C functions enable and disable can be found in the module mk_cpu.c and should be implemented according to the application's needs.

---------------------------------------------------------------------
Caution!                                                               
When it comes to implementing the interrupt handling routines it is    
of the greatest importance to know about the Cmicro Library's han      
dling of critical paths. Unpredictable results may result from a care  
less implementation!                                                   
---------------------------------------------------------------------

Initializing the Environment / the Interface to the Environment

There is one C function called xInitEnv available as a template in the mk_user.c module. The user should fill this module out appropriately, thus implementing connection to the environment (drivers, interrupt service routines and so on).

Receiving Signals from the Environment - xInEnv (), and Sending Signals into the SDL-System

There are several possibilities to send signals into the SDL system. In all cases, the user has to specify an SDL input symbol in the process, which has to consume the signal.

Alternative 1: Polling external events
This is done by the C function xInEnv, which is called
by the Cmicro Kernel after each transition.

Alternative 2: Directly sending signals into the SDL system, i.e. in an
Interrupt Service Routine (ISR), by using one of the
xmk_Send*( )-functions. These functions directly operate
on the SDL queue.

Important rule:

In any case, you have to include a header file containing the signal and process identifications in the module which exports xInEnv and
xOutEnv. Please view the subsection "Numbering SDL Objects by Hand" on page 2740.

Polling Signals from the Environment by Using xInEnv ()

In the case, where no ISR is available to handle an external event, the Cmicro Kernel can poll external events. You then have to use the C function xInEnv function in the mk_user module. For example, a hardware register can then be checked, in order to establish if its value has changed since the last call.

If an external signal is detected, then one of the xmk_Send* functions is to be called thus enabling the signal to be put into the SDL queue.

Example 336 : xInEnv()  
Assume, a hardware register, where the value 0 is the start-value, and where any other value means: data received. Two signals, namely REGISTER_TO_HIGH, and REGISTER_TO_LOW are to be defined in the SDL system, with a process receiving them. Then the user supplied C code should look like this:

void xInEnv (void)
{
  static xPID receiver_in_SDL=process_pid;
    /* the above variable is to be filled up by hand, if */
     /* possible, or by an signalling with the receiver of the */
    /* hardwaresignal.          */
    /* a process_pid is only available, if the receiver- */
    /* processtype has only 1 instance during runtime */
 static state = 0;    
    /* state, to detect changes in the hardwareregister */
    if ((state==0) && (hw_register != 0))
    {
    state   = 1;
    data_len   = 0;      /* type integer       */
         p_data   = (void *) NULL;    /* pointer to parameters, NULL here   */
    XMK_SEND_ENV (REGISTER_TO_HIGH, xDefaultPrioSignal, 
              data_len,
p_data, process_pid); /* It is also possible to give a higher */ /* priority here */ return; } if ((state==1) && (hw_register == 0)) { state = 0; data_len = 0;/* type integer */ p_data = (void *) NULL;/* pointer to parameters, here NULL */ XMK_SEND_ENV (REGISTER_TO_LOW, xDefaultPrioSignal, data_len,
p_data, process_pid); return; } return; } /* END OF SAMPLE */

Sending Signals into the SDL System by Using the xmk_Send*() Functions

It is possible to send signals directly into the SDL system by calling one of the C function xmk_Send*, no matter whether preemption is used or not. No conflict occurs, if an ISR uses a xmk_Send* function parallel to the C function xInEnv. Use the template in the previous subsection to see details how to use the xmk_Send* functions.

Sending Signals to the Environment -xOutEnv()

There are several possibilities to send signals to the environment:

Alternative 1:Using simple SDL output
The Cmicro Kernel is involved in the output operation.

Alternative 2:Using the #EXTSIG directive in the SDL output symbol
You can define your own output operation, like writing
to a register in a single in-line-assembler command.

Alternative 3:Using the #ALT directive in the SDL output symbol,
a variant of alternative 2

Alternative 1 is the most SDL like alternative, because it uses no non SDL constructs, like directives. This alternative should be selected, whereever possible, because it makes your diagrams more SDL conform and MSCs more readable.

Alternative 2 and 3 possibly are the more performant alternatives.

In the following, a way is described with alternative 1, because Alt.2/3 are already well described in the Cmicro Generator reference manual.

Each time, an SDL output of alternative 1 occurs, the Cmicro Kernel is called (C functions xmk_Send*). After performing some checks, the C function xOutEnv is called with all the parameters necessary to represent the signal, like receiver pid, priority, signal-ID, parameter length and a pointer to the parameter area.

The sender of the signal can be retrieved by the global variable xRunPID of the type xPID. Remember, in a system with only (x,1) process declarations, this pid represents the process type of the sender. In a system, where there is a minimum of one process declaration with (x, N), where N is >1, this pid represents the process type plus the process instance of the sender. Possibly it is required to make decisions depending on the sender of the signal. The user can evaluate the process type of the sender by using the C expression EPIDTYPE(xRunPID), i.e.:

Example 337 :Evaluating the Process Type  
unsigned char ptype;
ptype = EPIDTYPE(xRunPID);
  
Remember also, if it is required to signal to a specific pid in the environment, this requires a dynamic signalling, where a process in the environment establishes communication to a process in the system, or the other way around.

Normally, the destination of the receiver in the environment can be calculated from the id of the signal to be sent to the environment, in any case this is one of the simplest possibilities.

--------------------------------------------------------------------------
Note:                                                                       
If a signal with a given name exists at several channels / signal           
routes, and must also be sent to the environment, users must be             
aware to route it to the right receiver. The C function xOutEnv is          
called in any case, when a signal is to be sent, either internally, or to   
the environment. So, the user must take care to select the right re         
ceiver, by comparing the receiver id. Another possibility is to make        
signal names always unique for the whole SDL system.                        
--------------------------------------------------------------------------
If the signal to be sent to the environment contains parameters, it is then necessary to copy these parameters to the data area of the environment, see the example following.

-------------------------------------------------------------------
Note:                                                                
If interprocessorcommunication is to be performed, the user has to   
define a unique protocol between the communicating processors, or    
use an existing one, like ASN.1 and the Basic Encoding Rules         
(BER). In small applications with a restricted range, it might be    
enough to copy C structures, but mostly, this causes the first prob  
lems, when it comes to redesigning the hardware.                     
-------------------------------------------------------------------
In any case, a header file is to be included containing the signal and process identifications in the module which exports xInEnv and xOutEnv. Please view the subsection "Numbering SDL Objects by Hand" on page 2740.

Assume, for example, a process, which has to send a signal with parameters to the environment. The code, you then have to write into the mk_user- module, looks as follows:

Example 338 : xOutEnv()   
int xOutEnv    (xmk_T_SIGNAL  sig,
xmk_T_PRIO prio,
unsigned char data_len,
void *p_data,
xPID Receiver ) { int result = XMK_FALSE; switch (sig) { case SDL_Signal1 : /* Declaring a pointer to parameters */ ySig_SDL_Signal1 *p_signal1_parameters; p_signal1_parameters = (ySig_SDL_Signal1 *) p_data; /* define dest as a variable i.e.of type ySig_SDL_Signal1 */ /* to make it accessible in the environment, and perform */ /* the following default-setting of dest */ memset (dest, 0, sizeof (dest_type)); /* You must copy the signal parameters, i.e. */ /* copying simple values looks like : */ dest.p1 = p_signal_parameters->p1; dest.p2 = p_signal_parameters->p2; /* copying an inner structure or array looks like : */ /* ensure, if to use & or not : */ memcpy ([&] dest.pm, p_signal_parameters->pm,
sizeof(dest.pm)); /* do this for all parameters of the signal .... */ dest.pN = p_signal_parameters->pN; result = XMK_TRUE; break ; case SDL_Signal2 : result = XMK_TRUE; break ; default : result = XMK_FALSE; /* to tell the caller that the */ /* signal is NOT consumed, but is to * /* be handled by */ /* the Cmicro Kernel ... */ break ; } /* end of switch */ return (result); /* Note : Freeing of the signal takes place in
/* in the CmicroKernel */ /* Signalparameters are no longer valid
/* after returning from xOutEnv. */ } /* END OF SAMPLE */

Closing the Environment / the Interface to the Environment

There is one C function called xCloseEnv available as a template in the mk_user.c module. The user should fill this module out appropriately, thus realizing disconnection from the environment (drivers, interrupt service routines and so on). Disconnection can make sense if a reinitialization or a software reset is to be implemented.

The SDL_Halt () function is mapped to xCloseEnv () in Cmicro.

User defined Actions for System Errors - the ErrorHandler ()

Errors, warnings and information can be generated and detected in many places and situations during the lifetime of a SDL system. By fully utilizing the Analyzer several dynamic error sources can be eliminated at the design stage of development.

Some errors or warnings go undetectable by the Analyzer, for example resource errors or real time errors such as memory, performance, or illogical use of SDL.

These errors and warnings are detectable by the Cmicro Kernel and the Cmicro Tester. For a complete list of errors, warnings and information, please view the following subsection "List of Dynamic Errors and Warnings" on page 2770.

For each error and warning, there should be an appropriate reaction in the function ErrorHandler in the mk_user-module. Errors are numbered easily by an integer value. If your target allows the use of printf, then use the C function xmk_err_text contained in the ml_err-module. It is easier to specify error handling in this module rather than directly modifying the ErrorHandler function.

Example 339 : ErrorHandler  
void ErrorHandler ( int ErrorNo ) 
{
    /* I.E.implement the 3 functions 
fatalerror,warning,and
/*information */ switch (ErrNo) { case ERR_N_UNKNOWN :fatalerror (ErrNo); break; case ..... ..... default :warning(ERR_N_UNKNOWN); break; } } /* END OF SAMPLE */

List of Dynamic Errors and Warnings

Cmicro Kernel Errors (ERR_N_*)

ERR_N_NO_FREE_SIGNAL

The output operation fails. This happens if no free entry exists in the queue to insert the signal header of the current signal to be sent.

ERR_N_PARAMETER_MEM_ALLOC

The output operation fails as a signal with parameters is to be sent but not enough free memory is available for allocation of the signal parameters.

ERR_N_SEND_TO_NULLPID

An SDL-application tries to send to a null-PID. This case normally cannot arise as the Analyzer performs appropriate checks in the dynamic analyses pass. If it occurs, it is most probably so that either something is wrong with the environment signalling, or possibly with initialization of pid-variables.

ERR_N_PID_INDEX

The Cmicro Kernel uses pids as index values. Each SDL process in the generated system is numbered by a systemwide unique number. There is an error detected, when the index is out of range. This problem most probably is in the environment, which tries to send to a non existing process.

ERR_N_xOutEnv

The C function xOutEnv does not handle all necessary signals. It should handle all signals, which are sent to the environment.

ERR_N_NO_REC_AVAIL

If you are using implicit addressing (output without to), and there are several possible receivers of one type, the Cmicro Kernel tries to assign one of them to this signal. This assignment may fail, if there is no possible receiver. If there is more than one, then the first one found will be used in the output of the C function xmk_Send*.

ERR_N_xRouteSignal

The function xRouteSignal, which is to be written by the user, when signals do not contain a receiver pid, detects an error or was not able to handle the current signal, which is to be routed. See chapter functions to be filled up by the users for more details.

ERR_N_SYSTEM_SIGNAL

This error can only happen, if a non specified system signal is sent. Internally, some signals are predefined as system signals. System signals are given priority treatment. For example, for the dynamic process creation, there is a system signal called XMK_CREATE_SIGNALID.
To prevent this error situation, it is strongly recommended not to send an SDL signal with equal or higher priority than that of a system signal (please see the subsection "Scheduling" on page 2749).

ERR_N_SDL_DISCARD

A signal was sent to a process not existing (either not yet created or already stopped). The signal is therefore discarded.

ERR_N_CREATE_INSTANCE

This error happens, if there is no dormant instance of a process type, which can be (re)used. The Cmicro Package uses fixed upper process instance limits (x, N), where N is to be specified as an integer value. In the C code, all the data of one process instance is represented by one element of an array of the size N.
The error occurs, if all instances (i.e. all array elements) of this process type are currently active and the parent tries to create another instance of that type.

ERR_N_CREATE_NO_MEM

This error can happen in the case of using dynamic process creation. When a parent process tries to create another process, the Cmicro Kernel tries to allocate an entry in the queue, for the insertion of an internal create signal.
The error occurs when full queue capacity has been reached.

ERR_N_NO_FREE_TIMER

The error occurs when an SDL-process tries to start an instance of a timer and either the timer is unknown, or there is no memory available to start a timer instance. To eliminate the first source of error check the SDL compilation. For the second case increase the memory assigned to timers.

ERR_N_PRD_VAR

This error occurs when it is not possible to allocate memory for one or more SDL procedure calls. The solution is either to reduce the procedure maximum nesting level, or to increase the available heap (malloc) memory.

ERR_N_NO_CONT_PRIO

This error occurs when process priorities are not numbered according to the rules of the preemptive Cmicro Kernel. The numbering must begin from zero incremented consecutively to an upper limit. All numbers between zero and the upper limit-1 are to be used within a #PRIO directive, no number may be omitted.

ERR_N_TRANS_TIME

The maximum execution time for one SDL-transition was exceeded. This error can only happen, if no preemption is used, and if the administration of the transition-execution-time is switched on. See the flag XMK_USE_CHECK_TRANS_TIME.

ERR_N_DIVIDE_BY_ZERO

A division by zero has been detected in the generated SDL code, which is an SDL user error. Possibly, it is helpful to produce an execution trace to localize the error. Normally, it is possible to find such problems within the simulation.

ERR_N_EMPTY_CHARSTRING

An attempt was made to access a non existing element within an SDL charstring.

ERR_N_ERROR_CHARSTRING

An attempt was made to access a non existing element within an SDL charstring.

ERR_N_FATAL_CHARSTRING

An attempt was made to access a non existing element within an SDL charstring or an empty charstring.

ERR_N_UNDEFINED_ERROR

This error is implemented to serve the C-switch statement in use with a default branch. It shouldn't occur during system execution.

Errors of the Cmicro Tester (ERR_N_*)

ERR_N_INDEX_SIGNAL

Under normal circumstances this error should not occur. It is an error detected by the Cmicro Tester when a signal id is out of range. This is only used, if signal trace options are modified or asked for.

ERR_N_ILLEGAL_CMD

An illegal command was sent to the Cmicro Tester command interface module. This error situation arises due to careless implementation of the function interface and should not occur under normal circumstances.

ERR_N_TESTER_MESSAGE

An illegal message was sent to the Cmicro Tester, and it is not able to decode the message. A possible error source is an inconsistency in the underlaying protocol on the communications interface.

ERR_N_LINK_SYNC

It was not possible to receive the sync byte of the data link frame of the Cmicro Protocol.

ERR_N_LINK_DEST_BUFFER

A message which is to be decoded, is too large for the destination buffer. Possible error sources are an inconsistency in the data definition or the length information received is wrong.

ERR_N_LINK_ENC_LENGTH

An attempt was made to send more than the allowed maximum amount of bytes.

ERR_N_LINK_ENC_MEMORY

There is not enough, or no free memory to encode a data link frame of the Cmicro Protocol.

ERR_N_LINK_NOT_IMPL

A not implemented feature of the data link has been used, for example an attempt to send more than the maximum amount of allowed bytes.

ERR_N_DATA_LINK

There is an error on the data link detected.

ERR_N_DECODE_METHOD

There is no decoding method defined for a given frame of the Cmicro Protocol.

ERR_N_RING_WRITE_LENGTH

There is a ring buffer overflow detected in the data link module.

Structure of Generated C-Code

This section gives an overview of the code generated by the Cmicro Generator. 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 executables.

Figure 582 Structure of the generated C code 
-----
(fig)  
       
-----
.All intricate details of the generated code are not 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 Generator (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_).

-------------------------------------------------------------------
Note:                                                                
Generically speaking, the ordering of the following subsections cor  
responds 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.

Include Files

Code generation on the .c file for the current unit is started by generating the following include statements

Example 340   
/* Program generated by Micro Generator, version x.x */
#define MICRO_C_x_x
  #include "sdl_cfg.h"
  #include "ml_typ.h"
  

SDL Data Definitions and #CODE (#TYPE section)

Newtype, Syntype, Synonym and #CODE (#TYPE section)

Synonyms Translated to Macros

For each synonym definition that can be translated to a macro (predefined data type and computable at code generation time) the following code is generated:

#define SynonymName SynonymValue

Typedefinitions of Abstract Data Types and #CODE (#TYPE Section)

Please refer to the Master Library reference manual in order to get details about this item.

Function headings from Abstract data types

The unit is scanned for Newtypes and Syntypes. In the order the types are found the following is generated:

  1. The #HEADING section in the #ADT directive is copied.
  2. Help function headings and some macros. Examples:
extern void yAss_TypeName
  XPP(( TypeName *, TypeName , int ));
extern void yDef_TypeName  XPP(( TypeName * ));
#define yDef_TypeName1(yVar) \
   *(yVar) = DefaultExpression;
#define yDef_TypeName2(yVar) \
   yDef_TypeName3(yVar)
The first macro is used in most circumstances, and the second is used for a syntype, without default value, of a structured type. In this case the default function for the base type is reused.
extern char * yWri_TypeName XPP(( void * ));
extern int yRead_TypeName XPP(( void * ));
extern SDL_Boolean yEq_TypeName
  XPP(( TypeName, TypeName ));
extern TypeName yMake_TypeName
  XPP(( ComponentTypeName ));
extern TypeName yMake_TypeName
  XPP(( Component1TypeName,
        Component2TypeName ))
#ifdef XTESTF
extern xbool  yTest_TypeName  XPP(( TypeName ));
#endif
#ifdef XERANGE
extern TypeName  yTstA_TypeName XPP(( TypeName ));
#else
#define yTstA_TypeName(yExpr)  yExpr
#endif
#ifdef XEINDEX
extern TypeName  yTstI_TypeName XPP(( TypeName ));
#else
#define yTstI_TypeName(yExpr)  yExpr
#endif
The yTstA_TypeName and yTstI_TypeName are used to check the validity of an assignment to a syntype variable (yTstA_) and to check the validity of an index expression when indexing an array.
--------------------------------------------------------------------
Note:                                                                 
Note that the compilation flags XERANGE and XEINDEX determine if      
there should be test functions or if the macro versions, which only   
are substituted by the expression, should be used.                    
--------------------------------------------------------------------
The code for the yTstA_TypeName and yTstI_TypeName functions are shown in the subsection "Bodies from SDL Data Definitions" on page 2781 and their use is discussed in the subsection "Translation of SDL Expressions" on page 2809.
  1. If the type is a newtype, then literal function headings are generated.
    For each literal that should have a generated heading (type not translated to enum type):
extern TypeName  LiteralName XPP(( void ));

Synonym Variables

No synonym variables are generated by Cmicro.

System Data

Process and Procedure Variable Definitions and Signal Parameter Definitions

The Type yVDef_ProcessName

For each process and process type there will be a struct containing one component for each formal parameter (FPAR) and each variable (DCL).

For an exported variable there will be one extra component to represent the currently exported value.

There will also be a component for each type of expression that is used in decisions, except for the types Integer, Real, Boolean, Character, PId. Take, for example, a decision with a Charstring question:

DECISION CharstringVar;
  ('abc') : ...;
  ELSE : ...;
ENDDECISION;
then there will be a component where the question value can be stored. Together with the struct type there will also be a pointer type to the struct type. In the example below we assume that the process has two formal parameters, FPAR_var1 and FPAR_var2, two variables, DCL_var1 and DCL_var2, and a decision where the question type is TypeName5.

typedef struct {
    PROCESS_VARS
    TypeName1  FPAR_var1;
    TypeName2  FPAR_var2;
    TypeName3  DCL_var1;
    TypeName4  DCL_var2;
    TypeName5  yDcn_TypeName5;
} yVDef_ProcessName;
typedef yVDef_ProcessName  *yVDP_ProcessName;
In a process type, all variables, formal parameters, and so on, from the all the inherited process types are included in the struct above, starting from the top of the inheritance chain.

------------------------------------------------------------------
Note:                                                               
Note that fpars in create are not allowed in this Cmicro version.   
------------------------------------------------------------------

The Type yVDef_ProcedureName

For each procedure there will be a struct containing one component for each formal parameter (FPAR) and each variable (DCL). There will also be a component for each type of expression that is used in decisions, except for the types Integer, Real, Boolean, Character, PId. For a decision with a Charstring question:

DECISION CharstringVar;
  ('abc') : ...;
  ELSE : ...;
ENDDECISION;
then there will be a component where the question value can be stored. Together with the struct type there will also be a pointer type to the struct type

typedef struct {
    PROCEDURE_VARS
    TypeName1  FPAR_var1;
    TypeName2  *FPAR_var2;
    TypeName3  DCL_var1;
    TypeName4  DCL_var2;
    TypeName5  yDcn_TypeName5;
} yVDef_ProcedureName;
typedef yVDef_ProcedureName  *yVDP_ProcedureName;
where FPAR_var1 is assumed to be an in parameter, while FPAR_var2 is assumed to be an in/out parameter. Note that an in/out parameter is represented as an address. In a procedure, all variables, formal parameters, and decision variables, are included in the struct above.

Symbol Table Variables

Symbol tables are only generated for the Cmicro Tester. No symbol tables are generated for the Cmicro Kernel itself. The symbol tables generated for the Cmicro Tester are described within the Cmicro Testers reference manual.

External References

As Cmicro uses initialization only within the start transitions of processes, there is no need to generate yInit_UnitName C functions. An exception is the generation of the C function yInit in the case of a specific use of SDL synonyms.

#CODE (#HEADING and #BODY) and System Data

All #CODE directives (among declarations) are scanned in their relative order and the #BODY sections are copied.

Bodies from SDL Data Definitions

The unit is scanned for Newtypes and Syntypes. In the order the types are found the following is generated.

Example of generated code for a struct called struct1 with two integer components a and b:

/*------------------DEFAULT-----------------*/
#ifndef XNOPROTO
extern void yDef_z4_struct1(
  z4_struct1 *yVar )
#else
extern void yDef_z4_struct1( yVar )
  z4_struct1 *yVar;
#endif
{
  xDef_SDL_Integer(&((*yVar).a));
  xDef_SDL_Integer(&((*yVar).b));
}
/*------------------EQUAL-------------------*/
#ifndef XNOPROTO
extern SDL_Boolean yEq_z4_struct1(
  z4_struct1 yExpr1,
  z4_struct1 yExpr2 )
#else
extern SDL_Boolean yEq_z4_struct1( yExpr1, yExpr2 )
  z4_struct1 yExpr1, yExpr2;
#endif
{
  if ( yNEqF_SDL_Integer(yExpr1.a, yExpr2.a) )
    return SDL_False;
  if ( yNEqF_SDL_Integer(yExpr1.b, yExpr2.b) )
    return SDL_False;
  return SDL_True;
}
/*-------------------MAKE-------------------*/
#ifndef XNOPROTO
extern z4_struct1 yMake_z4_struct1(
  SDL_Integer ya,
  SDL_Integer yb )
#else
extern z4_struct1  yMake_z4_struct1( ya, yb )
  SDL_Integer ya;
  SDL_Integer yb;
#endif
{
  z4_struct1  yVar;
  memset((void *)(&yVar), 0, sizeof(z4_struct1));
  yAssF_SDL_Integer(yVar.a, ya, XASSMAKE);
  yAssF_SDL_Integer(yVar.b, yb, XASSMAKE);
  return yVar;
}
        /* #SDTREF(TEXT,mall.pr,7) */
COMMENT((This is the #body section))
First the SortIdNode for this newtype or syntype is declared. This is followed by the IdNodes for struct components or literals (if valid).

After that the help function bodies are generated.

#ifndef XNOPROTO
extern void yAss_TypeName (
  TypeName *yVar,
  TypeName  yExpr,
  int       AssType )
#else
extern void yAss_TypeName (yVar, yExpr, AssType)
  TypeName *yVar;
  TypeName  yExpr;
  int       AssType;
#endif
{
  code to perform assignment
}
#ifndef XNOPROTO
extern void yDef_TypeName( TypeName *yVar )
#else
extern void yDef_TypeName( yVar )
  TypeName  *yVar;
#endif
{
  code to assign the default value to
  variable yVar
}
#ifndef XNOPROTO
extern SDL_Boolean yEq_TypeName(
  TypeName yExpr1, TypeName yExpr2 )
#else
extern SDL_Boolean yEq_TypeName
  ( yExpr1, yExpr2 )
  TypeName  yExpr1, yExpr2;
#endif
{
  code to check if yExpr1 and yExpr2 are
  equal
}
#ifndef XNOPROTO
extern TypeName  yMake_TypeName(
  ComponentTypeName yExpr)
#else
extern TypeName  yMake_TypeName( yExpr )
  ComponentTypeName yExpr;
#endif
{
  code to return an array with all components 
  equal to yExpr
}
#ifndef XNOPROTO
extern TypeName  yMake_TypeName(
  Component1TypeName  yComponent1,
  Component2TypeName  yComponent2 )
#else
extern TypeName  yMake_TypeName
  ( yComponent1,yComponent2 )
  Component1TypeName  yComponent1;
  Component2TypeName  yComponent2;
#endif
{
  code to return a struct with value
  according to the parameters
}
#ifdef XTESTF
#ifndef XNOPROTO
extern xbool yTest_TypeName(TypeName yExpr)
#else
extern xbool yTest_TypeName( yExpr )
  TypeName  yExpr;
{
  code to check if yExpr is in the range
  conditions for this newtype or syntype
}
#endif
#ifdef XERANGE
#ifndef XNOPROTO
extern TypeName  yTstA_TypeName(TypeName yExpr )
#else
extern TypeName  yTstA_TypeName( yExpr )
  TypeName  yExpr;
#endif
{
  if (! yTest_TypeName(yExpr) ) {
    xErrorSubrange(ySrtN_TypeName,
      xWriteSort(&yExpr, ySrtN_TypeName));
  return yExpr;
}
#endif
#ifdef XEINDEX
#ifndef XNOPROTO
extern TypeName  yTstI_TypeName(TypeName yExpr )
#else
extern TypeName  yTstI_TypeName(  yExpr )
  TypeName  yExpr;
#endif
{
  if (! yTest_TypeName(yExpr) ) {
    xErrorIndex(ySrtN_TypeName,
      xWriteSort(&yExpr, ySrtN_TypeName));
    return lowest value of type;
  }
  return yExpr;
}
#endif
  1. The #BODY section in the #ADT directive is copied.
  2. If the type is a newtype then the literal function bodies of the literals that should have question functions are generated. Code is generated for each operator or literal according to the example below, where the code for an operator with two parameters is shown. A literal is treated as an operator without parameters.
Example 341 :   
#ifndef XNOPROTO
extern ResultTypeName  OperatorName(
  ParameterType1 yParam1, 
  ParameterType2 yParam2 )
#else
extern ResultTypeName  OperatorName
  (yParam1, yParam2)
  ParameterType1 yParam1;
  ParameterType2 yParam2;
#endif
{
  ResultTypeName  Result;
  xPrintString(
    "Operator xx in sort xx is called\n");
  xPrintOpParameter("Parameter 1: %s\n",
    &yParam1, ySrtN_ParameterType1);
  xPrintOpParameter("Parameter 2: %s\n",
    &yParam2, ySrtN_ParameterType2);
  if (! xReadOperator((void *)&Result,
            ySrtN_ResultTypeName))
    yDef_ResultTypeName(&Result);
  return Result;
}
  

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 (= 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.

Figure 583 : Root process table 
-----
(fig)  
       
-----
Example 342 : 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     */
C-Constants (sdl_cfg.h)

  #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-1
C 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 Cmicro Tester to store and retrieve test options, like switches, which define the trace.

The table is conditionally compiled, and only included, if the Cmicro Tester is contained in the target- executable.

The symbol trace table looks like:

Example 343 : Code for Symbol Trace Table  
/*************************************************************
**  Symbol trace table
*************************************************************/
#ifdef XMK_ADD_TEST_OPTIONS
XSYMTRACETBL *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   */
};
#endif
  
More information can be obtained by reading chapter 46, The Cmicro Tester.

Root-Timer Table for Timer Model 2

The following table is only generated, if timer model 2 is required.

-------------------------------------------------------------------
Note:                                                                
Timer model 2 is not contained in this version of Cmicro Package.    
Therefore the use of timers in this version is restricted to Timer   
model 1.                                                             
-------------------------------------------------------------------
Example 344   
C Type Definition (ml_typ.h)

#ifdef  XMK_USE_TIMER_ROM_TABLE
  typedef struct _XTIMER_ROM_TABLE_ENTRY
    {
      xPID                Ownerprocess;
      xmk_T_SIGNAL      timer_id;
      unsigned long     timer_startval;
      unsigned int      offset;
    } XTIMER_ROM_TABLE_ENTRY ;
  #define XDEFTIMER_ROM_TABLE_ENTRY(a,b,c,d) \
    a, b, c, d,
  #define X_END_TIMER_ROM  (xPID) 0xff
  #define MAXN  1
#endif /* ... XMK_USE_TIMER_ROM_TABLE */
C Code Generation for the whole system:

/*-------------Timer ROM table--------------*/
#ifdef XMK_USE_TIMER_ROM_TABLE
XCONST XTIMER_ROM_TABLE_ENTRY 
xTimerRomTable[MAX_SDL_TIMER_TYPES+MAXN] =
{
    X_END_TIMER_ROM
};
#endif
/*-------------Timer RAM table--------------*/
#define MAX_SDL_TIMER_INSTS 0
#ifdef XMK_USE_TIMER_RAM_TABLE
  XTIMER_RAM_TABLE_ENTRY
xTimerRamTable[MAX_SDL_TIMER_INSTS+MAXI]; #endif

Instance-Data-Struct

The struct is generated in the header-section of the generated C-file.

Example 345 : 
Code Generation of type definition for each SDL process typedef struct { PROCESS_VARS TypeName1 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:

Example 346 :   
#define X_MAX_INST_ProcessName   upperlimitofprocessinstances1
static 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" on page 2792.

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 347 : 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.

  
Example 348 : 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" on page 2792.

Transition Table

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 349 : 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;
C-Codegeneration

  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.

Where the C-define

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.

And where:

#define XASTERISK     -1
#define XSAVEID       xSave
  
A reference to this table is created in the "Process Description Table" on page 2792.

State Index Table

Is generated in the header-section of the generated C-file.

Example 350 : Code for State Index Table  
C-Typedef (ml_typ.h):

  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 351 : Code for PID Table  
C-Type definition (ml_typ.h)

#ifdef XMK_USE_PID_ADDRESSING
  typedef struct
  {
      #ifdef XMK_USE_SDL_PARENT
        xPID            Parent;
      #endif
      #ifdef XMK_USE_SDL_OFFSPRING
        xPID            Offspring;
      #endif
  } xPIDTable;
#endif
C-Code generation for each process:

/*-----------Process-PID-Values-------------*/
#ifdef XMK_USE_PID_ADDRESSING
  static xPIDTable yPID_TBL_z00_P1[X_MAX_INST_z00_P1];
#endif
  
A reference to this table is created in the Process Description Table, which is discussed in the subsection "Process Description Table" on page 2792.

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:

Figure 584 : Process Description Table 
-----
(fig)  
       
-----
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 352 : Code for Process Description Table  
C-Typedef for the process description table (ml_typ.h)

typedef struct {
  #ifdef XMK_USE_PID_ADDRESSING
    xPIDTable      *pPIDTable;   /* Table with */
/* Parent/OffspringValues */ #endif xINSTD *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 */ #endif xmk_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   1
    xPDTBL   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 SDT Standard C code generator, although some modifications are evident.

Procedures follow the same codegeneration 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 353 : yPAD_ProcessName ()  
/* Function for process ProcessName */
#ifndef XNOPROTO
extern YPAD_RESULT_TYPE yPAD_ProcessName ( YPAD_ANSI_PARAM )
#else
extern YPAD_RESULT_TYPE yPAD_ProcessName ( YPAD_KR_PARAM )
  YPAD_KR_DEF
#endif
{
    local variable section
    State-input-selection
    {
        start-transition including nextstate
        transition-1 including nextstate
        transition-2 including nextstate
        .......
        transition-n including nextstate
    }
    pad-end-section
}
/* Function for procedure ProcedureName */
#ifndef XNOPROTO
extern YPRD_RESULT_TYPE yPAD_ProcedureName ( YPRD_ANSI_PARAM )
#else
extern YPRD_RESULT_TYPE yPAD_ProcedureName ( YPRD_KR_PARAM )
  YPRD_KR_DEF
#endif
{
    local variable section
  section representing procedure body
  }
  

Local Variables Section

The following defines are generated in the local variables section for processes

Example 354   
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_YSVARP                     /* used for signal variable pointers   */
YPAD_YVARP(yVDef_znnn_ProcessName)
                       /* used for process variables */ 
YPRD_YVARP(yVDef_znnn_ProcedureName)                          
                                /* used for procedure variables    */         
YPRD_TEMP_VARS                  /* used for temporary variables   */
YPRDNAME_VAR("P1")            /* can be used for printf     */
After expansion by the C-Preprocessor:

extern void  znn_ProcedureName ( unsigned char * _xxptr )
{
  yVDef_znn_ProcedureName * yVarP =(yVDef_ProcedureName *)     
pRunData;
  unsigned char           * yOutputSignal;
  yVDef_znn_ProcedureName * yPrdVarP=(yVDef_znn_ProcedureName 
*) _xxptr ;
  SDL_Boolean               yDcn_SDL_Boolean ;
  (void) printf ("PROCEDURE %s\n", "ProcedureName"); ;  ;
  .....
}
  

Section Handling Procedure Calls

This section is used within SDT to handle SDL procedures with states. No corresponding section does exists here as SDL procedures with states are not supported by the Cmicro Package.

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. By 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-transition
      nextstate;
  case 1:  transition-1 
      nextstate;
}
After precompiling it:

switch (_xSymbolNumber_ ) 
{
  .....
}

Start Transition

The start transition is generated 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.

---------------------------------------------------------------
Note:                                                            
FPARS in dynamic process creation are not contained in this ver  
sion 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" on page 2799 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.

----------------------------------------------------------------------
Note:                                                                   
Some compilers produce a warning, if there is no return at the end      
of the yPAD function, other compilers produce a warning "unreach        
able code", if there is a return at the end of the yPAD function. For   
this reason, a function returning macro END_PAD exists which can be     
expanded in accordance with the particular compiler used.               
----------------------------------------------------------------------

Translation of Actions

The following actions (+label) are treated: Task, Output, Create, Decision, Set, Reset, Timer Active, Nextstate, Join, Stop, and Label.

The following actions are not contained in this version of the Cmicro Package:

Call, Export Return.

Translation of Task

The assignment statements in SDL are translated as assignments in C, while informal text in a task is ignored (except in trace). The following structure is generated:

  #ifdef XTRACE                                              
    xTraceTask("VariableName := ...");
  #endif
If the task contains informal text, the string is equal to the first informal text. If the task contains a #ID directive, the string contains the string specified in the directive.

After dealing with trace, the assignments and #CODE directives are handled in the order of occurrence. An SDL assignment is translated to an assignment in C or to a call of an assignment function, depending on the expression type.

Translation of Output

SDL output statements are translated to the following basic structure:

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 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 SDT to modify outputs, are discussed in chapter 44, The Cmicro Generator, please view the subsection "Modifying Outputs - Directive #EXTSIG, #ALT, #TRANSFER" on page 2687.

The other different output situations, which are handled, will be described in the next subsections.

Output without to and without via

If you specify output SignalName without to and via in SDL, the Cmicro Generator calculates the receiver of the signal. It is also possible to have more than one receiver for the signal. During execution time, any of the living possible receivers will be selected, or, 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")
-----------------------------------------------------------------
Note:                                                              
The ppp above stands for either PAR or NPAR for a Signal with or   
without parameters.                                                
-----------------------------------------------------------------
After expansion, you 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 doesn't 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 some...
SDL_OUTP_ppp_ENV  (Priority, 
                         SignalNamewithoutPrefix,
                         SignalNamewithPrefix,
                         ENV,
                         SignalParameterTypeStructureName,
                         "SignalNamewithoutPrefix") 
-----------------------------------------------------------------
Note:                                                              
The ppp above stands for either PAR or NPAR for a Signal with or   
without parameters.                                                
-----------------------------------------------------------------
After expansion, you 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: output SignalName to pid in SDL, the Cmicro Generator 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") 
-----------------------------------------------------------------
Note:                                                              
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 Generator 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

Translation 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);
-----------------------------------------------------------------
Note:                                                              
The ppp above stands for either PAR or NPAR for a Signal with or   
without parameters.                                                
-----------------------------------------------------------------
PriorityofCreatedProcess is generated as
xDefaultPrioProcess, if no priority is specified with #PRIO.

Translation of Decision

A decision is translated to an if statement. If the decision is of the boolean sort, then the following structure is generated:

#ifdef XTRACE
  xDcn_SDL_Boolean = QuestionExpression;
  xTraceDecision (&(xDcn_SDL_Boolean), 
xSrtN_SDL_Boolean);
  if (xDcn_SDL_Boolean)
#else
  if (QuestionExpression)
#endif
  ....
} else {
  ....
}

Translation for Timer Model 1

Translation of Set

The translation of set is, in order to produce effective code for a micro controller, restricted in a few areas. 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.

Example 355   
If the following is specified in SDL-PR:
Timer TimerName;
  ......
  ......
Set (now + durationvalue, TimerName) ;
or,
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")
  
Example 356   
If the following is specified in SDL-PR:
Timer TimerName := TimerGroundValue ;  ---> see Note below !
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). 
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);
#define SDL_SET_TICKS(TIME_EXPR, DUR_EXPR, TIMER_NAME, 
        TIMER_IDNODE, TIMER_VAR, TIMER_NAME_STRING) \
xmk_TimerSet(TIME_EXPR,TIMER_IDNODE);
  
Restrictions in the use of timers

set (now + 5.5, TimerName)
 
is not allowed (the real part is discarded i.e. 5.5 (= 5).
Translation of Reset

If you specify 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 then to xmk_TimerReset (TimerNamewithPrefix).

-----------------------------------------
Note:                                      
Timers with parameters are not supported.  
-----------------------------------------

Translation for Timer Model 2

The timer model 2 is not contained in this version of the Cmicro Package.

Translation of Export

Export is not supported.

Translation of Call

As SDL procedures are implemented with the restrictions already mentioned within the Cmicro Generators manual, 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:

Example 357 : Procedure Call  
TASK i := (call p(1)) + (call Q(i,k));
is translated to something like:
i = p(1) + Q(i,k);
  
-------------------------------------------------------------------
Note:                                                                
The value 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:

SDL_NEXTSTATE(State1, z000_State1, "State1")
after preprocessing:
return (z000_State1);
SDL_DASH_NEXTSTATE
which is defined as:
return (XDASHSTATE);

Translation of Join

A join is translated as a goto in C:

goto L_LabelName

Translation of Stop

A stop action is translated to:

SDL_STOP
which is defined as

return (XDORMANT);
which is most code saving. The Cmicro Kernel then enters the new state value into the Process State Table.

-------------------------------------------------------------------------
Note:                                                                      
This table contains ordinary SDL state values as well as the values        
XSTARTUP and XDORMANT. XSTARTUP is generated for each in                   
stance, 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 in      
stance as sleeping. In the case of creation this instance can be reused.   
-------------------------------------------------------------------------

Translation of Return

#ifdef XFREEVARS
  FREE_PROCESS_VARS ()
#endif
SDL_RETURN
The macro definitions are:

#define SDL_RETURN \
        if (_xxptr != (unsigned char*) NULL) \
        { \
          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 Label

An SDL label is simply translated to a C label. The C name will be L_SDLLabelName.

Translation of SDL Expressions

In this section some of the translation rules for expressions are described. For more information see chapter 44, The Cmicro Generator, where, for example, the translation rules for literals and operators in the predefined abstract data types are given.

Subrange Variable

If an expression is assigned to a subrange variable (in a task, input, output,...) a test function is generated to check the consistency of the value:

yTstA_TypeName(Expression)
where yTstA_TypeName is either a consistency check function or a macro that replaces the macro call by only the expression itself.

Index in Array

If an expression is used as index expression of an array, yTstI_TypeName is used in exactly the same way to check the consistency of the index expression.

SDL Variable

An SDL variable is represented in C by:

yVarP->VariableName1
yPrdVarP->VariableName2
((yVDP_ProcedureName)VarP->ActivePrd
  ->StaticFather)->VariableName3
(*(yPrdVarP->VariableName4))
The examples are:

  1. Reference to a process variable from the process or from a called procedure.
  2. Reference to a local variable or formal IN parameter from the procedure.
  3. Reference to a variable declared one static level above the one accessing the variable. The number of
    ->StaticFather determines the difference in declaration levels.
  4. Reference to a formal IN/OUT parameter from the procedure.

View

A VIEW expression is translated to a macro call SDL_VIEW.This is later expanded to a function call of SDL_View.

(*(SDL_Integer *)SDL_VIEW(SDL_PARENT,
  (xbool)1, "revVar", (xViewListRec *)
    &(((xBlockIdNode)XNAMENODE->
    Parent)->ViewList[yView_z_predefined_6_revVar]),
  sizeof(SDL_Integer)))

Import

Import is not supported from the Cmicro Package.

Now

SDL now is translated to the macro SDL_NOW which is expanded to the C function xmk_NOW which 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
#endif
All 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)
which is expanded to:

xmk_TimerActive(TimerName)
A conditional expression in SDL is translated to a conditional expression in C.

Init Function

An explicit initialization function is generated by the Cmicro Generator not 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 := /*#CODE anyUserFunction () */
The following C code is then generated within the C function yInit:

yInit is called by the Cmicro Kernel, if the define

XMK_USED_INITFUNC
is generated into the file sdl_cfg.h.

Building the Symbol Table

No symbol table is built by the Cmicro Generator into C code. This is to downsize the target code.

A symbol table is necessary for the Cmicro Tester running on the host or the development system.

For more information consult chapter 46, The Cmicro Tester.

---------------------------------------------------------------------
Note:                                                                  
Possible SDL objects in this context are: process types, signals, tim  
ers, process states.                                                   
---------------------------------------------------------------------

Initialization of Synonyms

The Cmicro Generator 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 Generator. This is absolutely unnecessary, because the main function always looks the same. Instead of an automatically generated main function, the user must supply the function body of main. Guidelines can be found under "Implementation of Main () Function" on page 2761.

Technical Data

These descriptions allow you to estimate the wanted resources for the target executable. The following items are described:

Allocating Dynamic Memory

Introduction

This chapter shows, if and how dynamic memory allocation is used in the Cmicro Package. It is shown,

The Cmicro Package uses a form of dynamic memory management for the following objects:

However, real dynamic memory management is used only in one case, namely for SDL signals, if a signal carries parameters with more than a few bytes.

This means, that the Cmicro Kernel has its own memory management to handle processes, signals, and timers. This is done in a way that each of these 3 objects are managed separately. For each of these 3 objects, a separate, fixed memory area is reserved during compilation time. I.e., the area to handle processes cannot be reused to handle timers. This seems to be a restriction, but in many micro controller applications, users have to fix an upper limit of processes, signals and timers, which can be handled in parallel during run time.

Processes

Processes are handled without malloc- and free functions. You have to specify an upper limit of process instances in the SDL diagram, separately for each SDL process. For each process instance, there is a variable, which is statically allocated.

Signals with and without Parameters

Signals, these are ordinary SDL signals, as well as timer signals (where timers are implemented without parameters), and can therefore be regarded as signals without parameters.

Timers

For timers, no malloc and free functions are used. The Cmicro Generator evaluates the amount of timers in the system and generates a C constant, which is then used in the Cmicro Kernel to define an array for timers.

Estimating the Required Memory

The RAM memory required for an application can be estimated if the maximum amount of processes, signals in the queue, timers, and variables is known. The ROM memory requirements for an application cannot be derived without programming and compiling the application, or having experience of a similar application. The ROM occupation from the Cmicro Library can be specified as a minimum and a maximum value for specific hardware.

The estimations made also depend on the target hardware. Microprocessors differ very strongly in the memory requirements for the program (code) (factor 2 is known) and the layout of variables (an integer sometimes is represented as 2 Bytes, but can sometimes be represented as 4 Bytes).

Another influencing factor is that it is not initially known, which language characteristics are to be used to implement the application. This is valid regardless of the implementation programming language.

Some threshold values are depicted in the following section.

The following values are measured with the MicroSoft C compiler version 8.0 for any 80x86 microprocessor, for a middle range SDL application with 15 processes.

ROM Occupation by the Generated Application without Cmicro Library Functions

RAM Occupation for the Generated Application without Cmicro Library Functions

For signals with more than 4 byte parameters, an additional memory block is allocated with the size of the parameter area.

ROM Occupation by the Functions and Tables of the Cmicro Library

The ROM occupation of the Cmicro Library is very strongly dependent on the automatic and manual scalings. The Cmicro Kernel uses between 1 Kilobyte to 8 Kilobyte on a 80x86.

Static RAM Occupation by the Functions and Tables of the Cmicro Library

For the non preemptive Cmicro Kernel:

For a Cmicro Kernel using preemption an additional static memory occupation of 8 Bytes to 16 Bytes in the scheduler per priority level applies.

Stack and dynamic RAM-occupation by the Cmicro Library

The Cmicro Kernel requires a stack of about 45 to 128 Bytes, no matter of it is scaled to preemption or not. If it is scaled to preemption, an additional stack occupation of about 14 to 28 bytes applies.

Performance

In this chapter, performance information over the Cmicro Kernel is given.

Observe the example within the section "Example of Generated C Code" on page 2850. The execution time for this example, is, measured on a SPARC-10:

26.2 seconds for 1.000.000 times ping-pong.
This means, that the time to handle 1 input and 1 output is about 13 microseconds.Or, in other words, in one second, it is possible to handle 77.000 signals.

When performed on a 80386-25 MHz DOS PC platform, using the DOS-command "time" the following performance results were recorded.

9 seconds for 30.000 times ping-pong.
The last performance measurement is more inaccurate, as DOS-interrupts cannot be excluded.

The following result was observed on a SPARC 10 platform with the example modified, so that 50 parameters were ping-ponged, where each parameter was an integer:

81.2 seconds for 1.000.000 times ping-pong.

Compilation Flags

Compilation flags are used to decide the properties of the Cmicro Library and the generated C code. Both in the Cmicro library and in the generated code #ifdefs are used to include or exclude parts of the code.

The switches used can be grouped:

  1. Flags, defining the compiler
  2. Flags, defining the properties of a compiler
  3. Flags, defining the properties of the Cmicro Library
  4. Flags, defining the implementation of a property
The first two groups are discussed in "Adaptation to compilers". The remaining two groups are discussed under "Manual scaling" and "Automatic scaling" in the following chapters.

Flag naming conventions:

Use the default settings of these flags in order to reduce potential problems.

Manual Scaling

Users are able to scale some features of the Cmicro Library and the Cmicro Kernel in order to optimize the generated code. All the flags discussed in this chapter are used throughout the complete SDL system, therefore it is not possible, to define flags for processes separately.

-------------------------------------------------
Note:                                              
You always have to generate the whole SDL-System.  
-------------------------------------------------

XMK_ADD_MICRO_TESTER (Cmicro Tester)

This is the main flag to enable and disable the Cmicro Tester. Use this flag, if you want to add features of the Cmicro Tester to the code. The following features are selected by this flag:

XMK_ADD_MICRO_COMMAND (Cmicro Tester)

This flag adds the command interface of the Cmicro Tester (please view chapter 46, The Cmicro Tester).

XMK_ADD_MICRO_TRACER (Cmicro Tester)

This flag enables the trace of the SDL execution and trace of system events to any device.

XMK_ADD_MICRO_RECORDER (Cmicro Tester)

This flag adds the functions of the record mode of the Cmicro Recorder (please view chapter 46, The Cmicro Tester).

XMK_ADD_MICRO_PLAY (Cmicro Tester)

This flag adds the functions of the play mode of the Cmicro Recorder (please view chapter 46, The Cmicro Tester).

XMK_ADD_MSCE_TRACE (Cmicro Tester)

This flag enables a static trace, as well as a dynamic trace with the SDT-MSC Editor. It is only to be set when compiling a host executable.

XMK_ADD_MSCE_TRACE_PARAMS (Cmicro Tester)

This flag enables the trace of variables on the SDT-MSC-Editor. It is only to be set when compiling a host executable.

XMK_ADD_NON_SDL_OPERATIONS (Cmicro Tester)

This flag adds more functions in the Cmicro Kernel, which are necessary to enable the debugging facilities of the Cmicro Tester.

XMK_ADD_PCO_CONTROLER (Cmicro Tester)

This flag adds the functionality of the PCO controller to the Cmicro Tester (see the Cmicro Tester Reference manual).

Not included in this version of the Cmicro Package.

XMK_ADD_TRACEBUF (Cmicro Tester)

If this flag is defined, a reduced ring buffer trace is done into the RAM. A few preparations are done only. The users must ensure the right amount of trace information.

XMK_ADD_PROFILE (Cmicro Tester)

This flag is to be defined, if the profiler is to be used. With the profiler, it is possible,

The profiler can be used independently from the Cmicro Tester functions. By using a debugger the following values may be inspected:-

int xmk_max_q_cnt,
this represents queue-dimensioning and

int xmk_act_q_cnt, 
this represents the maximum traffic load of the queue, at any time during the execution.

Default: Undefined.

XMK_USE_PREEMPTIVE (Cmicro Kernel)

Normally, the Cmicro Kernel is configured, so that the simple scheduling policy is used, i.e.transitions of SDL processes are not interruptible.

If you define XMK_USE_PREEMPTIVE, the Cmicro Kernel is configured, so that the preemptive scheduling policy is enabled. Each SDL process in the system is then interruptible, if for instance, an external signal is received from the environment, i.e.by means of an interrupt service routine. For a detailed description of what happens in this case see the chapters above.

Default: Not Defined.

XMK_USE_TIMESLICE (Cmicro Kernel)

Time slicing is not contained in this version of the Cmicro Package.

Normally, the Cmicro Kernel is configured, so that the simple scheduling policy is used, i.e.Transitions of SDL processes are not interruptible (neither XMK_USE_PREEMPTIVE, nor XMK_USE_TIMESLICE is defined).

If you define XMK_USE_TIMESLICE, the Cmicro Kernel is configured, so that the scheduling policy is scaled to preemptive time slicing.

It is also possible to combine preemption through process priorities with preemption through time slicing.

Default: Not Defined.

XMK_USE_xmk_SendSimple (Cmicro Kernel)

This flag enables the output C function xmk_SendSimple defined in the Cmicro Kernel. If the SDL system contains several signals without parameters and priorities, it is useful to set this flag in order to select the more optimal output C function xmk_SendSimple - in the Cmicro Kernel.

If neither XMK_USE_SEND nor XMK_USE_SENDSIMPLE is defined, a compilation error occurs in the standard Cmicro Package.

Default: Defined.

XMK_USE_xInitEnv (Cmicro Kernel)

This flag enables the C function xInitEnv which is given as a template in the mk_user module.

Default: Defined.

XMK_USE_xInEnv (Cmicro Kernel)

This flag enables the C function xInEnv which is given as a template in the mk_user module.

Default: Defined.

XMK_USE_xOutEnv (Cmicro Kernel)

This flag enables the C function xOutEnv which is given as a template in the mk_user module.

Default: Defined.

XMK_USE_xCloseEnv (Cmicro Kernel)

This flag enables the C function xCloseEnv which is given as a template in the mk_user module.

Default: Defined.

XMK_USE_SDL_SYSTEM_STOP (Cmicro Kernel)

Normally, it is unnecessary, to have an SDL system stop in microcontrollerapplications. An SDL system stop occurs, if no living process in the SDL system exists and all queues are empty. This occurs if all process instances have executed an SDL stop, and no create process action is open (create signal in any queue).

Defining XMK_USE_SDL_SYSTEM_STOP means, that the C-function main returns correctly with exit (...). To avoid this overhead in the Cmicro Kernel, the user should un-define the above flag.

Default: Defined.

XMK_USE_SIGNAL_PRIORITIES (Cmicro Kernel)

When this flag is defined the header of each signal, which is sent via the SDL queue, has an additional entry namely "priority". This is used to modify the ordering of signals in the queue.

This flag should be used in combination with using the #PRIO directive. It works for all the different scheduling policies.

Default: Undefined.

XMK_USE_SIGNAL_TIME_STAMP (Cmicro Kernel)

Defining this flag means, that in the header of each signal, which is sent via the SDL queue, there is an additional entry "timestamp". When using the standard Cmicro Library, the Cmicro Kernel sets the timestamp to NOW, if an SDL signal is inserted into the queue.

This timestamp is especially used by the Cmicro Recorder in order to enable the replay of an SDL session in simulated real-time.

In other cases, the user is free to modify the kind of timestamp implementation.

Default: Undefined.

XMK_USE_TIMER_MODEL1, XMK_USE_TIMER_MODEL2 (Cmicro Kernel)

One of the two timer models is to be selected in the Cmicro Library (Note: only timer model 1 is supported in this version of the Cmicro Library). When timers are used in an SDL system defining the appropriate flag selects the appropriate timer model. (Note the use of timers is automatically scaled by the flag XMK_USED_TIMER).

For a more detailed description see the section on translation of timer model 1/ timer model 2.

Default: Timer model 1 is defined.

XMK_USE_TIMER_RAM_TABLE / XMK_USE_TIMER_ROM_TABLE (Cmicro Kernel)

The flags are utilized for the implementation of timer model 2.
(Note: only timer model 1 is supported in this version of the Cmicro Library)

XMK_USE_ERR_CHECK (Cmicro Kernel)

When this flag is defined, additional error checks are contained in the generated code of the Cmicro Library. For further details see the appropriate section on "errors and warnings". For example the Cmicro Kernel calls the ErrorHandler, if a signal is sent to an undefined process
(i.e.undefined pid-value).

Default: Defined.

XMK_USE_NO_ERR_CHECK (Cmicro Kernel)

When this flag is defined, all error checks are excluded. It is recommended not to use this flag until the post testing phase of implementation, where it can be reasonably assumed that no errors remain. For further details see the appropriate section on "errors and warnings".

Default: Undefined.

XMK_USE_CHECK_TRANS_TIME (Cmicro Kernel)

When this flag is defined the time duration for each executed transition is checked against a predefined duration. If the executed duration is longer than the predefined duration set by the XMK_TRANS_TIME flag, the ErrorHandler is called. The flag is only available when using a non preemptive Cmicro Kernel. No additional hardware is necessary, as the evaluation is based on the SDL time value NOW, which is provided by the same hardware source as for the system clock.

Default: Undefined.

XMK_USE_COMMUNICATION (Cmicro Tester)

When this flag is defined, then a communications link exists as well on host as on target side in the compilation.

Default: Defined depending on the current configuration.

XMK_USE_CONFIG<nr> (Cmicro Tester)

This flag must be set to enable the Cmicro Tester. <nr> must be in the given range of 1 to 8 to implement a particular Cmicro Tester configuration. Under normal circumstances, XMK_USE_CONFIG5 must be defined, which enables a host-target communication.

Default: Undefined.

XMK_USE_CPU_IO (Cmicro Kernel)

This flag enables hardware dependent functions in the template of the module mk_cpu.[ch].

Default: Undefined.

XMK_USE_DISTRIBUTED (Cmicro Tester)

Defining this flag implements a Cmicro Tester host- target configuration. This flag should be used in combination either with XMK_USE_ON_HOST (ex-) or XMK_USE_ON_TARGET.

XMK_USE_DOUBLE_PRECISION (Cmicro Library)

When this flag is defined, then each SDL real value is translated to double in C. If it is not defined, Cmicro assumes SDL real values as C float values.

XMK_USE_HIGH_OPTIMIZATION (Cmicro Library)

When this flag is defined, some functions of the Cmicro Library concerning comfort or additional error handling are removed. It can be used to further reduce the size of the Cmicro Kernel.

XMK_USE_IRQ (Cmicro Kernel)

This flag should be defined, if enable and disable functions (which are used to lock critical pathes in the Cmicro Kernel) are to be compiled.

XMK_USE_KERNEL_INIT (Cmicro Kernel)

When this flag is defined, the Cmicro Kernel memsets all variables of an SDL process to 0, before the process is created. This is useful to spare some ROM memory, but has the disadvantage of a longer process creation phase. Especially the yDef_SDL_* functions can be spared in those cases, where the initialization with 0 is appropriate.

Default: Defined.

XMK_USE_KERNEL_WD_TRIGGER (Cmicro Kernel)

If this flag is defined the Cmicro Kernel calls a C function WatchdogTrigger before executing a transition. This function is present as a template in the Cmicro Library source files. Using WatchdogTrigger is only of value, when non preemptive scheduling is selected.

XMK_USE_LONG_INT (Cmicro Library)

By defining this switch, the SDL predefined sorts integer and natural are translated to long, else these are translated to int.

Default: Defined.

XMK_USE_ON_HOST (Cmicro Tester)

This flag is only applicable for a distributed configuration, i.e. when the host side of a host-target configuration is to be compiled. In this case, the flag XMK_USE_DISTRIBUTED must also be set.

Default: Defined, depending on the configuration selected with XMK_USE_CONFIG<nr>

XMK_USE_ON_TARGET (Cmicro Tester)

This flag is only applicable for a distributed configuration, i.e. if the target side of the host-target configuration is to be compiled. In this case, the flag XMK_USE_DISTRIBUTED must also be set.

Default: Defined, depending on the configuration selected with XMK_USE_CONFIG<nr>

XMK_USE_SDL_MEM (Cmicro Kernel)

If this flag is defined, then the Cmicro Kernel can use the dynamic memory management functions contained in the ml_mem - module (malloc and free). This is necessary, if the compiler in use has no malloc/free, or if the user wishes to modify the standard behavior of these functions, i.e. using a best fit, instead of first fit searching algorithm.

Default: Undefined.

XMK_USE_MemInit (Cmicro Kernel)

If this flag is defined, then the MemInit function of the mem module is compiled.

Default: Undefined.

XMK_USE_malloc (Cmicro Kernel)

If this flag is defined, then the malloc function of the mem module is compiled.

Default: Undefined.

XMK_USE_calloc (Cmicro Kernel)

If this flag is defined, then the calloc function of the mem module is compiled.

Default: Undefined.

XMK_USE_memshrink (Cmicro Kernel)

If this flag is defined, then the memshrink function of the mem module is compiled.

Default: Undefined.

XMK_USE_memset (Cmicro Kernel)

If this flag is defined, then the memset function of the mem module is compiled.

Default: Undefined.

XMK_USE_memcpy (Cmicro Kernel)

If this flag is defined, then the memcpy function of the mem module is compiled.

Default: Undefined.

XMK_IUSE_NON_SDL_OPERATIONS (Cmicro Kernel)

Defining this flag makes it possible to utilize functions, which are able to directly operate on variables, which are normally Cmicro Kernel exclusively. For example, functions to retrieve the current queue status, timer status, and SDL process status. These functions are useful for testing or debugging the code. For further details see section "List of non-SDL functions and operations" at the end of this reference manual.

Default: Undefined.

XMK_USE_BANKSW (Cmicro Kernel)

If this flag is defined, then the Cmicro Kernel uses a user defined macro to select a memory bank, before executing a transition, namely XMK_SWITCH_BANK.

Default: Undefined.

XMK_USE_RAM_OPT (Cmicro Kernel)

This flag defines that the Cmicro Kernel, were possible, works more sparingly on RAM than ROM. The flag has a lower priority than XMK_USE_ROM_OPT.

Default: Undefined.

XMK_USE_RECEIVER_PID_IN_SIGNAL (Cmicro Kernel)

When this flag is defined a receiver pid is included in each signal instance. It is possible to omit the receiver pid, if the user writes a C function xRouteSignal, which is given as a template in mk_user.c. Each signal type is then mapped to a unique receiver. It is recommended to define this flag in small systems, where unique receivers exist for each signal type. It is important to note that in the case of dynamically created processes an internal create signal is used. If there are any (x, N), N > 1, declarations in the system, the create signal cannot contain the receiver pid. The receiver pid is necessary for correct creation of processes, never leave it out using dynamic process creation.

Default: Undefined.

XMK_USE_SENDER_PID_IN_SIGNAL (Cmicro Kernel)

When this flag is defined a sender pid is included in each signal instance. It is possible to omit the sender pid, if the system contains no to sender or to parent addressing.

Default: Undefined.

XMK_USE_ROM_OPT (Cmicro Kernel)

This flag defines that the Cmicro Kernel, were possible, works more sparingly on ROM than RAM. The flag has higher priority than XMK_USE_RAM_OPT.

Default: Undefined.

XMK_USE_NO_AUTO_SCALING (Cmicro Kernel)

When this flag is defined automatic scaling of SDL features are prevented. Example of flag usage is implementing a change to the SDL system which doesn't require recompilation of the Cmicro Library. Note, if the amount of processes, signals or timers are changed the Cmicro Library must be recompiled. By defining this flag, the file "noscale.h" is included in ml_typ.h. The definitions contained there overwrite those in sdl_cfg.h.

Default: Undefined.

XMK_USE_OS_ENVIRONMENT (Cmicro Library)

The Cmicro Package is mainly intended for target implementation. However on some occasions OS features might wish to be used. By using this switch, int argc and char *argv [] are declared in the template C function main in order to give parameters to the implementation.

Default: Different for each compiler definition section.

XMK_USE_PID_ADDRESSING (Cmicro Kernel)

This flag will be automatically defined depending on whether direct PID addressing is used within the SDL system. The construct to PARENT exemplifies direct or explicit PID addressing.

Default: Defined when PID addressing is used in SDL.

XMK_USE_PRED (Cmicro Library)

When this flag is defined the predefined sorts section of the Cmicro library can be excluded. This exclusion should only be carried out when the SDL system contains no SDL data.

Default: Undefined.

XMK_ADD_STDIO (Cmicro Library)

The Cmicro Package is mainly intended for target implementation. However on some occasions OS features might wish to be used. Normally this flag is undefined when compiling for the target system, but may be defined if stdio is available and required on the target system.

Defining XMK_ADD_STDIO without setting XMK_ADD_PRINTF, allows the user to exclude the default printfs of the Cmicro Library, but implement user defined printfs.

Default: Defined

XMK_ADD_PRINTF (Cmicro Library)

When this flag is defined some additional printf C function calls are compiled giving users more information about the internal work of the system. The printf can be switched on separately for Cmicro Kernel, Cmicro Tester and SDL application. At a lower level, it can be switched on separately for each C module. Look to the defines in ml_typ.h, which all are named as XMK_ADD_PRINTF_*.

This flag must be undefined, when compiling into the target, except in the case, where there is a stdio implemented on the target, which is sometimes the case. For correct compilation, the user must also set XMK_ADD_STDIO. If the user wishes to implement user specific printf functionality then this flag need not be set.

Default: Defined.

XMK_ADD_SIGNAL_FILTER (Cmicro Tester)

This flag conditionally compiles the signal filtering mechanism of the Cmicro Tester (please view chapter 46, The Cmicro Tester).

Default: Defined, if Cmicro Tester enabled.

XMK_ADD_STDOUT_TRACE (Cmicro Tester)

This flag conditionally compiles trace on the screen.

Default: Defined, if Cmicro Tester enabled.

XMK_ADD_T<trace_event> (Cmicro Tester)

This flag conditionally compiles the trace of different SDL actions such as input, output etc., and system events such as priority level switching error handler calls etc.

<trace_event> is one of
CHECK_PARAMETERS, CREATE, DECISION,
DISCARD,DYNAMIC_CREATE etc...

The complete list is contained in the module ml_typ.h. All the flags are automatically set, if the Cmicro Tester is included. (please view chapter 46, The Cmicro Tester)

Default: Defined for enabled trace

XMK_IUSE_BUF

This flag conditionally compiles the buffering functions contained in ml_buf.[ch], which are primarily used for internal reasons but can be used by the user.

Default: Defined in some situations

XMK_IUSE_COD

This flag conditionally compiles the encoder / decoder functions contained in ml_cod.[ch], ml_enc.[ch] and ml_dec.[ch], which are primarily used for internal reasons but can be used by the user, too.

Default: Defined in some situations

XMK_IUSE_COM

This flag conditionally compiles the communications interface functions contained in ml_com.[ch] and ml_v24ux.[ch], which are used for host / target connection. The files only contain a template for a V.24 implementation.

Default: Defined in some situations

XMK_IUSE_DL

This flag conditionally compiles the data link functions of the communications interface contained in ml_dl.[ch], which are used for a host / target connection. The file only contains a template for a possible implementation using the buffer mechanisms in ml_buf.

Default: Defined in some situations

XMK_IUSE_FIL

This flag conditionally compiles the file handling functions contained in ml_fil.[ch], which are used for host / target connection and when compiling the host part.

Default: Defined in some situations

XMK_USE_CONFIG<nr> (Cmicro Tester)

This flag must be set to enable the Cmicro Tester. <nr> must be in the given range of 1 to 8 to implement a particular Cmicro Tester configuration. Under normal circumstances, XMK_USE_CONFIG5 must be defined, which enables a host-target communication.

Default: Undefined.

XMK_IUSE_ML_MON

This flag conditionally compiles the monitor functions (some additional printfs) contained in ml_mon.[ch], which are used in some cases.

Default: Defined in some cases.

XMK_IUSE_NO_KERNEL

This flag is not of common interest. It is set only when compiling a stand alone Cmicro Tester program.

Default: Defined in some cases.

XEDECISION

This flag defines, that an valid path exists for a SDL decision. If the flag is not set, the code to perform this check is left out. The flag may be left unset, if all decisions in the SDL system contains an else branch. However, if this cannot be ensured, the flag is to be set.

Default: Defined.

XERANGE/XTESTF

This flags define, that an SDL syntype is to be checked against its defined range. If the flags are not set, the code to perform this check is left out.

Default: Defined.

X_COMPACT_BOOL

This flag defines, that an SDL boolean is translated to char, when it is set. Otherwise each SDL boolean is translated to int.

Default: Defined.

Manual System Dimensioning

Although several properties of the Cmicro Library can be determined automatically from the SDL system, several properties remain undeterminable and therefore have to be explicitly defined by the user. The following section contains a description of flags that can be used to further scale the Cmicro Library.

XMK_MAX_SIGNALS (Cmicro Kernel)

In the Cmicro Package, the SDL queue is physically implemented as one queue for all processes. The define discussed in this section represents the maximum amount of signals in this queue. It may be difficult to evaluate the maximum entries wanted during run-time, because this fully depends on how the SDL system is specified, and target hardware performance. It is for example impossible to state how much time hardware requires to process an SDL signal.

One method is to use the Validator to calculate the maximum amount of entries in the queue. However the result can only be treated as an estimation, as the Validator uses a different scheduling policy than that of the Cmicro Kernel.

By examining the SDL system it can be determined which processes have a long transition time, and which processes send or receive more than one signal. Estimate by trying out worst case situations. A first estimation is also possible by calculating:

maximum amount of processinstances * 3
For a more exact estimation the user should use the profiler contained in the Cmicro Tester to obtain the necessary information on how many entries are used during run time.

Another method of helping to determine the maximum amount of signals required by the system is to use the exception handling mechanism offered by the ErrorHandler. i.e. when the queue is full, and another signal is to be inserted then the ErrorHandler function is called.

------------------------------------------------------------------
Note:                                                               
Using dynamic memory allocation does not prevent the user from      
estimating the required memory for the queue. Sooner or later prob  
lems arise (e.g. memory fragmentation), if dynamic memory man       
agement is used frequently. For this reason the Cmicro Package      
avoids where possible the use of dynamic memory management.         
------------------------------------------------------------------
Default: 20 entries.

Automatic Scaling

The flags described in this chapter are automatically generated by the Cmicro Generator. The purpose is to exclude parts of the C code in order to downsize the generated code. Features or functions, which are not required in the SDL description produce no (or only a small) overhead in the generated code.

If the user does not wish to employ automatic scaling facilities, for example, if test and debugging proves too difficult, then simply define the following flags as desired. This is possible if you use the separate header file"noscale.h" and define XMK_USE_NO_AUTO_SCALING.

All the flags discussed in this chapter are used on the whole SDL system i.e. it is not possible, to define flags for processes separately.

XMK_USED_ONLY_X_1 (Cmicro Library and Generated Code)

If this flag is generated as defined, then there is no process defined in the system, where N is > 1 in the process declaration (x, N). This allows memory to be saved as the overhead for process addressing in the system is reduced. The need for numbering of process instances is also eliminated.

XMK_USED_DYNAMIC_CREATE (Cmicro Kernel)

If this flag is generated as defined, the SDL system uses the dynamically created process feature of SDL. (It only requires one create-symbol in the SDL system to enable this flag to be set). This of course constitutes a bigger Cmicro Kernel.

XMK_USED_DYNAMIC_STOP (Cmicro Kernel)

If this flag is generated as defined, the SDL system uses the dynamic process stop feature of SDL. (It only requires one stop-symbol in the SDL system to enable this flag to be set). This of course constitutes a bigger Cmicro Kernel.

XMK_USED_SAVE (Cmicro Kernel)

If this flag is generated as defined, the SDL system uses the save feature of SDL. Using save means, that there has to be additional overhead in each signal stored in the SDL queue (each signal is tagged as save or not save).

The save construct, although a useful construct for manipulation of the SDL FIFO queue mechanism, unfortunately requires much code overhead. The user should avoid the utilization of this construct where possible.

XMK_USED_TIMER (Cmicro Kernel and Generated Code)

If there is a minimum of one timer declaration in the system, then this flag is generated as defined. If no timer declarations exist in the SDL system, the timer handling functions are excluded.

---------------------------------------------------------------------
Note:                                                                  
It is possible to implement a user defined timer model by undefining   
these flags and defining some other macros.                            
---------------------------------------------------------------------

XMK_USED_SIGNAL_WITH_PARAMS (Cmicro Kernel)

If no signals with parameters are defined in the SDL system, then this flag is generated as defined which reduces the overall code size.

--------------------------------------------------------------------
Note:                                                                 
It is not recommended in each case (because it is not SDL conform),   
but is possible to send parameters via global parameters by using C   
code in SDL.                                                          
--------------------------------------------------------------------

XMK_USED_SENDER, XMK_USED_PARENT, XMK_USED_OFFSPRING, XMK_USED_SELF
(Cmicro Kernel and Generated Code)

The above flags are generated as defined, if the user uses the appropriate addressing construct within SDL, that is sender, parent, offspring or self.

If "to" in output actions is not used, none of the above flags is generated as defined.

The define XMK_USE_PID_ADDRESSING depends on the above flags.

XMK_USED_PWOS (Cmicro Library)

If no procedures without states are contained in the SDL system, this flag is undefined, otherwise it is defined. Procedures with states are not supported by the Cmicro Package.

Automatic Dimensioning

Some resources of the Cmicro Library are automatically dimensioned. These are described in the following subsections.

MAX_SDL_PROCESS_TYPES(Cmicro Kernel and Generated Code)

The Cmicro Generator counts the amount of process types in the system and generates this define. This is used to dimension some tables used in the generated code, the Cmicro Kernel and the Cmicro Tester.

MAX_SDL_TIMER_TYPES(Cmicro Kernel and Generated Code)

The Cmicro Generator counts the amount of timer types in the system and generates this define. This is used to dimension some tables used in the generated code, the Cmicro Kernel and the Cmicro Tester.

MAX_SDL_TIMER_INSTS(Cmicro Kernel and Generated Code)

The Cmicro Generator counts the amount of instances of timers in the system and generates this define. This is used to dimension some tables used in the generated code, the Cmicro Kernel and the Cmicro Tester.

Creating a New Library

Directory Structure

The Cmicro Library is contained in $sdtdir/MICROLIBRARY with the following directory structure:

MICROLIBRARY

+---- kernel

+---- tester

+---- sdtmt

+---- others

+---- scripts

+---- template

The scripts, makeoptions and makefiles delivered with this version assume the above structure.

------------------------------------------------------------------
Note:                                                               
This directory structure should be considered as an template only.  
------------------------------------------------------------------

The File sdtsct.knl

It is possible for the user to select a kernel in the Analyzers menu "Generate Options" - "Kernel" window. In order to do this an appropriate entry must be placed in the file sdtsct.knl which should be located in one of the following directories present working directory, home directory or $sdtdir directory. The search algorithm for this file is as above.

The Cmicro Library is also contained as another entry in this file, as is seen below:

Example 358 : Content of the file $sdtdir/sdtsct.knl  
-------------------------------------------------------------
Output in Kernel menu       Compilation Flag  Explanation      
-------------------------------------------------------------
Simulation                  SCTDEBCOM         Monitor and      
                                              communica        
                                              tion             
Simulation-ansi             SCTADEBCOM        Monitor and      
                                              communica        
                                              tion             
RealTimeSimulation          SCTDEBCLCOM       Monitor,         
                                              communica        
                                              tion and         
                                              real time        
RealTimeSimulation-ansi     SCTADEBCLCOM      Monitor,         
                                              communica        
                                              tion and real    
                                              time             
ApplicationDebug            SCTDEBCLENVCOM    Monitor          
                                              and, real        
                                              time and the     
                                              user's Env       
ApplicationDebug-ansi       SCTADEBCLENVCOM   Monitor          
                                              and, real        
                                              time and the     
                                              user's Env       
                                                               
PerformanceSimulation       SCTPERFSIM        No monitor       
                                              included         
PerformanceSimulation-ansi  SCTAPERFSIM       No monitor       
                                              included         
                                                               
Application                 SCTAPPLCLENV      No monitor       
                                              but real time    
                                              and the user's   
                                              Env              
ApplicationDebug-ansi       SCTADEBCLENVCOM   Monitor          
                                              and, real        
                                              time and the     
                                              user's Env       
                                                               
Validation                  SCTVALIDATOR      Validator        
Validation-ansi             SCTAVALIDATOR     Validator        
MICROLIBRARY                MICROLIBRARY      Cmicro           
                                              Library          
                                              including        
                                              Kernel /         
                                              Tester           
-------------------------------------------------------------

Makefile

In each directory that contains a library version there is a Makefile that can "make" the library. To create a new library after an update of the source code, change directory to the directory for the library and execute the Makefile. The Makefile uses the makeoptions file in the directory to get the correct compilation switches and other relevant information.

----------------------------------------------------------------
Caution!                                                          
Do not generate and test libraries in the $sdtrelease directory   
structure. Create an appropriate copy.                            
----------------------------------------------------------------
----------------------------------------------------------------
Note:                                                             
The environment variables sdtdir and sctdir need not refer to di  
rectories in $sdtrelease. Any directory containing the relevant   
files may be used.                                                
----------------------------------------------------------------

makeoptions

Normally, the file makeoptions is free to use for the SDT users.

For the Cmicro Package, there is one exception, no precompiled run-time library exists.

In principle, the Cmicro Library is newly scaled each time code is generated for the SDL system. After SDL to C code generation, the Cmicro Library is to be compiled again. This ensures, that the Cmicro Library always contains the functions needed by the SDL system generated.

-------------------------------------------------------------------
Caution!                                                             
The compilation of files in the Cmicro Library are always based on   
the file sdl_cfg.h, which is generated and written into the current  
ly active working directory. If a new sdl_cfg.h file is generated    
with new contents, or if the user has modified parts of the Cmicro   
Library, the Cmicro library should be re-compiled.                   
-------------------------------------------------------------------

Compiling the generated C-Code using any Unix-System

When compiling the generated C code on any Unix system, it is possible to use the facility in the Analyzer / Cmicro Generator, to invoke the compiler directly after the SDL C code has been generated.

The file makeoptions includes all necessary dependencies to build a Cmicro Library.

Compiling the Generated C-Code under DOS / MS-Windows Using make

If the user wishes to compile the generated C code and the Cmicro Library under DOS or MS-Windows, the "makeoptions" file contained in the directory below can be used as a template:

#include $sdtdir/MICROLIBRARY/makeoptions
First, convert all necessary files from Unix format to DOS format:-

unix2dos filename newfilename
Sometimes problems occur, if there are too many arguments to pass to the compiler (or any tool, which you use in the makefile-actions). DOS has a limited set of 128 characters in each command. Possibly this can be solved by using C libraries, which we strongly recommend in each case. Please modify the makefile as is required.

Compiling under DOS / MS-Windows Without make

The other possibility is, to write a DOS batch file (which also can be executed under MS-Windows), where all C modules are compiled in any case.

It is most important, that the objects built from the Cmicro Library are consistent with the objects compiled from the application.

----------------------------------------------------------------
Note:                                                             
To be absolutely sure, recompile all C modules contained in the   
Cmicro Library.                                                   
----------------------------------------------------------------
The makefile dependencies can be viewed in the file

#include $sdtdir/MICROLIBRARY/makeoptions

Generated Make Files

The generated make files for an SDL system will as first action include the makeoptions file in the directory referenced by the environment variable sctdir. It will then use the variables sctIFDEF, sctLINKKERNEL,sctCC,sctCPPFLAGS,sctCCFLAGS,sctLD, and sctLDFLAGS to compile and link the SDL system with the selected library.

The make file is usually generated and executed by the SDT Organizer. Running the Analyzer stand-alone, the make file is however generated and executed by the Cmicro Generator.Below a make file generated for the SDT system Example is shown. This is generated by the Cmicro Generator. The make files generated by the SDT Organizer is similar but not exactly equal.

Example 359 :  
# makefile for System: Example
include $(sctdir)/makeoptions
default: Example$(sctEXTENSION)
Example$(sctEXTENSION): Example$(sctOEXTENSION)
  $(sctLD) $(sctLDFLAGS) \
          Example$(sctOEXTENSION) \
          $(sctLINKKERNEL) \
          -o Example$(sctEXTENSION)
Example$(sctOEXTENSION): Example.c
  $(sctCC) $(sctCPPFLAGS) $(sctCCFLAGS) \
        Example.c $(sctIFDEF) \
            -o Example$(sctOEXTENSION)
  

Adaptation to Compilers

In this section the necessary changes to the source code to adapt it to a new environment are discussed. Adapting to a new environment could mean moving the code to a new hardware or a new compiler.

The following parts may be changed:

Compiler Definition Section in ml_typ.h

The following switches are currently defined in the compiler definition section:

--------------------------------------------------------
Compilation-   Meaning                                    
switch                                                    
--------------------------------------------------------
SOLARIS_CYGNU  The CY-GNU C-Compiler for Solaris          
GNU80166       The GNU 80166 C-Compiler for Sun OS        
IARC51         The IAR 8051 C-Compiler                    
KEIL8051       The Keil 8051 C-Compiler                   
TMS320         The Texas Instruments C-Compiler for TMS   
               320C2x/C5x                                 
MSP58C80       The same as the Texas Instruments C-Com    
               piler for TMS 320                          
MS_C_5_1       The MicroSoft C-Compiler 5.1               
MS_C_8_0       The MicroSoft C-Compiler 8.0               
BORLAND_3_1    The Borland C-Compiler 3.1                 
--------------------------------------------------------
These are the compilers that have been used to compile and link generated code and the Cmicro Library. To introduce a new compiler, a new section in ml_typ.h should be introduced in which the properties of the compiler are defined.

Some changes are then necessary in the file mk_stim.c and mk_cpu.c, where the Cmicro Kernel is using direct hardware access.

If a tight integration with another real time operating system (RTOS), is to be carried out please ask your SDT distributor.

The remaining part of the code of the Cmicro Library should be compileable without performing any modifications. If you have problems with adapting a new compiler or hardware, please contact the supporter of this product.

The list of compilers will of course be extended as and when the necessary information on how to handle each particular compiler are obtained.

The following definitions are to be made in the compiler definition section of ml_typ.h:

#define XPP(x)     x
#define PROTO(x)   x
=>If not, define XNOPROTO
#define XPP(x)
#define PROTO(x)
#ifdef XMK_ADD_STDIO
  #include <stdio.h>
#endif
Does the operating system which is to be used after linking support Environment functions. This is argc and argv in the main function. If yes, then write:
#define XMK_USE_OS_ENVIRONMENT
#define XCONST const
If it is not, then undefine:
#undef XCONST
In general, the compilers which are able to produce ROM-able code, can handle the keyword "const".
Compilers may generate false object code, if using const.
#define XMK_UNIX
If it is not, then undefine:
#undef XMK_UNIX

Defining the SDL System Time Functions in mk_stim.c

The following functions exist in the module mk_stim.c:

void xmk_InitSystime(void)
Initialize the hardware registers to support the system time

void xmk_DeinitSystime(void)
Give up to use the system time. This normally cannot happen, but in some applications, where the SDL system is stopped and restarted again during run-time, it may prove useful.

void xmk_SetTime(xmk_T_TIME)
This function sets the system-time to the given value. Might be used for a hardware, which supports a hardware clock. Never called by Cmicro Kernel.

xmk_T_TIME   xmk_NOW(void)
This is the most important C function to handle SDL system-time. This function returns the absolute time, which is per default defined as a long value.

To make timers in SDL operable, absolute time must be implemented. This can be reached by using a hardware free running counter, or by using a timer ISR, which clocks a global variable containing the absolute time. See the templates contained in the mk_stim- module.

Functions for Direct CPU access in mk_cpu.c

The following C functions exist in the file mk_cpu.c:

Disable interrupts

void disable(void)
Enable interrupts

void enable(void )
These functions are used in the Cmicro Kernel, if it is scaled to preemption. Mostly, one has to implement the body of these functions by inserting assembler in-line code, but some compilers do have a library, which enables direct hardware access.

Differences between Cmicro and Cadvanced

General

This description deals with the differences between the generated C Code of the Cadvanced and the Cmicro Code Generator and the run-time libraries. Of course - there are differences. The reason behind that is - as already mentioned - the main application area for the different code generators.

Some of the differences discussed in the following are of interest for SDL users, whilst others are not.

SDL Restrictions

The Cmicro Generator uses some more SDL restrictions than the Cadvanced generator. The additional restrictions are described in the subsection "Restrictions and SDL-92 Supported Features" on page 2695 within chapter 44, The Cmicro Generator.

Scheduling

First, it must be depicted, that both schedulers do work full SDL conform, although their behavior is a different one.

Cadvanced uses a process ready queue, together with signal queues, in order to schedule processes. Cmicro uses no process ready queue, so that all scheduling is derived from one physical queue. This physical queue represents all SDL process input ports.

Another difference is the preemptive scheduler of Cmicro, if it is used.

Thus, different execution of processes will occur.

It is also a question of SDL process design, if the differences between Cadvanced and Cmicro make a difference as seen from black box view.

If no SDL process assumes a particular behavior from its communicating partner process then the behavior - as seen from a black box view - is always the wanted one.

Generation of Files

The Cmicro Generator generates some more files. This is of interest when implementing build scripts, makefiles and so on.

In addition, the way to include the generated interface file (.ifc) is another one compared with the Cadvanced Generator.

The C module which contains the environment functions, should first

 #include "<systemname>.ifc"
when using Cmicro.

Environment Handling Functions

The main differences come up when considering the environment handling functions. However, this only has consequences, if the SDL environment is the same in both cases (if Cadvanced is used for simulation only, and Cmicro for targeting, then the environment functions are to be implemented twice in any case).

In general (for Cmicro as well as Cadvanced) four C functions are used to represent the SDL environment, namely

All these functions have the same meaning comparing Cadvanced with Cmicro.

For Cmicro, each of the above C functions is compiled only, if it is wanted (selected by XMK_USE_xInitEnv, XMK_USE_xInEnv...)

Differences occur in the declaration of the C function xOutEnv. For Cmicro, xOutEnv carries a few parameters which represent the signal which is to be output to the environment, including the signal parameters. As a recommendation, the definition of the C function xOutEnv should be written twice, one for Cadvanced and one for Cmicro.

As another difference, signals and processes are identified in different ways. Cmicro doesn't use identifications like "xIdNode". Instead, it uses fixed C defines to identify signals and processes. This is good to reduce the amount of memory, but has the consequence, that each access to any signal and any process is to be implemented differently. The subsection "Numbering SDL Objects by Hand" on page 2740 gives more details of how identifiers are generated and can be used.

Including C Code in SDL by User

C code may be included in SDL by the user in the following cases:

If any C code, or C identifiers are used, then users must take care to use the right identifiers and functions.

Layout of Generated Code

Of course, the layout of generated C code is different, comparing Cmicro with Cadvanced. It would cost too much room to list all the details in this subsection. In addition, these differences are of interest for some technical reasons only, and not for pure SDL users.

To compare the different layouts, the following subsections can be viewed:

General Recommendations Regarding Compatibility

In order to reach full compatibility between Cadvanced and Cmicro, the following general recommendations should be followed:

Example of Generated C Code

Consider an SDL system with two processes, ping and pong which alternatively send the signals ping and pong to each other. This system can be used to check the performance. The example is included in the Cmicro Package in the directory $sdtdir/MICROLIBRARY/examples as perf01.pr. The example contains 2 processes, which perform 10000 ping-pongs. Following that, both processes will be stopped. The example, described by using SDL-PR, is:

Example 360 :  
system perf01;
block B1;
    signal    PING ,   PONG , PONG_SAY_BYE_BYE ;
    synonym MAXRUN integer = 10000 ;
process PING (1, 1);
    signalset PONG, PONG_SAY_BYE_BYE;
    start;
      output PING ;
      nextstate State1 ;
    state State1;
        input PONG ;
          output PING ;
          nextstate - ;
        input PONG_SAY_BYE_BYE ;
          stop ; 
endprocess;
process PONG (1, 1);
    signalset PING;
    DCL counter integer; 
    start;
        TASK counter := 0 ;
        nextstate State1;
    state State1;
        input PING ;
          TASK counter := counter + 1;
          DECISION counter > MAXRUN ;
          (true) : 
               output PONG_SAY_BYE_BYE ;
               stop ;
          (false) :
               output PONG ;
               nextstate - ;
          ENDDECISION ;
endprocess;
endblock;
endsystem;
As an example for generation without separation, the generated code now looks like this:

/* Program generated by Micro Generator, version x.x */
#define MICRO_C_x_x
#include "sdl_cfg.h"
#include "ml_typ.h"
#include "ml_err.h"
#define XPTID_z00_PING 0
extern XCONST XPDTBL yPDTBL_z00_PING;
#define XPTID_z01_PONG 1
extern XCONST XPDTBL yPDTBL_z01_PONG;
/************************************************************
**  SYNONYM MAXRUN
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,b1.sbk(1),122(10,10),6)
************************************************************/
#define z05_MAXRUN SDL_INTEGER_LIT(10000)
/***********************************************************
**  PROCESS PING
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,ping.spr(1),110(3,10),1)
************************************************************/
extern YPAD_RESULT_TYPE yPAD_z00_PING XPP((YPAD_ANSI_PARAM));
typedef struct {
    PROCESS_VARS
} yVDef_z00_PING;
#define z000_State1  1
/***********************************************************
**  PROCESS PONG
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,pong.spr(1),110(3,10),2)
************************************************************/
extern YPAD_RESULT_TYPE yPAD_z01_PONG XPP((YPAD_ANSI_PARAM));
typedef struct {
    PROCESS_VARS
        /* #SDTREF(SDL,pong.spr(1),149(5,25),2) */
    SDL_Integer  z011_counter;
} yVDef_z01_PONG;
#define z010_State1  1
/************************************************************
**  SIGNAL PING
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,b1.sbk(1),122(10,10),2)
*************************************************************/
#define z02_PING 1
/************************************************************
**  SIGNAL PONG
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,b1.sbk(1),122(10,10),3)
**************************************************************
/
#define z03_PONG 2
/***********************************************************
**  SIGNAL PONG_SAY_BYE_BYE
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,b1.sbk(1),122(10,10),4)
************************************************************/
#define z04_PONG_SAY_BYE_BYE 3
/***********************************************************
**  #CODE directives, #HEADING sections
************************************************************/
/**********************************************************
**  #CODE directives, #BODY sections
************************************************************/
/**********************************************************
**  Root Process Table
***********************************************************/
XCONST XPDTBL *xPDTBL[MAX_SDL_PROCESS_TYPES+1] =
{
  &yPDTBL_z00_PING,
  &yPDTBL_z01_PONG,
  X_END_ROOT_TABLE
};
/**********************************************************
**  Symbol Trace Table
***********************************************************/
#ifdef XMK_ADD_TEST_OPTIONS
XSYMTRACETBL *xSYMTRACETBL[MAX_SDL_PROCESS_TYPES+1] =
{
  (XSYMTRACETBL_ENTRY *)  NULL,
  (XSYMTRACETBL_ENTRY *)  NULL,
  X_END_SYMTRACE_TABLE
};
#endif
/**********************************************************
**  Timer table
***********************************************************/
/*-------------Timer ROM table--------------*/
#ifdef XMK_USE_TIMER_ROM_TABLE
XCONST XTIMER_ROM_TABLE_ENTRY 
xTimerRomTable[MAX_SDL_TIMER_TYPES+MAXN] =
{
  X_END_TIMER_ROM
};
#endif
/*-------------Timer RAM table--------------*/
#ifdef XMK_USE_TIMER_RAM_TABLE
XTIMER_RAM_TABLE_ENTRY 
xTimerRamTable[MAX_SDL_TIMER_INSTS+MAXI];
#endif
/**********************************************************
**  PROCESS PING
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,ping.spr(1),110(3,10),1)
***********************************************************/
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
** Tables for process PING
** #SDTREF(SDL,ping.spr(1),110(3,10),1)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*--------------Instance Data---------------*/
#define X_MAX_INST_z00_PING 1
static yVDef_z00_PING yINSTD_z00_PING[X_MAX_INST_z00_PING];
/*--------------Process State---------------*/
static xSTATE yPSTATETBL_z00_PING[X_MAX_INST_z00_PING] = {
  XSTARTUP
};
/*---------------State Index----------------*/
static XCONST xSITBL xSTATE_INDEX_z00_PING[2] = {0, 2};
/*---------------Transition-----------------*/
#define XMAX_TRANS_z00_PING 2
static XCONST xTR_TABLE_ENTRY 
yTRTBL_z00_PING[XMAX_TRANS_z00_PING] = {
    /* State1 */
  z03_PONG, 1,
  z04_PONG_SAY_BYE_BYE, 2
};
/*-----------Process-PID-Values-------------*/
#ifdef XMK_USE_PID_ADDRESSING
static xPIDTable yPID_TBL_z00_PING[X_MAX_INST_z00_PING];
#endif
/*-----------Process Description------------*/
#define X_PRIO_z00_PING  xDefaultPrioProcess
XCONST XPDTBL yPDTBL_z00_PING = {
#ifdef XMK_USE_PID_ADDRESSING
  yPID_TBL_z00_PING,
#endif
  (xINSTD *)yINSTD_z00_PING,
  sizeof(yINSTD_z00_PING[0]),
  X_MAX_INST_z00_PING,
#ifdef XMK_USE_TIMESLICE
  X_TIMESLICE_z00_PING,
#endif
#ifdef XMK_USE_PREEMPTIVE
  X_PRIO_z00_PING,
#endif
  (xmk_T_TRANS_ADDRESS) yPAD_z00_PING,
  yTRTBL_z00_PING,
  xSTATE_INDEX_z00_PING,
  yPSTATETBL_z00_PING
};
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
** Function for process PING
** #SDTREF(SDL,ping.spr(1),110(3,10),1)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef XNOPROTO
extern YPAD_RESULT_TYPE yPAD_z00_PING( YPAD_ANSI_PARAM )
#else
extern YPAD_RESULT_TYPE yPAD_z00_PING( YPAD_KR_PARAM )
  YPAD_KR_DEF
#endif
{
  YPAD_YSVARP
  YPAD_YVARP(yVDef_z00_PING)
  YPAD_TEMP_VARS
  YPRSNAME_VAR("PING")
  BEGIN_PAD
  switch (XSYMBOLNUMBER) {
/*-----
** START
** #SDTREF(SDL,ping.spr(1),134(5,25),1)
------*/
  case 0:
    BEGIN_START_TRANSITION
/*-----
** OUTPUT PING
** #SDTREF(SDL,ping.spr(1),137(5,40),1)
------*/
    ALLOC_SIGNAL_NPAR(PING, z02_PING, 0)
    SDL_OUTP_NPAR(xDefaultPrioSignal, PING, z02_PING, 
TO_PROCESS(PONG,
      z01_PONG), 0, "PING")
/*-----
** NEXTSTATE State1
** #SDTREF(SDL,ping.spr(1),140(5,55),1)
------*/
    SDL_NEXTSTATE(State1, z000_State1, "State1")
/*-----
** INPUT PONG
** #SDTREF(SDL,ping.spr(1),125(30,40),1)
------*/
  case 1:
    XOS_TRACE_INPUT("PONG")
/*-----
** OUTPUT PING
** #SDTREF(SDL,ping.spr(1),128(30,55),1)
------*/
    ALLOC_SIGNAL_NPAR(PING, z02_PING, 0)
    SDL_OUTP_NPAR(xDefaultPrioSignal, PING, z02_PING, 
TO_PROCESS(PONG,
      z01_PONG), 0, "PING")
/*-----
** NEXTSTATE -
** #SDTREF(SDL,ping.spr(1),131(30,70),1)
------*/
    SDL_DASH_NEXTSTATE
/*-----
** INPUT PONG_SAY_BYE_BYE
** #SDTREF(SDL,ping.spr(1),119(55,40),1)
------*/
  case 2:
    XOS_TRACE_INPUT("PONG_SAY_BYE_BYE")
/*-----
** STOP
** #SDTREF(SDL,ping.spr(1),122(55,55),1)
------*/
#ifdef XFREEVARS
    FREE_PROCESS_VARS
#endif
    SDL_STOP
  }
  END_PAD(yPAD_z00_PING)
}
/***********************************************************
**  PROCESS PONG
**  <<SYSTEM perf01/BLOCK B1>>
**  #SDTREF(SDL,pong.spr(1),110(3,10),2)
************************************************************/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
** Tables for process PONG
** #SDTREF(SDL,pong.spr(1),110(3,10),2)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*--------------Instance Data---------------*/
#define X_MAX_INST_z01_PONG 1
static yVDef_z01_PONG yINSTD_z01_PONG[X_MAX_INST_z01_PONG];
/*--------------Process State---------------*/
static xSTATE yPSTATETBL_z01_PONG[X_MAX_INST_z01_PONG] = {
  XSTARTUP
};
/*---------------State Index----------------*/
static XCONST xSITBL xSTATE_INDEX_z01_PONG[2] = {0, 1};
/*---------------Transition-----------------*/
#define XMAX_TRANS_z01_PONG 1
static XCONST xTR_TABLE_ENTRY 
yTRTBL_z01_PONG[XMAX_TRANS_z01_PONG] = {
    /* State1 */
  z02_PING, 1
};
/*-----------Process-PID-Values-------------*/
#ifdef XMK_USE_PID_ADDRESSING
static xPIDTable yPID_TBL_z01_PONG[X_MAX_INST_z01_PONG];
#endif
/*-----------Process Description------------*/
#define X_PRIO_z01_PONG  xDefaultPrioProcess
XCONST XPDTBL yPDTBL_z01_PONG = {
#ifdef XMK_USE_PID_ADDRESSING
  yPID_TBL_z01_PONG,
#endif
  (xINSTD *)yINSTD_z01_PONG,
  sizeof(yINSTD_z01_PONG[0]),
  X_MAX_INST_z01_PONG,
#ifdef XMK_USE_TIMESLICE
  X_TIMESLICE_z01_PONG,
#endif
#ifdef XMK_USE_PREEMPTIVE
  X_PRIO_z01_PONG,
#endif
  (xmk_T_TRANS_ADDRESS) yPAD_z01_PONG,
  yTRTBL_z01_PONG,
  xSTATE_INDEX_z01_PONG,
  yPSTATETBL_z01_PONG
};
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
** Function for process PONG
** #SDTREF(SDL,pong.spr(1),110(3,10),2)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef XNOPROTO
extern YPAD_RESULT_TYPE yPAD_z01_PONG( YPAD_ANSI_PARAM )
#else
extern YPAD_RESULT_TYPE yPAD_z01_PONG( YPAD_KR_PARAM )
  YPAD_KR_DEF
#endif
{
  YPAD_YSVARP
  YPAD_YVARP(yVDef_z01_PONG)
  YPAD_TEMP_VARS
  YPRSNAME_VAR("PONG")
  BEGIN_PAD
  switch (XSYMBOLNUMBER) {
/*-----
** START
** #SDTREF(SDL,pong.spr(1),140(55,10),1)
------*/
  case 0:
    BEGIN_START_TRANSITION
    xDef_SDL_Integer(&yVarP->z011_counter);
/*-----
** TASK counter := ...
** #SDTREF(SDL,pong.spr(1),143(55,25),1)
------*/
#ifdef XTRACE
    xTraceTask("counter := ...");
#endif
    yAssF_SDL_Integer(yVarP->z011_counter, SDL_INTEGER_LIT(0), 
XASS);
/*-----
** NEXTSTATE State1
** #SDTREF(SDL,pong.spr(1),146(55,40),1)
------*/
    SDL_NEXTSTATE(State1, z010_State1, "State1")
/*-----
** INPUT PING
** #SDTREF(SDL,pong.spr(1),119(80,25),1)
------*/
  case 1:
    XOS_TRACE_INPUT("PING")
/*-----
** TASK counter := ...
** #SDTREF(SDL,pong.spr(1),122(80,40),1)
------*/
#ifdef XTRACE
    xTraceTask("counter := ...");
#endif
    yAssF_SDL_Integer(yVarP->z011_counter,
      xPlus_SDL_Integer(yVarP->z011_counter, 
SDL_INTEGER_LIT(1)), XASS);
/*-----
** DECISION
** #SDTREF(SDL,pong.spr(1),125(80,55),1)
------*/
#ifdef XTRACE
    yAssF_SDL_Boolean(yDcn_SDL_Boolean, xGT_SDL_Integer(yVarP-
>z011_counter,
      z05_MAXRUN), XASS);
    xTraceDecision(&(yDcn_SDL_Boolean), xSrtN_SDL_Boolean);
    if (yDcn_SDL_Boolean) {
#else
    if (xGT_SDL_Integer(yVarP->z011_counter, z05_MAXRUN)) {
#endif
/*-----
** OUTPUT PONG_SAY_BYE_BYE
** #SDTREF(SDL,pong.spr(1),134(80,70),1)
------*/
      ALLOC_SIGNAL_NPAR(PONG_SAY_BYE_BYE, z04_PONG_SAY_BYE_BYE, 
0)
      SDL_OUTP_NPAR(xDefaultPrioSignal, PONG_SAY_BYE_BYE, 
z04_PONG_SAY_BYE_BYE,
        TO_PROCESS(PING, z00_PING), 0, "PONG_SAY_BYE_BYE")
/*-----
** STOP
** #SDTREF(SDL,pong.spr(1),137(80,85),1)
------*/
#ifdef XFREEVARS
      FREE_PROCESS_VARS
#endif
      SDL_STOP
    } else {
/*-----
** OUTPUT PONG
** #SDTREF(SDL,pong.spr(1),128(105,70),1)
------*/
      ALLOC_SIGNAL_NPAR(PONG, z03_PONG, 0)
      SDL_OUTP_NPAR(xDefaultPrioSignal, PONG, z03_PONG, 
TO_PROCESS(PING,
        z00_PING), 0, "PONG")
/*-----
** NEXTSTATE -
** #SDTREF(SDL,pong.spr(1),131(105,85),1)
------*/
      SDL_DASH_NEXTSTATE
    }
  }
  END_PAD(yPAD_z01_PONG)
}
  

List of non SDL Functions and Operations

The functions listed here are used by the Cmicro Tester, but may also be of user interest. It is not absolutely necessary to have knowledge of these functions, but knowledge of the functions prove useful when it comes to debugging and testing an application.

Exported from mk_sche.c

xmk_GetProcessState

Description:
The function evaluates the current SDL-state of the SDL-process with the given process-PID and returns it to the caller. During SDL system start-up, one possible return value might be XSTARTUP. This means, that a process will be started during system start-up. During normal execution and system start-up, the return value XDORMANT may be returned. This means, that an SDL-process instance is either stopped or has never been created dynamically (created).

Parameter: xPID Process-PID

Return : xmk_T_STATE state-Value

(may also be XSTARTUP / XDORMANT)

#ifdef XMK_ANSI
  xmk_T_STATE xmk_GetProcessState ( xPID pid)
#else
  xmk_T_STATE xmk_GetProcessState ( pid )
  xPID pid;
#endif

Exported from mk_tim1.c

xGetTimerState

Description:
The function evaluates the current State of SDL-Timer handling and
returns it to the caller. The following information is obtainable:-

Parameter: xmk_T_STATE *tinfo

Return : -

#ifdef XMK_ANSI
void xGetTimerState ( xmk_T_STATE *tinfo )
#else
void xGetTimerState ( tinfo )
xPID pid;
#endif

Exported from mk_queu.c

xmk_GetQueueState

Description:
The function evaluates the current SDL-Queue-State and returns some information to the caller:

Parameter : xmk_Q_STATE *qinfo

Return : -

#ifdef XMK_ANSI
  void xmk_GetQueueState ( xmk_Q_STATE *qinfo )
#else
  void xmk_GetQueueState ( qinfo )
  xmk_Q_STATE *qinfo;
#endif

List of Templates for Users and Exported Functions

The list in the following section gives an overview of the functions exported by each module of the Cmicro Library in order to understand the module structure. The functions declared as static are not considered here.

Exported from example.c

main

Description:
This is a template to show users how to use the Cmicro Kernel and the Cmicro Tester.

Parameter : -

Return : -

int main ( int argc, char* argv[] )
#ifdef XMK_ANSI
  #ifdef XMK_USE_OS_ENVIRONMENT
    int main ( int argc, char* argv[] )
  #else
    int main()
  #endif
#endif

Exported from mk_user.c

xInitEnv

Description:
This function is called by the Cmicro Kernel during initialization of the
SDL-System.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xInitEnv (void)
#else
   void xInitEnv ()
#endif

xInEnv

Description:
This function is called by the Cmicro Kernel continuously to retrieve signals polled from the environment. Use the Cmicro Kernel function xmk_Send** to put signals into the system. The use of this function is not absolutely necessary in this case, where the Cmicro Kernel is scaled to preemption, and all external Events are put into the SDL-System via an Interrupt Service Routine, which is to be written by the user.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xInEnv (void)
#else
   void xInEnv ()
#endif

xOutEnv

Description:
This function is called by the Cmicro Kernel, if an SDL-Signal is to be sent to the environment.

Note:
You have several possibilities to send signals to the Environment, see reference manual.

Parameter : sig, prio, dat_len, *p_data, Receiver

Return :
Function must return with TRUE, if Signal was sent to the environment, otherwise with FALSE.

#ifdef XMK_ANSI
   int xOutEnv
   (
   xmk_T_SIGNAL       sig,
   xmk_T_PRIO           prio,
   unsigned char        data_len,
   void                  *p_data,
   xPID                 Receiver
   )
#else
   int xOutEnv (sig, prio, data_len, p_data, Receiver)
   xmk_T_SIGNAL       sig;
   xmk_T_PRIO           prio;
   unsigned char        data_len;
   void                  *p_data;
   xPID                 Receiver;
#endif

ErrorHandler

Description:
This is a function which is to be filled out by the user. The Cmicro Kernel as well as the SDL-Application are the main clients of this function.

Parameter : int ErrorNo - given error number (see header file ml_err.h)

Return : -

#ifdef XMK_ANSI
   void ErrorHandler ( int ErrorNo )
#else
   void ErrorHandler ( ErrorNo )
   int ErrorNo;
#endif

WatchdogTrigger

Description:
If so scaled, this function is called by the Cmicro Kernel each time an SDL-transition is executed.

--------------------------------------------------------------------
Caution!                                                              
Be sure, that the time-out used for the Watchdog is longer than the   
longest SDL Transition (in the case of non preemptive Cmicro Ker      
nel). If the Cmicro Kernel is scaled preemptively, then the Watch     
dog Trigger should not be used, because the execution time of tran    
sitions can never be calculated.                                      
--------------------------------------------------------------------
Parameter : void

Return : -

#ifdef XMK_ANSI
   void WatchdogTrigger ( void )
#else
   void WatchdogTrigger ( )
#endif

MemError

Description:
If scaled so, this function is called by a function contained in the module ml_mem (dynamic memory management), if an error has occurred, i.e. no more dynamic memory is available or inconsistent information in the malloc headings.

-----------------------------------------------------
Caution!                                               
Do not integrate this function into the ErrorHandler!  
-----------------------------------------------------
Parameter : int errnum - error number

Return : -

#ifdef XMK_ANSI
   void MemError ( int errnum )
#else
   void MemError ( errnum )
   int errnum;
#endif

Exported from mk_main.c

xmk_InitSDL

Description:
This C function is called by the user before calling the C function xmk_RunSDL and implements the initialization of the whole SDL-System, namely Timer, Queue, Processes.

Parameter : -

Return : -

#ifdef XMK_ANSI
void
xmk_InitSDL( void )
#else
void xmk_InitSDL( )
#endif

xmk_RunSDL

Description:
This functions either processes a fixed number of signals or processes endlessly. Before processing signals, SDL time-outs are checked and a user-definable C function xInEnv is called.

Parameter :
CountSignals - amount of signals, which are to be processed in this function call, where 0xFF means endless processing.

Return :
NORMALRETURN - SDL-System not to be stopped. There are
processes living or the queue is not empty.

STOP - SDL-System is to be stopped, because there are no more process instances living and no signal to be worked on.

#ifdef XMK_ANSI
int  xmk_RunSDL (unsigned char CountSignals)
#else
int  xmk_RunSDL (CountSignals)
unsigned char CountSignals;
#endif

Exported from mk_sche.c

xmk_StartProcesses

Description:
This function implements the startup phase of the SDL-System. All static process-instances are created. This means executing the start-transition of all process-instances to be created. For each created process-instance, the first state is set. If configured right, the values SDL_SELF, SDL_PARENT and SDL_OFFSPRING are correctly initialized (only necessary if no semantic check was performed, i.e. if the SDT-Analyzer not used).

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_StartProcesses( void )
#else
  void xmk_StartProcesses( )
#endif

xmk_ProcessSignal

Description:
This function processes an SDL-signal and remains in an internal loop, until a signal was processed, or until no signal remains in any input-port in the SDL-system.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_ProcessSignal( void )
#else
  void xmk_ProcessSignal( )
#endif

xmk_CreateProcess

Description:
This function tries to create an instance of the given process-type. This can fail, either if there is no allocatable <create-signal>, or if there is no free <process-instance> of that type (i.e. no instance is "DORMANT").

Parameter : ProcessID - ID of the process type

Return :
ID of the newly created instance (0.... (NMax - 1)) OR xNULLINST if it was not possible to create a new instance

#ifdef XMK_ANSI
  xmk_T_INSTANCE xmk_CreateProcess( xmk_T_PROCESS 
ProcessTypeID )
#else
  xmk_T_INSTANCE xmk_CreateProcess( ProcessTypeID )
  xmk_T_PROCESS ProcessTypeID ;
#endif

xmk_IsAnyProcessAlive

Description:
This function checks for any active instance of a process type by searching for instances not in the state XDORMANT.

Parameter : -

Return : TRUE - There is an active instance
FALSE - No active instances throughout the system

#ifdef XMK_ANSI
  T_BOOL xmk_IsAnyProcessAlive ( void )
#else
  T_BOOL xmk_IsAnyProcessAlive ( )
#endif

xmk_InitPreemptionVars

Description: The variables used in preemption are initialized.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_InitPreemptionVars ( void )
#else
  void xmk_InitPreemptionVars ()
#endif

xmk_DisablePreemption

Description:
The variable which stores the preemption status is incremented. A value greater than zero means it isn't allowed to perform a context-switch at the moment.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_DisablePreemption ( void )
#else
  void xmk_DisablePreemption ()
#endif

xmk_EnablePreemption

Description:
The variable which stores the preemption status is decremented if preemption was disabled. If the variable's value is zero after it is decremented, the function xmk_CheckIfSchedule is called.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_EnablePreemption( void )
#else
  void xmk_EnablePreemption()
#endif

xmk_FetchHighestPrioLevel

Description:
This function searches for signals in the priority queue levels. This is done with decreasing priority in order to find the highest priority level where signals exist. The return value is the highest priority level containing a signal to work on.

Parameter : -

Return : xmk_T_PRIOLEVEL highest prio-level, where a
signal exists.

#ifdef XMK_ANSI
  xmk_T_PRIOLEVEL xmk_FetchHighestPrioLevel ( void )
#else
  xmk_T_PRIOLEVEL xmk_FetchHighestPrioLevel ()
#endif

xmk_CheckIfSchedule

Description:
It is checked whether a context switch is admissible. If this is the case the current priority-level is compared with the highest priority-level where a signal exists. Supposing the highest level is higher than the current, a context-switch is performed using xmk_SwitchPrioLevel. This is repeated until the current priority-level is the highest level.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_CheckIfSchedule( void )
#else
  void xmk_CheckIfSchedule()
#endif

xmk_SwitchPrioLevel

Description:
The global variables for the current priority-level are stored. Afterwards, the function xmk_ProcessSignal is called in order to deal with the signals on the higher priority level. After returning from this function call the variables for the current priority-level are restored.

Parameter : xmk_T_PRIOLEVEL NewPrioLevel - next prio-level to deal with

Return : -

#ifdef XMK_ANSI
  void xmk_SwitchPrioLevel(xmk_T_PRIOLEVEL NewPrioLevel)
#else
  void xmk_SwitchPrioLevel( NewPrioLevel )
  xmk_T_PRIOLEVEL NewPrioLevel;
#endif

xmk_GetProcessState

Description:
The function evaluates the current SDL-state of the SDL-process with the given process-PID and returns it to the caller. During SDL system start-up, one possible return value might be XSTARTUP. This means, that a process will be started during system start-up. During normal execution and system start-up, the return value XDORMANT may be returned. This means, that an SDL-process instance is either stopped or has never been dynamically created.

Parameter : xPID Process-PID

Return : xmk_T_STATE state-Value
(may also be XSTARTUP / XDORMANT)

#ifdef XMK_ANSI
  xmk_T_STATE xmk_GetProcessState ( xPID pid)
#else
  xmk_T_STATE xmk_GetProcessState ( pid )
  xPID pid;
#endif

Exported from mk_outp.c

xmk_SendSimple

Description:
This is a quite simple SDL-Output Function, which needs only 2 Parameters if called. Most SDL-Systems consist of a lot of "normal" Signals without any Parameters and no priority. It makes sense to use this simple Function whenever possible. The Signal is put into the linked list of Signals by using a default Priority.

Parameter : sig - Signal's code
Receiver - PID of the receiver-process

Return : -

#ifdef XMK_ANSI
  void xmk_SendSimple(xmk_T_SIGNAL sig, xPID Receiver)
#else
  void xmk_SendSimple ( sig, Receiver )
  xmk_T_SIGNAL         sig;
  xPID                 Receiver;
#endif

xmk_Send

Description:
This is a more complete SDL-Output Function, which needs all possible Signal parameters if called.

Parameter : sig- signal's code
prio- signal's priority
data_len- number of bytes of signal's parameter
p_data- pointer to dynamically allocated memory area
containing the signal's parameter (NULL if
parameter contained within signal)
Receiver- PID of the receiver-process

Return : -

#ifdef XMK_ANSI
  void xmk_Send(xmk_T_SIGNAL sig, xmk_T_PRIO prio,       
               unsigned char data_len,
               void *p_data, xPID Receiver)
#else
  void xmk_Send ( sig, prio, data_len, p_data, Receiver )
  xmk_T_SIGNAL         sig;
  xmk_T_PRIO           prio;
  unsigned char        data_len;
  void                  *p_data;
  xPID                 Receiver;
#endif

xmk_Determine_Receiver

Description:
This function determines if any instance of the given type is available as a signal's receiver. If no instance can be found, xNULLPID is returned.

Parameter : proc_type - process type to be checked for a receiver

Return : global PID of a found receiver, xNULLPID if none is found

#ifdef XMK_ANSI
  xPID xmk_Determine_Receiver ( unsigned char proc_type )
#else
  xPID xmk_Determine_Receiver ( proc_type )
  unsigned char proc_type;
#endif

Exported from mk_queu.c

xmk_InitQueue

Description:
This function initializes the signal queue. All relevant pointers are initialized. All signal-elements are put into the free-list. The SAVE-state of all signals is set to false.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_InitQueue( void )
#else
  void xmk_InitQueue()
#endif

xmk_FirstSignal

Description:
The first signal in the current queue, which is the one with the highest priority, is copied to the pointer of the currently treated signal and returned to the caller.

Parameter : -

Return :
pointer to first signal in queue (NULL, if no signals in queue)

#ifdef XMK_ANSI
  xmk_T_MESSAGE* xmk_FirstSignal( void )
#else
  xmk_T_MESSAGE* xmk_FirstSignal( )
#endif

xmk_NextSignal

Description:
The signal following the current signal is copied to the current signal. If there isn't another signal, NULL is returned.

Parameter : -

Return :
Pointer to the next signal in the queue (NULL if no more signals in the queue)

#ifdef XMK_ANSI
  xmk_T_MESSAGE* xmk_NextSignal( void )
#else
  xmk_T_MESSAGE* xmk_NextSignal( )
#endif

xmk_InsertSignal

Description:
This function inserts a signal into the queue. The insert-position depends on the Signal-Priority if specified at all.

Parameter : *p_Message - pointer to signal which is to be inserted

Return : -

#ifdef XMK_ANSI
  void xmk_InsertSignal( xmk_T_MESSAGE *p_Message )
#else
  void xmk_InsertSignal ( p_Message )
  xmk_T_MESSAGE *p_Message ;
#endif

xmk_RemoveCurrentSignal

Description:
The signal which was currently processed is removed from the queue and inserted into the list of free signals.

Parameter : -

Return : -

#ifdef XMK_ANSI
  void xmk_RemoveCurrentSignal( void )
#else
  void xmk_RemoveCurrentSignal( )
#endif

xmk_RemoveSignalBySignalID

Description:
Signals of a given signal-code sent to the current process are removed from the queue and inserted in the list of free signals. The signal currently being processed must not be removed, as it is necessary for the current actions. It is only removed after processing is completed.

Parameter : SignalID - signal code of the signals to be removed

Return : -

#ifdef XMK_ANSI
  void xmk_RemoveSignalBySignalID( xmk_T_SIGNAL SignalId 
)
#else
  void xmk_RemoveSignalBySignalID ( SignalId )
  xmk_T_SIGNAL SignalId ;
#endif

xmk_RemoveSignalsByProcessID

Description:
All signals addressed to a specific process are removed by calling this Function.

Parameter : ProcessId - PID of Process

Return : -

#ifdef XMK_ANSI
  void xmk_RemoveSignalsByProcessID( xPID ProcessID )
#else
  void xmk_RemoveSignalsByProcessID( ProcessID )
  xPID           ProcessID;
#endif

xmk_AllocSignal

Description:
An initialized signal from the beginning of the list of free signals is returned, as far as there still remains one. If not NULL is returned.

Parameter : -

Return : Pointer to returned signal (NULL if there is none)

#ifdef XMK_ANSI
  xmk_T_MESSAGE* xmk_AllocSignal( void )
#else
  xmk_T_MESSAGE* xmk_AllocSignal( )
#endif

xmk_FreeSignal

Description:
A signal is initialized and inserted into the free-list at the first position.

Parameter : *p_Message - Pointer to signal to be initialized

Return : -

#ifdef XMK_ANSI
  void xmk_FreeSignal( xmk_T_MESSAGE *p_Message )
#else
  void xmk_FreeSignal( p_Message )
  xmk_T_MESSAGE *p_Message;
#endif

xmk_TestAndSetSaveState

Description:
This function checks whether a signal's SAVE-state is set or not. In testing, the SAVE-state is set to TRUE or FALSE.

Parameter : State - SAVE-state

Return :
TRUE - the given SAVE-state equals the signal's SAVE-state
FALSE - the given SAVE-state differs from the signal's

#ifdef XMK_ANSI
  T_BOOL xmk_TestAndSetSaveState( xmk_T_STATE State )
#else
  T_BOOL xmk_TestAndSetSaveState( State )
  xmk_T_STATE State ;
#endif

xmk_QueueEmpty

Description:
This function tests whether there is a signal remaining in the queue(s) or not.

Parameter :

Return :
TRUE - No more signals in any queue
FALSE - There is a signal in any queue

#ifdef XMK_ANSI
  T_BOOL xmk_QueueEmpty ( void )
#else
  T_BOOL xmk_QueueEmpty ( )
#endif

Exported from mk_tim1.c

xmk_InitTimer

Description:
All initializations of timers are performed within this function, which is called during SDL system start. It initializes some pointers, and the free-list of timers.

Parameter : -

Return : -

#ifdef XMK_ANSI
void xmk_InitTimer( void )
#else
void xmk_InitTimer( )
#endif

xmk_TimerSet

Description:

This function activates an instance of a timer with the given "Signal-ID"-value and the given time.

Working principles:

Parameter :
time - Expiration time of the timer
sid - ID of the timer signal which is produced at timer expiration.

Return : void

#ifdef XMK_ANSI
void xmk_TimerSet( xmk_T_TIME time ,xmk_T_SIGNAL sid )
#else
void xmk_TimerSet( time, sid )
xmk_T_TIME time ;
xmk_T_SIGNAL sid ;
#endif

xmk_TimerReset

Description:
This function resets the timer with the given "Signal-ID"-Value, if it is active and set by the currently running process. If an active timer instance is found, then the timer is inserted into the free-list.

Parameter : sid -ID of the timer signal which is produced at timer expiration.

Return : -

#ifdef XMK_ANSI
void xmk_TimerReset( xmk_T_SIGNAL sid )
#else
void xmk_TimerReset( sid )
xmk_T_SIGNAL sid ;
#endif

xmk_TimerActive

Description :
The functions checks, if a Timer with the given "Signal-ID" value is active, in the current running process.

Parameter : sid - ID of the timer signal which is produced at timer expiration.

Return :
TRUE - the timer is active in the current running process.
FALSE - the timer is not active in the current running process.

#ifdef XMK_ANSI
T_BOOL xmk_TimerActive( xmk_T_SIGNAL sid )
#else
T_BOOL xmk_TimerActive( sid )
xmk_T_SIGNAL sid ;
#endif

xmk_ResetAllTimer

Description:
All active Timers of a Process equal to the given process PID Value are reset and inserted into the free list.

Parameter : xPID pid - global Process-ID

Return : -

#ifdef XMK_ANSI
void xmk_ResetAllTimer( xPID pid )
#else
void xmk_ResetAllTimer( pid )
xPID pid;
#endif

Exported from ml_err.c

xmk_err_text

Description:
This function on receiving an error-number as input returns a pointer to a corresponding text string.

Parameter : int nr - Error Number

Return : Pointer to error text string

#ifdef XMK_ANSI
char *xmk_err_text ( int nr )
#else
char *xmk_err_text ( nr )
int nr ;
#endif

Exported from mk_stim.c

xmk_InitSystime

Description:
This function initializes the hardware timer and is to be filled out by the user.

Parameter : -

Return : -

#ifdef XMK_ANSI
void xmk_InitSystime( void )
#else
void xmk_InitSystime( )
#endif

xmk_DeinitSystime

Description:
This function deinitializes the hardware-Timer and is to be filled out by the user.

Parameter : -

Return : -

#ifdef XMK_ANSI
void xmk_DeinitSystime( void )
#else
void xmk_DeinitSystime( )
#endif

xmk_SetTime

Description:
This function sets the system time to the given value and is to be filled out by the user.

Parameter : -

Return : -

#ifdef XMK_ANSI
void xmk_SetTime( xmk_T_TIME time )
#else
void xmk_SetTime( time )
xmk_T_TIME time ;
#endif

xmk_NOW

Description:
This function is used by

The function is to be filled out by the user.

Parameter : -

Return : current time

#ifdef XMK_ANSI
xmk_T_TIME xmk_NOW ( void )
#else
xmk_T_TIME xmk_NOW ( )
#endif

Exported from ml_mem.c

MemInit

Description:
This function is to be called by the user, before dynamic memory management can be used. The user has to specify the beginning and the end of the area to be used for dynamic MM.

Parameter :
_mem_begin:
_mem_end:

Return : void

#ifdef XMK_ANSI
void MemInit( char* _mem_begin, char* _mem_end )
#else
void MemInit( _mem_begin, _mem_end )
char* _mem_begin;
char* _mem_end;
#endif

malloc

Description:
This function is a template for the malloc () implementation, which works on a policy of "first fit".

Parameter : rsize :

Return :

#ifdef XMK_ANSI
void* malloc( unsigned long rsize )
#else
void* malloc( rsize )
unsigned long rsize;
#endif

free

Description:
This function is a template for the free () implementation.

Parameter : mem:

Return :

#ifdef XMK_ANSI
void free( void *mem )
#else
void free( mem )
void *mem;
#endif

calloc

Description:
This function is a template for the calloc () implementation.

Parameter : RequestedSize:

Return :

#ifdef XMK_ANSI
void* calloc( unsigned long RequestedSize )
#else
void* calloc( RequestedSize )
unsigned long RequestedSize;
#endif

memshrink

Description:
This function is a template for an extension of the Standard of the dynamic Memory Management supported by an ordinary C-Compiler. It allows the user to shrink down a memory area previously requested with malloc.

Parameter :
pMemBlock:
NewSize :

Return :

#ifdef XMK_ANSI
void memshrink( void  *pMemBlock, unsigned long NewSize )
#else
void memshrink(pMemBlock, NewSize )
void     *pMemBlock ;
unsigned  long NewSize ;
#endif

memset

Description:
This function is a template for the memset () implementation.

CAUTION:
Take care when the preemption policy is utilized.

#ifdef XMK_ANSI
void memset ( char *p, char val, int length)
#else
void memset ( p, val, length)
void *p;
char  val;
int   length;
#endif

memcpy

Description:
This function is a template for the memcpy () implementation.

CAUTION:
Take care when the preemption policy is utilized.

#ifdef XMK_ANSI
void memcpy ( char *dest, char *source, int length)
#else
void memcpy ( dest, source, length)
char  *dest;
char  *source;
int    length;
#endif

Exported from mk_cpu.c

_out

Description:
A template for character output (default for MS-DOS). Should normally not be used in the target.

Parameter : -

Return : -

#ifdef XMK_ANSI
void _out( int pa , char v )
#else
void _out( pa , v )
int pa ;
char v ;
#endif

_in

Description:
A template for character input (default for MS-DOS). Should normally not be used in the target.

Parameter : -

Return : -

#ifdef XMK_ANSI
char _in( int pa )
#else
char _in( pa )
int pa ;
#endif

disable

Description:
A Template to show how to disable interrupts (default for MS-DOS)

Parameter : -

Return : -

#ifdef XMK_ANSI
void disable( void )
#else
void disable( )
#endif

enable

Description:

A Template to show how to enable interrupts (default for MS-DOS)

Parameter : -

Return : -

#ifdef XMK_ANSI
void enable( void )
#else
void enable( )
#endif

xxmonPID

Description:
Used for test purposes, free use.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xxmonPID (char *ostring, xPID pid)
#else
   void xmonPID (ostring, pid)
   char *ostring;
   xPID  pid;
#endif

xxmonhexsingle

Description:
Used for test purposes, free use.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xxmonhexsingle (char *p_text, unsigned char 
*p_adress, int length)
#else
   void xxmonhexsingle (p_text, p_adress, length)
   char  *p_text;
   unsigned char *p_adress;
   int  length;
#endif

xxmonhex

Description:
Used for test purposes, free use.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xxmonhex (char *p_text, unsigned char *p_adress, 
int length)
#else
   void xxmonhex (p_text, p_adress, length)
   char  *p_text;
   unsigned char *p_adress;
   int  length;
#endif

xxmonconfig

Description:
Function for test purposes, free use.

Parameter : -

Return : -

#ifdef XMK_ANSI
   void xxmonconfig ()
#else
   void xxmonconfig ()
#endif
 
Table of Contents Next Chapter