Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档 > MATLAB技术文章
MATLAB技术文章 MATLAB Technical Articles From Mathworks
 
 
主题工具 显示模式
旧 2008-01-06, 16:32   #1
TechnicalArticles
游客
 
帖子: n/a
默认 Legacy Code Function Integration Using Real-Time Workshop Embedded Coder

Legacy Code Function Integration Using Real-Time Workshop Embedded Coder


by Tom Erkkinen and Eric Dillaber
This is the second in a series of articles dealing with legacy code. The previous article, which appeared in the May 2004 issue of the MATLAB Digest, examined legacy code data. This article describes legacy function integration technologies for importing and exporting code generated by Real-Time Workshop Embedded Coder. (Integration of code for simulation is not described here.)
The following sections describe legacy function integration topics:
  • Exporting generated code into legacy code
  • Importing legacy code into generated code
Note: The material and examples in this article use features of products in MathWorks Release 14 with Service Pack 1.
Model Description

Figure 1 shows a model that demonstrates 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.

Figure 1. Built-in-test sensor fault model (BIT_sensor_fault.mdl).
Click on image to see enlarged view.


In our previous article, we used this model to describe methods for importing and exporting the model signals and parameters. In this article we use this model and the comparator subsystem to illustrate how to import and export functions involving Simulink and legacy code.
Exporting Generated Code into Legacy Code

You may want to export code automatically generated from Simulink models and integrate it into your legacy application. For example, you may have a large hand-coded application that is shipping (and validated) in a production program. If you are working on a new project that requires small changes to the existing application, you may not want to integrate the full code base into Simulink at this point. Exporting the code generated from models lets you model just one new algorithm at a time, automatically generate code for it, and properly call the generated code function(s) from the existing application.
Callable functions in the generated code (referred to as entry points) enable code to be exported. Examples of model entry points include the model_initialize, model_step, and model_terminate functions. These functions let you initialize, step through, and terminate the generated code, respectively. You gain access to entry points through the generated model.h file. To call entry-point functions, you must add an #include model.h directive and then properly invoke the entry point from your hand-written application.
You need to know the exact function call signature in order to call the entry point properly. It is important to consider whether the generated code must be reusable. Reusable (reentrant) code is important when you require multiple instances of a single model. For example, a sensor validation or filtering algorithm with states may require a separate instance for each sensor that is processed. To support reentrancy, the states, parameters, and I/O for each instance are passed in separately. Reentrant code can also enable an algorithm to be reused such that data parameters can be easily interchanged.
The generated code is neither reusable nor reentrant by default; it simply passes data to and from functions, using global memory. You can change the default behavior and make entry points reusable by using the Real-Time Workshop Embedded Coder option Generate reusable code. This feature lets you pass root-level I/O into the reusable code as individual arguments or structures. As a result, you can change the function call signature.
Figure 2 shows how to use Generate reusable code to generate the following code.
BIT_sensor_fault.c (with Generate reusable code disabled) /* Model step function */
void BIT_sensor_fault_step(void)
BIT_sensor_fault.c (with Generate reusable code enabled to pass structures) /* Model step function */
void BIT_sensor_fault_step(ExternalInputs_BIT_sensor_fault *BIT_sensor_fault_U, ExternalOutputs_BIT_sensor_fault *BIT_sensor_fault_Y)

Figure 2. Using the Generate reusable code option.
Click on image to see enlarged view.

The Real-Time Workshop Embedded Coder User Guide section “A Guide to the ERT Target Options::Interface Pane” describes Generate reusable code restrictions, related options, and additional features. (You should have a detailed understanding of these options before attempting to export automatically generated code into your legacy application.)
Subsystem reuse is a technology related to model reuse. A reusable subsystem generates a single shared function that can be called multiple times for a subsystem. In addition to supporting reentrancy, subsystem reuse consolidates code, significantly improving the size and efficiency of generated code.
To enable code reuse open the Block Parameters dialog box and select both Treat as atomic unit and Reusable function from the RTW system code pull-down menu. You can also name the generated function and file into which the function is placed, as illustrated in Figure 3.
reusable_comparator_file.c /* Output and update for atomic system: '/comparator' */
void reusable_comparator(rtB_reusable_comparator *localB)

Figure 3. Using the reusable subsystem option. In the block diagram, the reusable subsystem has a bold outline to clarify that it is an atomic unit. Click on image to see enlarged view.
Importing Legacy Code into Generated Code

Simulink has two primary utilities that allow you to quickly insert custom (legacy) code into generated code: the Custom Code dialog and Custom Code blocks. They change the generated code but do not support simulation of the legacy code. (The mechanisms that support importing legacy code for simulation and code generation are beyond the scope of this article.)
The new Model Explorer in Simulink 6 provides a Custom Code dialog that lets you import functions within the generated code. Code fragments that you insert via the Custom Code dialog produce the same code in the generated C files. You can also use the Custom Code dialog to specify additional files and paths to be included in the code build process. Custom Code dialogs provide access to key points during the code execution and offer an easy way to insert specialized routines that must be invoked at startup or shutdown, such as those involving hardware initialization or termination.
The top pane of the Custom Code dialog lets you place legacy code in the following files and sections of the generated code:
  • Source file—Code is placed near the top of the generated model.c
    file, outside of any function.
  • Header file—Code is placed near the top of the generated model.h
    file.
  • Initialize function—Code is placed inside the model's initialize function in the model.c
    file.
  • Terminate function—Code is placed inside the model's terminate function in the model.c
    file.
Figure 4 shows how to use the Custom Code dialog to call a custom safe shutdown function, close_devices, in the generated code. The Real-Time Workshop Embedded Coder code interface option Terminate function required (the default) must be enabled for this example to work correctly.
BIT_sensor_fault.c /* Model terminate function */
void BIT_sensor_fault_terminate(void)
{ /* user code (Terminate function Body) */
/* Custom function to properly shutdown hardware */
close_devices();
}

Figure 4. Using the Custom Code dialog in the Model Explorer. Use the bottom pane in the Custom Code dialog to add additional directory paths, sources files, and libraries to the build process. Click on image to see enlarged view.
Figure 5 shows Custom Code blocks, which are closely related to the Custom Code dialog. These blocks insert custom code into generated code files and functions. The two model blocks have text fields that let you specify code to be inserted at the top or bottom of the header and source files. The eight system blocks contain text fields that let you insert custom code sections at the declarations, execution, and exit sections of the designated system functions.
The Custom Code blocks provide you with more control over placement of custom code than the Custom Code dialog. You must manually add Custom Code blocks to your Simulink block diagrams (this process is not automatic).

Figure 5. Accessing the Custom Code blocks in the Real-Time Workshop Library.
Click on image to see enlarged view.


Using an Extensible API to Import Custom Code

You can also import custom code using an extensible API provided by Real-Time Workshop Embedded Coder. This API lets you customize the generated code and generate additional files and functions.
The File Customization Template option, located on the Real-Time Workshop Embedded Coder Templates dialog, lets you specify a custom script that is executed at the end of the code generation process. From this script, you can automatically generate or import additional code to interface with your application.
To see this API in action, run the demo model rtwdemo_fileprocess, included with the Real-Time Workshop Embedded Coder demos.
To see a collection of all demos related to legacy code integration, find the demo library rtwdemos and select CustomCode library.
For more information, see the Simulink and Real-Time Workshop Embedded Coder product documentation.


更多...
  回复时引用此帖
 


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 19:42


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.