IBM
Contents Index Previous Next



Targeting


Preparations - File Structure

  1. Create a new empty directory <cmicrotutorial> in your home directory or on your local hard disk. This directory will be denoted by <MyTutorial> in the following.
  2. Copy the directory
    <installation>/sdt/examples/cmicrotutorial/<platform>/pager
    (including all files and subdirectories) to your new <MyTutorial> directory and remove all write protections.
  3. In the Organizer, open the Pager system (Pager.sdt) found in <MyTutorial>/pager/system.

Using the Targeting Expert

  1. Select the system symbol in the Organizer view.
  2. Start the Targeting Expert from the Generate menu. The Targeting Expert will generate a default partitioning diagram model (see Partitioning Diagram Model File) and will check the directory structure.
  3. As the target directory specified in the Organizer does not exist yet, you will be prompted if it should be created. Press the Yes button.

A sub-directory structure is added in the target directory afterwards by the Targeting Expert. For further information see Target Sub-Directory Structure.

Note:

If the Targeting Expert is started the very first time a welcome window is displayed. Just press the Close button and proceed. The welcome window will be shown any time you start the Targeting Expert again until you select the "Do not show again at startup" check box.

The work flow of the Targeting Expert is divided into four steps.

The very first time you are using the Targeting Expert, an assistant is automatically started showing you how to proceed. When you have closed the assistant, you can always re-start it by choosing the menu option Help > Assistant.

The Help Viewer will be displayed and show the appropriate manual page if you click on one of the numbered boxes.

Step 1: Select the Desired Component

Hint:

The component can be given any name you like if the system is deployed using the Deployment Editor. For more detailed information on how to deploy a system, see The Deployment Editor.

Figure 180 : The Targeting Expert's main window

Background Information

Step 2: Select the Type of Integration

  1. Press the left most combo box in the integration tool bar of the main window (or click the component entry in the partitioning diagram model using the right mouse button). This is shown in Figure 181.

Figure 181 : Popup menu in the Targeting Expert

  1. A tree structure containing all the pre-defined integrations is shown in the popup menu displayed. Select Light Integrations > Application TEST.

The SDL system is now checked for correctness and the automatic configuration is done.

Hint:

Although only the automatic configuration files sdl_cfg.h and ml_mcf.h are needed the SDL to C compiler also generates the files: component.c, component.ifc, and component.sym.

After the SDL to C compiler has finished, the Targeting Expert:

Hint:

After the integration has been selected the Targeting Expert automatically sets the default compiler. The default compiler's name is taken from the preferences.

If a different compiler is required than the one set as default in the preferences, it is possible to change this in the integration tool bar's combo box.

Background Information

If you want to do an integration not given in the SDL Suite distribution, please select the entry <user defined> in the integration popup menu. Then you are able to do all settings needed for the used hardware. You are also able to set up your own integration accessible in the integration popup menu.

The contents of the files:

Edit the Environment File

In this section you will learn how to fill in the environment functions in the file env.c.

Hint:

There is also a prepared env.c. You can copy it from directory:
<MyTutorial>/pager/prepared into
<MyTutorial>/pager/target/pager._0/Application_TEST.

Do not forget to remove the write protection!

Note the differences between the prepared and generated file.

Note:

In the following section the Targeting Expert starts a text editor. Per default the built-in editor is used. This can be changed in the Tools > Customize menu.

  1. Select the menu Edit > Edit Environment File to open the file env.c

Caution!

In the file env.c, you should only edit code between the lines:

/* BEGIN User Code ... */ 
/*   END User Code ... */

The reason is:

If the Targeting Expert needs to generate the file a second time, the code in these sections will be read in and copied to the new file. Only the code between the mentioned lines will be unchanged.

Do NOT edit lines with the text:

/* BEGIN User Code ... */ 
/*   END User Code ... */

  1. Find the lines from the global section:
    /* BEGIN User Code (global section)*/
    
    /* It is possible to define some global variables here */
    
    /* or to include other header files. */
    
    
    
    This tutorial describes a console application. It will use the screen and the keyboard to communicate with the user. It is necessary to include the used header file(s).
    For a better style some defines are used. Further some global variables and functions have to be implemented. The functions are called, if there should be something simulated in the environment, like a display. After the line
    /* or to include other header files. */
    the following code needs to be inserted:
    #if defined(MICROSOFT_C)
    
      #include <conio.h>
    
    #else
    
      #include <stdio.h>
    
    #endif
    
    
    
    #define key_was_pressed 1
    
    #define key_not_pressed 0
    
    
    
    int  KeySignalPresent  = 0;
    
    char LastKeyPressed;
    
xInitEnv()
  1. We like to have a welcome message displayed when the system is started. This can be done like this in the function xInitEnv()
    printf("-------- Welcome to Pager system--------\n\n");
    
    printf("get message :  0 to 4\n");
    
    printf("scroll right:  r\n");
    
    printf("scroll left :  l\n");
    
    printf("delete      :  d\n\n");
    

The code must be inserted between

/* BEGIN User Code (init section) */

and

/*   END User Code (init section) */
xInEnv()
  1. Now you have to handle the data from the environment. In this tutorial it means you have to handle the input from the keyboard!

Caution!

Do not use blocking functions in the environment file.

The environment is polled with every cycle of the Cmicro Kernel. That is the reason why it is not allowed to use blocking functions like getchar(). These kind of functions stop the kernel making it unable to process events in the SDL system, for example expired timers.

The possible handling of the data:
If a key has been pressed the digits 0-4 are recognized as a message and the letters 'r', 'l' and 'd' are the commands for scrolling and deleting.
Please go to the code position of the function xInEnv() with the following lines:
/* BEGIN User Code (variable section)*/
/* It is possible to define some variables here      */
/* or to insert a functionality which must be polled */
Below these lines insert the following code:
char my_inkey;

KeySignalPresent = key_not_pressed;

#if defined(XMK_UNIX)
  my_inkey = 0;
  if((my_inkey = getchar_unlocked()) != 0)
  {
    KeySignalPresent=key_was_pressed;
  }
#elif defined(MICROSOFT_C)
  if (kbhit())
  {
    my_inkey=_getch();
    KeySignalPresent=key_was_pressed;
  }
#endif

if (KeySignalPresent==key_was_pressed)
{	 
  if ((my_inkey == 'r') || 
      (my_inkey == 'l') ||
      (my_inkey == 'd') ||
      ((my_inkey>='0')&&(my_inkey<='4')))
    LastKeyPressed = my_inkey;
  else
    LastKeyPressed=0;
}
else
 LastKeyPressed = 0;

  1. Find the following lines of code in the function xInEnv()
    /* BEGIN User Code <ScrollRight>_1 */
    
      if (i_have_to_send_signal_ScrollRight)
    
    /*   END User Code <ScrollRight>_1 */
    
    In step 2 we implemented the variable LastKeyPressed. In step 4 we assigned it the value of my_inkey which has the value of the last key pressed. Modify the if() statement into:
    if (LastKeyPressed == 'r')
    
  2. Find the following line of code in the function xInEnv()
    GLOBALPID(Who_should_receive_signal_ScrollRight,0));
    
    The process type ID which should receive the signal ScrollRight needs to be inserted. To get an overview of the process type IDs look at the dialog window that has pop-ed up by the Targeting Expert. All the used process type IDs are given here.

Figure 182 : Process type ID dialog

Select the XPTID_Keypad entry in this dialog to copy it into the clipboard. Then paste it into the env.c as shown below.
GLOBALPID(XPTID_Keypad,0));
The function returns, and the signal is treated.
  1. Find the following lines in the function xInEnv()
    /* BEGIN User Code <ScrollLeft>_1 */
    
      if (i_have_to_send_signal_ScrollLeft)
    
    /*   END User Code <ScrollLeft>_1 */
    
    Modify the if() statement to:
    if (LastKeyPressed == 'l')
    
  2. Find the following line of code in the function xInEnv()
    GLOBALPID(Who_should_receive_signal_ScrollLeft,0));
    
    Copy the XPTID_keypad as described in step 6.
    GLOBALPID(XPTID_Keypad,0));
    
  3. Find the following lines of code in the function xInEnv()
    /* BEGIN User Code <Delete>_1 */
    
      if (i_have_to_send_signal_Delete)
    
    /*   END User Code <Delete>_1 */
    
    Modify the if() statement to:
    if (LastKeyPressed == 'd')
    
  4. Find the following line of code in the function xInEnv()
    GLOBALPID(Who_should_receive_signal_Delete,0));
    
    Copy the XPTID_keypad as described in step 6.
    GLOBALPID(XPTID_Keypad,0));
    
  5. Because we do not use a real target hardware, but simulate the Pager system, we have to predefine some messages.
    Find the following lines of code in the function xInEnv()
    /* BEGIN User Code <ReceivedMsg>_1 */
    
    if (i_have_to_send_signal_ReceivedMsg)
    
    /*   END User Code <ReceivedMsg>_1 */
    
    Modify the if() statement to:
    if ((LastKeyPressed>='0')&&(LastKeyPressed<='4'))
    
    This if-statement checks whether the key hit on the keyboard was one of the defined keys or not.
  6. Go to the next empty "User Code" section and insert following lines:
    char *p;
    
      xmk_var.Param1.MyText = (SDL_Charstring)NULL;
    
      
    
      switch(LastKeyPressed)
    
      {
    
        case '0':
    
             p = " Hello user";
    
    	  xmk_var.Param1.TelNumber = 12345;
    
    	  break;
    
        case '1':
    
    	  p = " How do you feel doing targeting?";
    
    	  xmk_var.Param1.TelNumber = 555555;
    
    	  break;
    
        case '2':
    
    	  p = " Targeting is all so easy!";
    
    	  xmk_var.Param1.TelNumber = 987654;
    
    	  break;
    
        case '3':
    
    	  p = " I only wanted to check if it works.";
    
    	  xmk_var.Param1.TelNumber = 45454;
    
    	  break;
    
        case '4':
    
    	  p = " ... and it works very fine!";
    
    	  xmk_var.Param1.TelNumber = 911911;
    
    	  break;
    
        default :
    
            break;
    
      }
    
      xAss_SDL_Charstring(&(xmk_var.Param1.MyText), p, 
    XASS_AC_ASS_FR);
    
    In this part the messages to the equivalent numbers 0-4 are stored. With the switch statement it is decided which one is handed over to the environment.

Note:

This way of "receiving" messages is of course just a helper function because we do not use a real interface here!

The line xmk_var.Param1.MyText = (SDL_Charstring)NULL;
means that the element MyText of the parameter message which is a parameter of the signal ReceivedMsg is set to null.
The Signal ReceivedMsg and the parameter message are declared in the SDL system.
The line xAss_SDL_Charstring(&(xmk_var.Param1.MyText), p, XASS_AC_ASS_FR); allocates memory for the pointer p.

Note:

If an SDL charstring is mapped to an array of char in C, the first character in this array (index 0) is for internal use only, i.e. the text message should start at index 1. This is done by having a space in front of the text in the implementation shown above.

  1. Find the following line of code in the function xInEnv()
    GLOBALPID(Who_should_receive_signal_ReceivedMsg,0));
    
    Modify the statement as showed below.
    GLOBALPID(XPTID_PagerCtrl,0));
    
xOutEnv()

Caution!

The function xOutEnv() provides a pointer named: xmk_TmpDataPtr. The data referenced by this pointer is valid only as long as the function xOutEnv() is processed.

If you need to treat the data after leaving the function, copy it to variables defined by you.

  1. Find the following code section:
    case CurrentMsg :
    
              {
    
                /* BEGIN User Code <CurrentMsg>_1 */
    
    /* Use (yPDP_CurrentMsg)xmk_TmpDataPtr to access               
    the signal's parameters */
    
    /* ATTENTION: the data needs to be copied.  Otherwise it */
    
    /* will be lost when leaving xOutEnv */
    
                /*   END User Code <CurrentMsg>_1 */
    
    
    
                /* BEGIN User Code <CurrentMsg>_2 */
    
                /* Do your environment actions here. */
    
                xmk_result = XMK_TRUE; /* to tell the caller that 
    */
    
                                       /* signal is consumed      
    */
    
                /*   END User Code <CurrentMsg>_2 */
    
              } 
    
    This code fragment handles the signal CurrentMsg. The chosen message is displayed on the screen (telnumber, message, current message position and the total number of messages). Insert the following code after: /* Do your environment actions here. */
    printf("\r                                                ");
    
    printf( "\rCurrentMessage:  %6d  %s   (%d/%d)",
    
          ((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param3.TelNumber,
    
          ((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param3.MyText+1,
    
          ((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param1,
    
          ((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param2);
    
    xFree(&(((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param3.MyText));
    
    The line
    xFree(&(((yPDP_CurrentMsg)xmk_TmpDataPtr)->Param3.MyText)); frees the memory allocated in the kernel when sending the signal.
  2. Find the following code in the function xOutEnv():
    case ServiceMsg :
    
      {
    
        /* BEGIN User Code <ServiceMsg>_1 */
    
        /* Use (yPDef_Close*)xmk_TmpDataPtr to access
    
           the signal's parameters */
    
        /* ATTENTION: the data needs to be copied.
    
                      Otherwise it */
    
         /*                will be lost when leaving xOutEnv */
    
         /*   END User Code <ServiceMsg>_1 */
    
    
    
         /* BEGIN User Code <ServiceMsg>_2 */
    
         /* Do your environment actions here. */
    
    
    
         xmk_result = TRUE; /* to tell the caller that */
    
         /* signal is consumed      */
    
         /*   END User Code <ServiceMsg>_2 */
    
      }
    
    The code fragment handles the signal ServiceMsg. The handling of the data is same as in the step before. So insert the following code after: /* Do your environment actions here. */
    printf("\r                                                ");
    
    printf( "\rServiveMessage: %s",
    
          ((yPDP_ServiceMsg)xmk_TmpDataPtr)->Param1+1);
    
    xFree(&(((yPDP_ServiceMsg)xmk_TmpDataPtr)->Param1));
    
    
    
  3. Find the following code section in the function xOutEnv():
    case ShortBeep :
    
         {
    
           /* BEGIN User Code <ShortBeep>_1 */
    
           /*   END User Code <ShortBeep>_1 */
    
    
    
           /* BEGIN User Code <ShortBeep>_2 */
    
           /* Do your environment actions here. */
    
              xmk_result = XMK_TRUE; /* to tell the caller that */
    
                                     /* signal is consumed      */
    
           /*   END User Code <ShortBeep>_2 */
    
         }
    
         break ;
    
    The code fragment handles the signal ShortBeep. A beep sounds when the pager receives a message or you do something which is not allowed. After the code /* BEGIN User Code <ShortBeep>_1 */ insert
    putchar(07);
    
  4. Find the following code section in the function xOutEnv():
    case LongBeep :
    
         {
    
           /* BEGIN User Code <LongBeep>_1 */
    
           /*   END User Code <LongBeep>_1 */
    
    
    
           /* BEGIN User Code <LongBeep>_2*/
    
           /* Do your environment actions here. */
    
              xmk_result = XMK_TRUE; /* to tell the caller that */
    
                                     /* signal is consumed      */
    
           /*   END User Code <LongBeep>_2*/
    
         }
    
         break ;
    
    Insert the following code after
    /* BEGIN User Code <LongBeep>_1 */
    putchar(07);
    
    putchar(07);
    

Closing the Environment

In this tutorial there is no need to close the environment. In other cases, e.g. microprocessor hardware, it is probably necessary to do so.

Have a look in the file env.c, find code like this in the function xCloseEnv():

/* BEGIN User Code (close section) */
/* Do the actions here to close your environment */
/*   END User Code (close section) */

Insert any code you need to have here.

Step 3: Configure the Build Process

  1. Press the items below the Application TEST in the partitioning diagram. If it is necessary to add or remove settings for your job, you can edit the settings.
  2. Click Save to close the dialog.

For this section of the tutorial there it is not necessary to modify anything, though we will do some modifications later in section Run Target EXE without Tester.

Background Information

Short description of the different areas:

Step 4: Make the Component

  1. In the dialog which is displayed by default (when the Application TEST is selected) you have to select two check boxes. Analyze / Generate Code and Environment functions.
  2. Click on the button Full Make to start the code generation and make.

After the SDL to C compiler has finished the code generation, the Targeting Expert will re-generate the env.c (and keep your modifications). Afterwards it generates a makefile with the given settings and the code will be compiled and linked.

The Targeting Expert then starts the SDL Target Tester.


http://www.ibm.com/rational
Contents Index Previous Next