Skip to Main Content Skip to Search
Product Documentation

Integrating Generated Code into External Environment

About this Tutorial

Learning Objectives

Prerequisites

Required Files

Relocating Code to Another Development Environment

Generated code depends on static support files that MathWorks provides. If you need to relocate the static and generated code files for a model to another development environment, such as a dedicated build system, use the Simulink Coder pack-and-go utility (packNGo ). This utility finds and packages all files to build an executable image, including external files you define in the Code Generation > Custom Code pane of the Configuration Parameters dialog box, and packages the files in a standard zip file.

  1. Open rtwdemo_throttlecntrl_externenv.mdl. Save a copy to throttlecntrl_externenv.mdl in a writable location on your MATLAB path. Proceed through the tutorial from this location.

  2. Generate code for the model.

    After code generation, the model is configured to run packNGo.

  3. In your working folder, find and examine the contents of the generated file throttlecntrl_externenv.zip.

    The number of files in the zip file depends on the version of Embedded Coder software that you are running and the configuration of the model. The compiler does not require all files in the zip file. The compiled executable size (RAM/ROM) is dependent on the link process. You must configure the linker to include only required object files.

To generate the zip file manually, in the MATLAB Command Window:

  1. Load the buildInfo.mat file, located in the build folder for the model.

  2. Enter the command packNGo(buildInfo).

For more information about using the packNGo utility, see Relocating Code to Another Development Environment in the Simulink documentation.

Integrating Generated Code into Existing System

A full embedded controls system has multiple components, both hardware and software. Control algorithms are just one type of component. The other standard types of components include:

In general, code is not generated for any of these components. Instead, you develop interfaces that connect the components. MathWorks provides hardware interface block libraries for many common embedded controllers. For details, see the block libraries under Embedded Targets.

Setting Up Main Function

For this tutorial, you modify a supplied main function to build a full system. The main function performs basic actions to exercise the code for a simple system. It is not an example of an actual application main function.

  1. Copy files for the example main function to your working folder. The files are in matlabroot/toolbox/rtw/rtwdemos/EmbeddedCoderOverview/externenv_files. matlabroot represents the name of your MATLAB installation folder.

  2. Open and examine the code in the file example_main.c.

      Note   For the example_main.c file, name your copy of the model file rtdemo_throttlecntrl_externenv.mdl asthrottlecntrl_externenv.mdl.

    #include <stdio.h>              /* This ert_main.c example uses printf/fflush */
    #include "throttlecntrl_externenv.h"             /* Model's header file */
    #include "rtwtypes.h"                  /* MathWorks types */
    #include "throttlecntrl_externenv_private.h"     /* Local data for PCG Eval */
    #include "defineImportedData.h"        /* The inputs to the system */
    
    
    /* Observable signals */
    static BlockIO_throttlecntrl_externenv throttlecntrl_externenv_B;
    /* Observable states */
    static D_Work_throttlecntrl_externenv throttlecntrl_externenv_DWork;
    
    real_T pos_cmd_one;                    /* '<Root>/Signal Conversion1' */
    real_T pos_cmd_two;                    /* '<Root>/Signal Conversion2' */
    ThrottleCommands ThrotComm;            /* '<Root>/Pos_Command_Arbitration' */
    ThrottleParams Throt_Param;            /* '<S1>/Bus Creator' */
    
    
    int simulationLoop = 0;
    
    int_T main(void)
    {
      /* Initialize model */
      rt_Pos_Command_Arbitration_Init(); /* Set up the data structures for chart*/
      throttle_cnt_Define_Throt_Param(); /* SubSystem: '<Root>/Define_Throt_Param' */
      defineImportData();                /* Defines the memory and values of inputs */
      
      do /* This is the "Schedule" loop.  
          Functions would be called based on a scheduling algorithm */
      {
        /* HARDWARE I/O */
          
      	/* Call control algorithms */
        PI_Cntrl_Reusable((*pos_rqst),fbk_1,&throttlecntrl_externenv_B.PI_ctrl_1,
                           &throttlecntrl_externenv_DWork.PI_ctrl_1);
        PI_Cntrl_Reusable((*pos_rqst),fbk_2,&throttlecntrl_externenv_B.PI_ctrl_2,
                           &throttlecntrl_externenv_DWork.PI_ctrl_2);
        pos_cmd_one = throttlecntrl_externenv_B.PI_ctrl_1.Saturation1;
        pos_cmd_two = throttlecntrl_externenv_B.PI_ctrl_2.Saturation1;
       
        throttle_Pos_Command_Arbitration(pos_cmd_one, &Throt_Param, pos_cmd_two,
                         &throttlecntrl_externenv_B.sf_Pos_Command_Arbitration);
        
    
     	
      	simulationLoop++;
      } while (simulationLoop < 2);
      return 0;
    }

    Identify areas of the code that perform each of the following functions:

    • Defines function interfaces (function prototypes)

    • Includes required files for data definition

    • Defines extern data

    • Initializes data

    • Calls simulated hardware

    • Calls algorithmic functions

  3. Close example_main.c.

The order of execution of functions in example_main.c matches the order in which the test harness model and throttlecntrl_externenv.h call the subsystems. If you change the order of execution in example_main.c, results from the executable image differ from simulation results.

Matching System Interfaces

Integration requires matching the data and function interfaces of the generated code and the existing system code. In this example, the example_main.c file defines the data with #include statements and calls the functions from the generated code.

  1. Specify input data.

    The system has three input signals: pos_rqst, fbk_1, and fbk_2. The two feedback signals are imported externs (ImportedExtern) and the position signal is an imported extern pointer (ImportedExternPointer). Because of how the signals are defined, the code generator does not create variables for them. Instead, the signal variables are defined in a file that is external to the MATLAB environment.

    1. Open your copy of the file defineImportedData.c.

      /* Define imported data */
      #include "rtwtypes.h"
      real_T fbk_1;
      real_T fbk_2;
      real_T dummy_pos_value = 10.0;
      real_T *pos_rqst;
      void defineImportData(void)
      {
          	pos_rqst = &dummy_pos_value;
      }	
      

      This file contains code for a simple C stub that defines the signal variables. The generated code has access to the data from the extern definitions in your generated throttlecntrl_externenv_Private.h file. In a real system, the data comes from other software components or from hardware devices.

    2. Close defineImportedData.c.

    3. In your build folder, open throttlecntrl_externenv_Private.h.

    4. Find and examine the following extern definitions.

      /* Imported (extern) block signals */
      extern real_T fbk_1;                   /* '<Root>/fbk_1' */
      extern real_T fbk_2;                   /* '<Root>/fbk_2' */
      
      /* Imported (extern) pointer block signals */
      extern real_T *pos_rqst;               /* '<Root>/pos_rqst' */
    5. Close throttlecntrl_externenv_Private.h.

  2. Specify output data.

    You do not have to do anything with the output data. However, you can access the data in your generated throttlecntrl_externenv.h file.

    1. In your build folder, open throttlecntrl_externenv.h

    2. Examine the contents of the file.

    3. Close throttlecntrl_externenv.h.

    Verifying Generated Code shows how to save the output data to a log file.

  3. Identify additional data.

    The code generator creates several data elements that you do not need to access to complete this tutorial. Such data elements include:

    • Block state values (integrator, transfer functions)

    • Local parameters

    • Time

    For this tutorial, the throttlecntrl_externenv.h file declares this data.

    1. In your build folder, open throttlecntrl_externenv.h

    2. Search the file for the data listed in the following table. The table lists the most common data structures. Depending on the configuration of the model, some or all of these structures are in the generated code.

      Data TypeData NameData Purpose
      Constantsthrottlecntrl_externenv_cPConstant parameters
      Constantsthrottlecntrl_externenv_cBConstant block I/O
      Outputthrottlecntrl_externenv_URoot and atomic subsystem input
      Outputthrottlecntrl_externenv_YRoot and atomic subsystem output
      Internal datathrottlecntrl_externenv_BValue of block output
      Internal datathrottlecntrl_externenv_DState information vectors
      Internal datathrottlecntrl_externenv_MTime and other system level data
      Internal datathrottlecntrl_externenv_ZeroZero-crossings
      Parametersthrottlecntrl_externenv_PParameters

    3. Close throttlecntrl_externenv.h.

  4. Match the function-call interface.

    By default, the code generator creates functions that have a void Func(void) interface. If you configure the model or an atomic subsystem as reentrant code, the code generator creates a more complex function prototype.

    1. Open your copy of example_main.c.

    2. The example_main function is configured to call the functions.

      throttlecntrl_externenv_B.sf_Pos_Command_Arbitration);
                         ((*pos_rqst),fbk_1,&throttlecntrl_externenv_B.PI_ctrl_1,
                         &throttlecntrl_externenv_DWork.PI_ctrl_1);
      PI_Cntrl_Reusable((*pos_rqst),fbk_2,&throttlecntrl_externenv_B.PI_ctrl_2,
                         &throttlecntrl_externenv_DWork.PI_ctrl_2);
      pos_cmd_one = throttlecntrl_externenv_B.PI_ctrl_1.Saturation1;
      pos_cmd_two = throttlecntrl_externenv_B.PI_ctrl_2.Saturation1;
      
      throttlePos_Command_Arbitration(pos_cmd_one, &Throt_Param, pos_cmd_two, 
                         &throttlecntrl_externenv_B.sf_Pos_Command_Arbitration);

    Calls to the PI_Cntrl_Reusable function use a mixture of user-defined variables and default data structures. The build process defines data structures in throttlecntrl_externenv.h. The preceding code fragment also shows how the data structures map to user-defined variables.

Building Project in Eclipse Environment

This tutorial uses the Eclipse IDE to build the embedded system.

  1. Create a build folder on your C drive. Name the folder such that the path contains no spaces (for example, EclipseProjects/throttlecntrl/externenv). For this tutorial and Verifying Generated Code, you use the Cygwin Debugger, which requires that your build folder be on your C drive and the folder path not include spaces.

  2. Unzip the file throttlecntrl_externenv.zip into the build folder you just created.

  3. Delete the files ert_main.c and throttlecntrl_externenv.c. Then, add example_main.c that you examined in Setting Up Main Function.

  4. Use the Eclipse Integrated Development Environment (IDE) and Cygwin Debugger to step through and evaluate the execution behavior of the generated C code. For instructions on installing the IDE, creating a new project, and configuring the debugger, see Installing and Using an IDE for the Integration and Testing Tutorials.

  5. Close throttlecntrl_externenv.mdl.

Key Points

Learn More

  


Related Products & Applications

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.

 © 1984-2012- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS