TechnicalArticles
2008-01-06, 16:32
Integrate Legacy Code for Simulation and Embedded Code Generation with the Legacy Code Tool
by Tom Erkkinen ([email protected]), Eric Dillaber ([email protected]), and Emmanuel Roy ([email protected])
Simulink (http://www.mathworks.com/products/simulink/) and Real-Time Workshop Embedded Coder (http://www.mathworks.com/products/rtwembedded/) let you simulate, automatically generate, and deploy software applications onto embedded systems using Model-Based Design (http://www.mathworks.com/products/featured/embeddedsys.html). You can generate and build an entire application based solely on Simulink models. However, most software development organizations require incorporation of legacy code (i.e., existing code) into portions of their application. Examples include math utilities, specialized filters, table lookups, and low-level device drivers. Legacy code integration is a complex problem where no single solution fits all cases.
This is the third in a series of articles dealing with legacy code. The previous article (http://www.mathworks.com/company/newsletters/digest/nov04/legacy.html) in this series described how to import and export code generated by Real-Time Workshop Embedded Coder with legacy code but it did not address simulation of the legacy code within Simulink. This article describes integration of code for simulation and code generation and introduces a new code integration technology, the Legacy Code Tool. (The tool is available on MATLAB Central (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6797&objectType=FILE). This article provides installation procedures.)
The following sections describe legacy function integration topics:
Model and legacy code example description (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#desc)
Legacy code overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview)
Legacy code integration options (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#options)
Legacy Code Tool (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#tool) Note: The material and examples in this article are based on MathWorks Release 14 with Service Pack 1.
Model and Legacy Code Example Description
Figure 1 shows a model that we will use to demonstrate legacy code integration. The inputs represent raw data values from primary and backup input sensors. The model converts the raw sensor input values to counts and removes known sensor bias. A comparator validates the primary signal by comparing it to the backup signal. Then the primary sensor value and its validity flag are assigned to outputs.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/sensorfault_model_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/sensorfault_model_wl.gif) Figure 1. Built-in-test sensor fault model (BIT_sensor_fault.mdl).
Click on image to see enlarged view.
In a previous article, we used this model to describe how to import and export functions involving legacy code and generated code, but without simulation support. In this article we will use the example to illustrate how to import legacy functions into Simulink for both simulation and code generation. We will replace the comparator subsystem with a legacy code version of the comparator that returns additional information in the status word. The legacy code comparator compares two inputs and returns an output indicating whether the comparison passed, failed low, or failed high (see Figure 2).
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_comparator_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_comparator_wl.gif) Figure 2. Legacy code (comparator.c).
Click on image to see enlarged view.
Legacy Code Overview
To import legacy code into Simulink for simulation and code generation, you must provide Simulink with an appropriate function call interface, or signature, for the legacy code. Code dependencies such as header files and legacy data type definitions must also be specified and linked in as appropriate. You can organize legacy code functions into categories to help you understand code dependencies and derive a common set of legacy code integration requirements.
We will organize legacy functions into three categories:
Device drivers (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#device)
General functions and interfaces (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#general)
Lookup tables (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#lookup) Device Drivers
Device drivers provide access to the embedded hardware peripheral devices, typically through reading and writing of internal or external hardware registers. Examples of embedded hardware devices include input devices such as analog-to-digital converters (ADC), output devices such as pulse-width-modulators (PWM), and network interfaces such as Controller Area Network (CAN). Interfaces to device drivers range from a simple memory access for an ADC to a sophisticated message passing and synchronization protocol for a network interface.
General Functions and Interfaces
General functions are software utilities that perform frequent tasks in a complete application. Examples include special filters, specialized math utilities, and optimized PID controllers. The comparator in our example is a general legacy function.
Interfaces provide methods for interacting with other layers of software in a complete application. Examples include real-time operating systems or middleware. These functions are sometimes called directly or are accessed through a generalized set of APIs.
Lookup Tables
A lookup table is one of the most common examples of legacy code used in production applications. Lookup tables are often developed in-house and optimized for the type of applications that a software organization develops. The table data formatting and lookup algorithms vary widely. The differences are often driven by the requirement to support calibration and parameter-tuning activities that rely on specialized tools and file formats.
While each of these legacy code categories is unique, they share many similar requirements. When you understand the requirements, you can determine a legacy code integration technology that uses the appropriate MathWorks tools.
Interfaces to the legacy code functions we described may require support for:
Hardware dependencies
Specifying simulation and code generation behaviors
Input, output, and parameter passing
Support for basic (MATLAB built-in) data types
Support for special data types and data formatting
Support for reentrant functions involving persistent data (e.g., states)
Support for reusable functions (multiple calls of single function) In practice, any given function, independent of the category, may require all of the requirements listed above or have other software requirements not represented here. Such is the nature of legacy code integration.
Legacy Code Integration Options
With Model-Based Design it is important that the simulation behavior of the model match that of the generated code, otherwise your final product may not satisfy its executable specification. The MathWorks provides the S-Function as the primary mechanism for importing legacy code in a manner that supports simulation using Simulink and code generation using Real-Time Workshop. See the Simulink documentation (http://www.mathworks.com/access/helpdesk/help/toolbox/simulink/) for more information about S-Functions and the S-Function Builder.
The S-Function provides a block that lets you specify the legacy function to be called along with all necessary inputs, outputs, states, and parameters. The S-Function requires interfaces to be built including a C program (.c and .h files), which is employed for simulation, and usually a template (.tlc file) to control how the generated code invokes the legacy code.
There are several ways to build an S-Function, including:
Handcrafted S-function—You manually write the S-function interfaces.
S-Function Builder—You specify legacy system information using a Simulink block, which then automatically builds the S-function interfaces.
Legacy Code Tool—You specify legacy code information using an M-file, which then automatically builds the S-function interfaces optimized for embedded applications. An extremely powerful and flexible technology, the S-Function can be used to integrate a complete system using sets of equations that describe initialization, output, derivative, and state update mathematics. The S-Function then interacts with the Simulink simulation environment, which takes care of block sorting, type propagation, solving, and integration of continuous and discrete state equations.
However, many of the system information sections and specification fields within handcrafted S-functions and the S-Function Builder are superfluous for integrating legacy code functions used in an embedded system, such as the categories described in the Legacy Code Overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview).
The Legacy Code Tool is a utility that provides a simple way to integrate legacy code while building a more optimized code interface. Unlike the S-Function Builder, the Legacy Code Tool does not generate extra interface code that wraps the legacy code. Handcrafted S-Functions and, to a lesser extent, the S-Function Builder offer a great deal of flexibility in terms of what types of code you can integrate (for example, continuous-time equations used for plant modeling). Table 1 compares the three S-Function options.
Handcrafted S-Function S-Function Builder Legacy Code Tool Ease of Use Low Mid High Application and Language Support High
Hybrid systems (plant and controller). Ada , C, C++, Fortran, and MATLAB. Mid
Hybrid systems (plant and controller). C only. Low
Digital controllers/signal processing (drivers, tables, functions). C only. Simulink Feature Support and Flexibility High
Supports widest range of Simulink features and capabilities. Mid
Some constraints such as no expression folding, dynamic data types/ports, others. Mid-Low
Has expression folding and features key to embedded code but less general feature support. Generated Code Optimization Varies
Experts can produce optimized interface code. Low
Code is not optimized because wrapper is generated. High
Code is optimized and no wrapper generated. Table 1. Distinguishing features and characteristics of S-Function options.
Legacy Code Tool
The Legacy Code Tool supports many of the requirements described in the Legacy Code Overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview) including hardware dependencies; simulation and code generation integration; input, output, and parameter passing; and basic data types. The installation procedure and example usage for the Legacy Code Tool are as follows.
Installation Procedure
The Legacy Code Tool installation package is available on MATLAB Central for you to download and start using. Check regularly for updates based on user feedback. To install the Legacy Code Tool, take the following 6 steps.
Download the current version of the ZIP file (e.g., lctV1.0.zip) from MATLAB Central (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6797&objectType=FILE).
Unzip lctV1.0.zip to a directory of your choosing using an appropriate ZIP program. If you are using MATLAB and want to unzip the program into a folder named lctdir, type: unzip('lctV1.0.zip','lctdir')
Verify the installation by examining the directory. You will see several new files along with test models and legacy code.
In MATLAB, change to the lct/lct folder in the install directory and run lct_setup.m to add the required MATLAB paths. For example, >> cd lctdir/lct/lct
>> lct_setup
Open the MATLAB Preferences dialog from the File menu, and select General. If Enable toolbox path cache is selected, click on Update Toolbox Path Cache.
To test the install and learn details about the tool, type legacy_code('help') in MATLAB. >> legacy_code('help') This article demonstrates the Legacy Code Tool using MathWorks Release 14 with Service Pack 1, however, the tool supports Release 13 with Service Pack 1 and higher.
Using the Legacy Code Tool
You can follow a simple procedure to use the Legacy Code Tool. For each step described here, we illustrate the procedure as applied to the comparator example from the Model and Legacy Code Example Description section.
Step 1: Create a MATLAB file to register the information required to invoke the legacy function (e.g., function name, number of arguments, data types, dependency files, etc.). Then add the appropriate Legacy Code Tool APIs to automatically generate the S-Function interfaces as shown in Figure 3.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/regfile_comparator_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/regfile_comparator_wl.gif)
Figure 3. Registration file for comparator (comparator.m). Click on image to see enlarged view.
Step 2: Build S-Function interfaces by invoking the registration file. We used the following command to invoke the registration file for the comparator: >> comparator
Step 3: Add an S-Function block to the diagram and reference the generated S-Function interface (sfun_comparator) as shown in Figure 4.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/builtin_test_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/builtin_test_wl.gif)
Figure 4. Built-in-test model with legacy code (BIT_sensor_fault_legacy.mdl).
Click on image to see enlarged view.
Step 4: Simulate the model and generate the code. Inspect the code and note that it has the appropriate function call as shown in Figure 5.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_code_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_code_wl.gif)
Figure 5. Generated code with legacy code call. Click on image to see enlarged view.
For more information:
To view all demos related to legacy code integration, type rtwdemos within MATLAB and select the Custom Code library.
Contact the authors with additional comments or questions regarding the Legacy Code Tool.
更多... (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html)
by Tom Erkkinen ([email protected]), Eric Dillaber ([email protected]), and Emmanuel Roy ([email protected])
Simulink (http://www.mathworks.com/products/simulink/) and Real-Time Workshop Embedded Coder (http://www.mathworks.com/products/rtwembedded/) let you simulate, automatically generate, and deploy software applications onto embedded systems using Model-Based Design (http://www.mathworks.com/products/featured/embeddedsys.html). You can generate and build an entire application based solely on Simulink models. However, most software development organizations require incorporation of legacy code (i.e., existing code) into portions of their application. Examples include math utilities, specialized filters, table lookups, and low-level device drivers. Legacy code integration is a complex problem where no single solution fits all cases.
This is the third in a series of articles dealing with legacy code. The previous article (http://www.mathworks.com/company/newsletters/digest/nov04/legacy.html) in this series described how to import and export code generated by Real-Time Workshop Embedded Coder with legacy code but it did not address simulation of the legacy code within Simulink. This article describes integration of code for simulation and code generation and introduces a new code integration technology, the Legacy Code Tool. (The tool is available on MATLAB Central (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6797&objectType=FILE). This article provides installation procedures.)
The following sections describe legacy function integration topics:
Model and legacy code example description (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#desc)
Legacy code overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview)
Legacy code integration options (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#options)
Legacy Code Tool (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#tool) Note: The material and examples in this article are based on MathWorks Release 14 with Service Pack 1.
Model and Legacy Code Example Description
Figure 1 shows a model that we will use to demonstrate legacy code integration. The inputs represent raw data values from primary and backup input sensors. The model converts the raw sensor input values to counts and removes known sensor bias. A comparator validates the primary signal by comparing it to the backup signal. Then the primary sensor value and its validity flag are assigned to outputs.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/sensorfault_model_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/sensorfault_model_wl.gif) Figure 1. Built-in-test sensor fault model (BIT_sensor_fault.mdl).
Click on image to see enlarged view.
In a previous article, we used this model to describe how to import and export functions involving legacy code and generated code, but without simulation support. In this article we will use the example to illustrate how to import legacy functions into Simulink for both simulation and code generation. We will replace the comparator subsystem with a legacy code version of the comparator that returns additional information in the status word. The legacy code comparator compares two inputs and returns an output indicating whether the comparison passed, failed low, or failed high (see Figure 2).
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_comparator_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_comparator_wl.gif) Figure 2. Legacy code (comparator.c).
Click on image to see enlarged view.
Legacy Code Overview
To import legacy code into Simulink for simulation and code generation, you must provide Simulink with an appropriate function call interface, or signature, for the legacy code. Code dependencies such as header files and legacy data type definitions must also be specified and linked in as appropriate. You can organize legacy code functions into categories to help you understand code dependencies and derive a common set of legacy code integration requirements.
We will organize legacy functions into three categories:
Device drivers (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#device)
General functions and interfaces (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#general)
Lookup tables (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#lookup) Device Drivers
Device drivers provide access to the embedded hardware peripheral devices, typically through reading and writing of internal or external hardware registers. Examples of embedded hardware devices include input devices such as analog-to-digital converters (ADC), output devices such as pulse-width-modulators (PWM), and network interfaces such as Controller Area Network (CAN). Interfaces to device drivers range from a simple memory access for an ADC to a sophisticated message passing and synchronization protocol for a network interface.
General Functions and Interfaces
General functions are software utilities that perform frequent tasks in a complete application. Examples include special filters, specialized math utilities, and optimized PID controllers. The comparator in our example is a general legacy function.
Interfaces provide methods for interacting with other layers of software in a complete application. Examples include real-time operating systems or middleware. These functions are sometimes called directly or are accessed through a generalized set of APIs.
Lookup Tables
A lookup table is one of the most common examples of legacy code used in production applications. Lookup tables are often developed in-house and optimized for the type of applications that a software organization develops. The table data formatting and lookup algorithms vary widely. The differences are often driven by the requirement to support calibration and parameter-tuning activities that rely on specialized tools and file formats.
While each of these legacy code categories is unique, they share many similar requirements. When you understand the requirements, you can determine a legacy code integration technology that uses the appropriate MathWorks tools.
Interfaces to the legacy code functions we described may require support for:
Hardware dependencies
Specifying simulation and code generation behaviors
Input, output, and parameter passing
Support for basic (MATLAB built-in) data types
Support for special data types and data formatting
Support for reentrant functions involving persistent data (e.g., states)
Support for reusable functions (multiple calls of single function) In practice, any given function, independent of the category, may require all of the requirements listed above or have other software requirements not represented here. Such is the nature of legacy code integration.
Legacy Code Integration Options
With Model-Based Design it is important that the simulation behavior of the model match that of the generated code, otherwise your final product may not satisfy its executable specification. The MathWorks provides the S-Function as the primary mechanism for importing legacy code in a manner that supports simulation using Simulink and code generation using Real-Time Workshop. See the Simulink documentation (http://www.mathworks.com/access/helpdesk/help/toolbox/simulink/) for more information about S-Functions and the S-Function Builder.
The S-Function provides a block that lets you specify the legacy function to be called along with all necessary inputs, outputs, states, and parameters. The S-Function requires interfaces to be built including a C program (.c and .h files), which is employed for simulation, and usually a template (.tlc file) to control how the generated code invokes the legacy code.
There are several ways to build an S-Function, including:
Handcrafted S-function—You manually write the S-function interfaces.
S-Function Builder—You specify legacy system information using a Simulink block, which then automatically builds the S-function interfaces.
Legacy Code Tool—You specify legacy code information using an M-file, which then automatically builds the S-function interfaces optimized for embedded applications. An extremely powerful and flexible technology, the S-Function can be used to integrate a complete system using sets of equations that describe initialization, output, derivative, and state update mathematics. The S-Function then interacts with the Simulink simulation environment, which takes care of block sorting, type propagation, solving, and integration of continuous and discrete state equations.
However, many of the system information sections and specification fields within handcrafted S-functions and the S-Function Builder are superfluous for integrating legacy code functions used in an embedded system, such as the categories described in the Legacy Code Overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview).
The Legacy Code Tool is a utility that provides a simple way to integrate legacy code while building a more optimized code interface. Unlike the S-Function Builder, the Legacy Code Tool does not generate extra interface code that wraps the legacy code. Handcrafted S-Functions and, to a lesser extent, the S-Function Builder offer a great deal of flexibility in terms of what types of code you can integrate (for example, continuous-time equations used for plant modeling). Table 1 compares the three S-Function options.
Handcrafted S-Function S-Function Builder Legacy Code Tool Ease of Use Low Mid High Application and Language Support High
Hybrid systems (plant and controller). Ada , C, C++, Fortran, and MATLAB. Mid
Hybrid systems (plant and controller). C only. Low
Digital controllers/signal processing (drivers, tables, functions). C only. Simulink Feature Support and Flexibility High
Supports widest range of Simulink features and capabilities. Mid
Some constraints such as no expression folding, dynamic data types/ports, others. Mid-Low
Has expression folding and features key to embedded code but less general feature support. Generated Code Optimization Varies
Experts can produce optimized interface code. Low
Code is not optimized because wrapper is generated. High
Code is optimized and no wrapper generated. Table 1. Distinguishing features and characteristics of S-Function options.
Legacy Code Tool
The Legacy Code Tool supports many of the requirements described in the Legacy Code Overview (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html#overview) including hardware dependencies; simulation and code generation integration; input, output, and parameter passing; and basic data types. The installation procedure and example usage for the Legacy Code Tool are as follows.
Installation Procedure
The Legacy Code Tool installation package is available on MATLAB Central for you to download and start using. Check regularly for updates based on user feedback. To install the Legacy Code Tool, take the following 6 steps.
Download the current version of the ZIP file (e.g., lctV1.0.zip) from MATLAB Central (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=6797&objectType=FILE).
Unzip lctV1.0.zip to a directory of your choosing using an appropriate ZIP program. If you are using MATLAB and want to unzip the program into a folder named lctdir, type: unzip('lctV1.0.zip','lctdir')
Verify the installation by examining the directory. You will see several new files along with test models and legacy code.
In MATLAB, change to the lct/lct folder in the install directory and run lct_setup.m to add the required MATLAB paths. For example, >> cd lctdir/lct/lct
>> lct_setup
Open the MATLAB Preferences dialog from the File menu, and select General. If Enable toolbox path cache is selected, click on Update Toolbox Path Cache.
To test the install and learn details about the tool, type legacy_code('help') in MATLAB. >> legacy_code('help') This article demonstrates the Legacy Code Tool using MathWorks Release 14 with Service Pack 1, however, the tool supports Release 13 with Service Pack 1 and higher.
Using the Legacy Code Tool
You can follow a simple procedure to use the Legacy Code Tool. For each step described here, we illustrate the procedure as applied to the comparator example from the Model and Legacy Code Example Description section.
Step 1: Create a MATLAB file to register the information required to invoke the legacy function (e.g., function name, number of arguments, data types, dependency files, etc.). Then add the appropriate Legacy Code Tool APIs to automatically generate the S-Function interfaces as shown in Figure 3.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/regfile_comparator_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/regfile_comparator_wl.gif)
Figure 3. Registration file for comparator (comparator.m). Click on image to see enlarged view.
Step 2: Build S-Function interfaces by invoking the registration file. We used the following command to invoke the registration file for the comparator: >> comparator
Step 3: Add an S-Function block to the diagram and reference the generated S-Function interface (sfun_comparator) as shown in Figure 4.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/builtin_test_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/builtin_test_wl.gif)
Figure 4. Built-in-test model with legacy code (BIT_sensor_fault_legacy.mdl).
Click on image to see enlarged view.
Step 4: Simulate the model and generate the code. Inspect the code and note that it has the appropriate function call as shown in Figure 5.
http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_code_w.gif (http://www.mathworks.com/company/newsletters/digest/2005/jan/images/legacy_code_wl.gif)
Figure 5. Generated code with legacy code call. Click on image to see enlarged view.
For more information:
To view all demos related to legacy code integration, type rtwdemos within MATLAB and select the Custom Code library.
Contact the authors with additional comments or questions regarding the Legacy Code Tool.
更多... (http://www.mathworks.com/company/newsletters/digest/2005/jan/legacy.html)