Integrate Generated Code with Custom Code in External Environment

Identify required files and interfaces for calling generated code in an external build process.

Learn how to:

  • Collect files required for building outside of Simulink®

  • Interface with external variables and functions

For information about the example model and other examples in this series, see Generate C Code from a Control Algorithm for an Embedded System.

Collect and Build Required Data and Files

The code that Embedded Coder® generates requires support files that are provided by MathWorks®. To relocate the generated code to another development environment, such as a dedicated build system, you must also relocate these support files. You can package all of these files in a zip file by using the packNGo utility. This utility finds and packages the files that you need to build an executable image. The utility uses tools for customizing the build process after code generation, which include a buildinfo_data structure, as well as a packNGo function. These files include external files that you identify in the Code Generation > Custom Code pane in the Model Configuration Parameters dialog box. The utility saves the buildinfo MAT-file in the model_ert_rtw folder.

Open the example model, rtwdemo_PCG_Eval_P5.

This model is configured to run packNGo after code generation.

Generate code from the entire model.

To generate the zip file manually:

  1. Load the file buildInfo.mat (located in the rtwdemo_PCG_Eval_P5_ert_rtw subfolder).

  2. At the command prompt, enter the command packNGo(buildInfo).

The number of files in the zip file depends on the version of Embedded Coder® and on the configuration of the model that you use. The compiler does not require all of the files in the zip file. The compiled executable size (RAM/ROM) depends on the link process. The linker likely includes only the object files that are necessary.

Integrating the Generated Code into an Existing System

This example shows how to integrate the generated code into an existing code base. The example uses the Eclipse™ IDE and the Cygwin™/gcc compiler. The required integration tasks are common to all integration environments.

Overview of Integration Environment

A full embedded controls system consists of multiple hardware and software components. Control algorithms are just one type of component. Other components can be:

  • An operating system (OS)

  • A scheduling layer

  • Physical hardware I/O

  • Low-level hardware device drivers

Typically, you do not use the generated code in these components. Instead, the generated code includes interfaces that connect with these components. MathWorks® provides hardware interface block libraries for many common embedded controllers. For examples, see the Embedded Targets block library.

This example provides files to show how you can build a full system. The main file is example_main.c, which contains a simple main function that performs only basic actions to exercise the code.

View example_main.c.

The file:

  • Defines function interfaces (function prototypes)

  • Includes files that declare external data

  • Defines extern data

  • Initializes data

  • Calls simulated hardware

  • Calls algorithmic functions

The order of function execution matches the order of subsystem execution in the test harness model and in rtwdemo_PCG_Eval_P5.h. If you change the order of execution in example_main.c, results that the executable image produces differ from simulation results.

Match System Interfaces

Integration requires matching both the Data and Function interfaces of the generated code and the existing system code. In this example, the example_main.c file imports and exports the data through #include statements and extern declarations. The file also calls the functions from the generated code.

Connect Input Data

The system has three input signals: pos_rqst, fbk_1, and fbk_2. The generated code accesses the two feedback signals through direct reference to imported global variables (storage class ImportedExtern). The code accesses the position signal through an imported pointer (storage class ImportedExternPointer).

The handwritten file defineImportedData.c defines the variables and the pointer. The generated code does not define the variables and the pointer because the handwritten code defines them. Instead, the generated code declares the imported data (extern) in the file rtwdemo_PCG_Eval_P5_Private.h. In a real system, the data typically come from other software components or from hardware devices.

View defineImportedData.c.

View rtwdemo_PCG_Eval_P5_Private.h.

Connect Output Data

In this example, you do not access the output data of the system. The example Test Generated Code shows how you can save the output data to a standard log file. You can access the output data by referring to the file rtwdemo_PCG_Eval_P5.h.

View rtwdemo_PCG_Eval_P5.h.

Access Additional Data

The generated code contains several structures that store commonly used data including:

  • Block state values (integrator, transfer functions)

  • Local parameters

  • Time

The table lists the common data structures. Depending on the configuration of the model, some or all of these structures appear in the generated code. The data is declared in the file rtwdemo_PCG_Eval_P5.h, but in this example, you do not access this data.

Data Type      Data Name     Data Purpose
Constants      |model_cP|    Constant parameters
Constants      |model_cB|    Constant block I/O
Output         |model_U|     Root and atomic subsystem input
Output         |model_Y|     Root and atomic subsystem output
Internal data  |model_B|     Value of block output
Internal data  |model_D|     State information vectors
Internal data  |model_M|     Time and other system level data
Internal data  |model_Zero|  Zero-crossings
Parameters     |model_P|     Parameters

Match Function Call Interfaces

By default, functions that the code generator generates have a void Func(void) interface. If you configure the model or atomic subsystem to generate reentrant code, the code generator creates a more complex function prototype. In this example, the example_main function calls the generated functions with the correct input arguments.

Calls to the function PI_Cntrl_Reusable use a mixture of separate, unstructured global variables and Simulink® Coder™ data structures. The handwritten code defines these variables. The structure types are defined in rtwdemo_PCG_Eval_P5.h.

Build Project in Eclipse™ Environment

This example uses the Eclipse™ IDE and the Cygwin™ GCC debugger to build the embedded system. The example provides installation files for both programs. Software components and versions numbers are:

  • Eclipse™ SDK 3.2

  • Eclipse™ CDT 3.3

  • Cygwin™/GCC 3.4.4-1

  • Cygwin™/GDB 20060706-2

To install and use Eclipse™ and GCC, see Install and Use Cygwin and Eclipse.

You can install the files for this example automatically by clicking this hyperlink.

Set up the build folder.

Alternatively, to install the files manually:

  1. Create a build folder (Eclipse_Build_P5).

  2. Unzip the file into the build folder.

  3. Delete the files rtwdemo_PCG_Eval_P5.c, ert_main.c and rt_logging.c, which are replaced by example_main.c.

Note: Before continuing to the next example in the series, if you have not generated code for the model or if the zip file does not exist, complete the steps in Collect and Build Required Data and Files.

You can use the Eclipse™ debugger to step through and evaluate the execution behavior of the generated C code. See the example Install and Use Cygwin and Eclipse.

The next example in this series, Test Generated Code, shows how to exercise the model with input data.

More About

Was this topic helpful?