SinelaboreRT Header Logo

SinelaboreRT

As simple as possible, but not any simpler!

User Tools

Site Tools


wiki:news:10oct2013

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
wiki:news:10oct2013 [2013/09/09 21:32] pmuellerwiki:news:10oct2013 [2022/08/17 19:44] (current) – Discussion status changed pmueller
Line 1: Line 1:
-====== Creating complex state machines ======+====== Multiple instances of the same machine ======
  
-The sinelabore code generator allows the generation of state machine +Sometimes you want to run the same state machine multiple times. E.g. processing three serial interfaces with the same state machine. In object orient languages this is easy as the concept of objects is the basis of these languages. You would simply instantiate the class three times.
-code from quite complex state machines.+
  
-Nevertheless there are users who want to generate code from even more +Luckily in C there is also a well known concept to do thisInstead of defining objects you define a (instance) structure that contains all local data a function needs. When calling that function a pointer to the instance data structure is handed over. In our case the function is the state machine handler. The code generator automatically creates the instance data structure automatically for you.
-complex modelsEspecially if you used specialized state machine modeling tools +
-before and now want to switch to general purpose UML tools this is for you.+
  
-Examples for features not possible before are states in regions that contain regions again (region in region((Regions are well supported from the code-generatorBut simulation and test-case generation is not yet possible. For more details have a look in the manual.+In this example we will show you how to "create multiple instances" of the state machine. 
 +And then we show you how to create an own structure where additional private data for the state handler can be defined.
  
-))). +Let's start ...
-Or models with sub-machines in regionsBoth is shown in the figure below.+
  
-Have fun!+===== Create Multiple Instances ===== 
 +Follow these simple steps to prepare the generated code for multiple instances. First set some parameters in the configuration file: 
 +  - Set parameter ''HsmFunctionWithInstanceParameters'' to ''YES'' 
 +  - Set parameter ''HsmFunctionWithEventParameter'' to ''YES''
  
 +As a result the generated state machine handler signature looks like this:
  
-{{ :wiki:news:sm_ea_region_region.png?nolink |}}+<code c> 
 +void  testcase(TESTCASE_INSTANCEDATA_T* userInstanceVar, TESTCASE_EVENT_T msg) 
 +</code>
  
-{(rater>id=2|name=How do you like this article?|type=rate)} +You can now simply declare multiple variables of type TESTCASE_INSTANCEDATA_T which contains the data per instance. When calling the state machine just point to one of these variables. 
-~~DISCUSSION|Leave your comments~~+
  
 +Sometimes it is necessary that a state machine knows on which object it currently works on. Therefore a predefined member called ''inst_id'' is generated by default. You can set it to any value that makes sense in your context (e.g. provide the COM port number the machine currently processes).
 +
 +<code c>
 +TESTCASE_INSTANCEDATA_T instDataA = TESTCASE_INSTANCEDATA_INIT;
 +TESTCASE_INSTANCEDATA_T instDataB = TESTCASE_INSTANCEDATA_INIT;
 +TESTCASE_INSTANCEDATA_T instDataC = TESTCASE_INSTANCEDATA_INIT;
 +
 +// Set object ID if the machine needs to know which object it is
 +// E.g. which serial port to open ...
 +instDataA.inst_id=0;
 +instDataB.inst_id=1;
 +instDataC.inst_id=2;
 +
 +// call "object A"
 +testcase(&instDataA, msg);
 +        
 +// call "object B"
 +testcase(&instDataB, msg);
 +        
 +// call "object C"
 +testcase(&instDataC, msg);
 +
 +</code>
 +
 +I think you agree that there is no magic in running multiple instances of the state handler.
 +
 +===== Provide an own Instance Structure =====
 +Sometimes it makes sense to provide an own instance structure. In our example we want to store the baud rate, parity and other values relevant for each serial port.
 +
 +So first define an own struct in a file called ''own_inst_type.h'' (as an example). The example below shows how to define local variables like the ''noRxBytes'' (number of already defined bytes) as well as parameters like the parity etc.
 +
 +<code c>
 +#ifndef __OWN_INST_TYPE__
 +#define __OWN_INST_TYPE__
 +
 +typedef struct InstanceData MY_TESTCASE_INSTANCEDATA_T;
 +
 +#include <stdint.h>
 +#include <testcase_ext.h>
 +#include "testcase.h"
 +
 +struct InstanceData{
 +        uint16_t baudrate;
 +        uint8_t noBits;
 +        uint8_t parity;
 +        uint8_t stopBit; 
 +        TESTCASE_INSTANCEDATA_T instanceVar;
 +};
 +
 +#endif // __OWN_INST_TYPE__
 +</code>
 +
 +Then tell the code generator to use this struct. Add the third line to the configuration file which then looks like this:
 +<code>
 +HsmFunctionWithInstanceParameters=YES
 +HsmFunctionWithEventParameter=YES
 +HsmFunctionUserDefinedParameter=MY_TESTCASE_INSTANCEDATA_T
 +</code>
 +
 +The generated state machine signature now looks as follows. The difference is that the own instance structure is now used instead of the generic one.
 +<code c>
 +void  testcase(MY_TESTCASE_INSTANCEDATA_T* userInstanceVar, TESTCASE_EVENT_T msg)
 +</code>
 +
 +To use the newly defined instance type declare the instance variables now as follows:
 +
 +<code c>
 +// init three different serial ports
 +MY_TESTCASE_INSTANCEDATA_T instDataA = {0,9600,8,'N',1,TESTCASE_INSTANCEDATA_INIT};
 +MY_TESTCASE_INSTANCEDATA_T instDataB = {0,19200,8,'E',1,TESTCASE_INSTANCEDATA_INIT};
 +MY_TESTCASE_INSTANCEDATA_T instDataC = {0,9600,8,'N',1,TESTCASE_INSTANCEDATA_INIT};
 +
 +// Set object ID if the machine needs to know which object it is
 +// E.g. which serial port to open ...
 +instDataA.instanceVar.inst_id=0;
 +instDataB.instanceVar.inst_id=1;
 +instDataC.instanceVar.inst_id=2;
 +
 +// call "object A"
 +testcase(&instDataA, msg);
 +
 +</code>
 +
 +Now the state machine is ready to use the new private instance data inside the machine code.
 +
 +===== Putting all Things Together =====
 +
 +Coming back now to the example of three serial interfaces. The following figure shows a simplified state machine for handling a serial interface. The state machine is generic. Whether COM0 or COM1 or COM2 is processed is determined only from the content of the instance variable. And also other parameters are stored there and of course the local machine variables.
 +
 +{{:wiki:news:multiple_instances.png?nolink}}
 +
 +I hope that the concepts how to run multiple state machines of the same type are clearer now. And also how to define an own instance structure that is necessary for more complex machines.
 +
 +In case of any questions don't hesitate to contact me!
 +
 +
 +
 +~~DISCUSSION:closed|Leave your comments~~
wiki/news/10oct2013.1378755159.txt.gz · Last modified: 2013/09/09 21:32 by pmueller

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki