www.gusucode.com > ecoder 案例源码程序 matlab代码 > ecoder/PartitionFunctionsInGeneratedCodeExample.m
%% Partition Functions in the Generated Code % Associate subsystems in a model with function names and files. % % Learn how to: % % * Specify function and file names in the generated code. % * Identify the parts of the generated code that are required for % integration. % * Generate code for atomic subsystems. % * Identify data that are required to execute a generated function. % % For information about the example model and other examples in this % series, see <docid:ecoder_examples.example-rtwdemo_pcgd_stage_1_p1_script>. %% Atomic and Virtual Subsystems % The example models in <docid:ecoder_examples.example-rtwdemo_pcgd_stage_1_p1_script> % and <docid:ecoder_examples.example-rtwdemo_pcgd_stage_2_p1_script> % use _virtual subsystems_. Virtual subsystems % visually organize blocks but do not affect the model functionality % _Atomic subsystems_ evaluate all of the included blocks as a unit. % With atomic subsystems, you can specify additional function % partitioning information. In a model, atomic subsystems appear with a bold border. %% View Changes in Model Architecture % <matlab:RTWDemos.pcgd_open_pcg_model(3,0); Open the example model, % |rtwdemo_PCG_Eval_P3|>. % % Save a copy of the model to your current folder. % % This example shows how to replace the virtual subsystems % with _function call subsystems_. Function call subsystems: % % * Are atomic subsystems % * Enable you to control subsystem execution order % * Execute when a _function call signal_ triggers % % By controlling the execution order of the subsystems, you can match the model with an existing system that has a % specific execution order. % % The figure identifies the function call subsystems (1) |PI_ctrl_1|, % |PI_ctrl_2|, and |Pos_Command_Arbitration|. % % <<../stage_3_with_markup.jpg>> % % This version of the model contains the new subsystem |Execution_Order_Control| (2), which contains a % Stateflow(R) chart that models the calling functionality of a scheduler. % The subsystem % controls the execution order of the function call subsystems through function call signals (3). Later in % this example, you examine % how changing the execution order can change the simulation results. % % This version of the model contains new Signal Conversion blocks (4) at the outputs of the PI % controllers. With these additional blocks in place, the code generator can % generate a single reentrant function for the PI controllers. %% Control Function Location and File Placement in the Generated Code % In <docid:ecoder_examples.example-rtwdemo_pcgd_stage_1_p1_script> % and <docid:ecoder_examples.example-rtwdemo_pcgd_stage_2_p1_script>, % the code generator creates a single % |_model__step| function that contains all of the control algorithm code. However, many % applications require a greater level of control over the file placement of % functions. By modifying the parameters of atomic subsystems, you can % specify multiple functions within a single model. % % The figure shows the subsystem parameters for |PI_ctrl_1|. % % <<../TheAtomicSubsystem.png>> % % * *Treat as atomic unit*: Enables other submenus. For atomic subsystems, this parameter is automatically selected and disabled. % * *Sample time*: Specifies a sample time for execution. Not available for function-call subsystems. % * *Function packaging*: % % Auto Determines how the subsystem appears in the generated code. This value is the default. % % Inline Places the subsystem code inline with the rest of the model code. % % Function Generates the code for the subsystem as a function. % % Reusable function Generates a reusable (reentrant) function from the % subsystem. % The function passes all input and output data through formal parameters. % The function does not directly access global variables. % % * *Function name options*: Selecting |Function| or |Reusable function| for *Function packaging* enables function name options. % % Auto Determines the function. % % Use subsystem name Bases the function on the subsystem name. % % User specified Applies the specified file name. % % * *File name options*: Selecting |Function| or |Reusable function| for *Function packaging* enables file name options. % % Auto Places the function definition in the module generated for the parent system, or, if % the model root is the parent, in |model.c|. % % Use subsystem name Generates a separate file. The name of the file is the name of the subsystem or library block. % % Use function name Generates a separate file. The name of the file is the name that you specify with *Function name options*. % % User specified Applies the specified, unique file name. % % * *Function with separate data*: Enabled when you set *Function % packaging* to |Function|. When selected, the code generator separates the % internal data of the subsystem (for example, signals) from the data of % the parent model. The subsystem owns this separate data. %% Generate Reentrant Code % Embedded Coder(R) supports _reentrant code_. Reentrant % code is a reusable programming routine that multiple programs can use simultaneously. % Reentrant code is used in operating systems and % other system software that uses multithreading to handle concurrent events. % Reentrant code does not maintain state data, so there are no persistent % variables in the function. Calling programs maintain state % variables and must pass the state data into the function. Any % number of users or processes can share one copy of a reentrant routine. % % To generate reentrant code, you must first specify the % subsystem as reusable by configuring the subsystem parameter *Function % packaging*. % % <<../reusable_subsystem_param.jpg>> % % In some cases, the configuration of the model prevents reusable code. The table lists common issues. % % Cause Solution % % Subsystem output feeds global signal Add a Signal Conversion block between the % data subsystem and the global signal. % % Generated function receives data Select Configuration Parameters > % (formal parameters) through pointers Model Referencing > Pass fixed-size scalar root % inputs by value for code generation. % % Subsystem uses global signal data Use a port to pass the global data in and out % in internal algorithm of the subsystem. % %% Use a Mask to Pass Parameter Values into Library Subsystem % To define algorithmic parameter data (such as a gain or coefficient) % outside the scope of a reusable library block or subsystem, you can apply % a _mask_ to the block or subsystem and create a mask parameter. You can % then specify a different parameter value for each instance of the block % or subsystem. Each mask parameter appears in the generated code as a formal parameter % of the reentrant function. % % In this version of the model, the subsystems |PI_ctrl_1| and |PI_ctrl_2| % are % masked. In each mask, the values of the |P| and |I| gains are set by data % objects such as |I_Gain_2| and |P_Gain_2|. % % <<../Masked_SubSystems.png>> %% Generate Code for Atomic Subsystem % In <docid:ecoder_examples.example-rtwdemo_pcgd_stage_1_p1_script> % and <docid:ecoder_examples.example-rtwdemo_pcgd_stage_2_p1_script>, you generate code at the root level of the model. % Alternatively, you can build a specific subsystem. % % <<../code_gen_for_sub.jpg>> % % To initiate a subsystem build, use the context menu. % You can choose from these options: % % # *Build Subsystem*: % Treats the subsystem as a separate mode and creates the full set of source % C files and header files. This option does not support % function-call subsystems. % # *Generate S-Function*: % Generates C code for the subsystem and creates an S-Function wrapper. % You can then simulate the code in the original model. This option does % not support function-call subsystems. % # *Export Functions*: % Generates C code without the scheduling code that comes with the % *Build Subsystem* option. Use this option to build % subsystems that use triggers, such as function-call subsystems. %% Examine Generated Code % This example compares the files that are generated for the full system build with the % files that are generated for exported functions. You also examine how the % masked data appears in the code. % % Run the build script for the three options. Then, examine the generated % files by clicking the hyperlinks. % % # <matlab:RTWDemos.pcgd_buildDemo(3,0); Generate code from the entire model.> % # <matlab:RTWDemos.pcgd_buildDemo(3,2,'PI_ctrl_1') Export the function |PI_ctrl_1|.> % # <matlab:RTWDemos.pcgd_buildDemo(3,2,'Pos_Command_Arbitration') Export the function |Pos_Command_Arbitration|.> % % *rtwdemo_PCG_Eval_P3.c* % % * Full Build: <matlab:RTWDemos.pcgd_showSection(3,'func'); Yes>, Step function % * PI_ctrl_1: No % * Pos_Command_Arbitration: No % % *PI_ctrl_1.c* % % * Full Build: No % * PI_ctrl_1: <matlab:RTWDemos.pcgd_showSection(3,'PI_ctrl_1_c','PI_ctrl_1_ert_rtw'); Yes>, Trigger function % * Pos_Command_Arbitration: No % % *Pos_Command_Arbitration.c* % % * Full Build: No % * PI_ctrl_1: No % * Pos_Command_Arbitration: <matlab:RTWDemos.pcgd_showSection(3,'Pos_Command_Arbitration_c','Pos_Command_Arbitration_ert_rtw'); Yes>, Init and Function % % *PI_Ctrl_Reusable.c* % % * Full Build: <matlab:RTWDemos.pcgd_showSection(3,'Reusable'); Yes> % * PI_ctrl_1: <matlab:RTWDemos.pcgd_showSection(3,'PI_Cntrl_Reusable_c','PI_ctrl_1_ert_rtw'); Yes> % * Pos_Command_Arbitration: No % % *ert_main.c* % % * Full Build: <matlab:RTWDemos.pcgd_showSection(3,'ert_main'); Yes> % * PI_ctrl_1: <matlab:RTWDemos.pcgd_showSection(3,'ert_main_c','PI_ctrl_1_ert_rtw'); Yes> % * Pos_Command_Arbitration: <matlab:RTWDemos.pcgd_showSection(3,'ert_main_c','Pos_Command_Arbitration_ert_rtw'); Yes> % % *eval_data.c* % % * Full Build: <matlab:RTWDemos.pcgd_showSection(3,'eval_data_c'); Yes(1)> % * PI_ctrl_1: <matlab:RTWDemos.pcgd_showSection(3,'eval_data_c','PI_ctrl_1_ert_rtw'); Yes(1)> % * Pos_Command_Arbitration: No, Eval data not used in diagram % % (1) |eval_data.c| has different content in the full and % export function builds. The full build includes all of the parameters that the % model uses. The export function contains only the variables that the % subsystem uses. % % *Masked Data in the Generated Code* % % In the file |rtwdemo_PCG_Eval_P3.c|, the call sites of the reentrant function use the data objects % |P_Gain|, |I_Gain|, |P_Gain_2|, and |I_Gain_2| as arguments. % % <<../MaskedParametesInCode.png>> %% Effect of Execution Order on Simulation Results % By default, Simulink(R) executes the subsystems in this % order: % % # |PI_ctrl_1| % # |PI_ctrl_2| % # |Pos_Command_Arbitration| % % For this example, you can specify one of two alternative orders of execution. You can then use the test harness % to observe the effect of the execution order on the simulation results. % The subsystem |Execution_Order_Control| has % two configurations that control the execution order. To choose a % configuration, use the subsystem context menu. % % Change the execution order and observe the results. % % # <matlab:RTWDemos.pcgd_set_exec_order(3,1) Set the execution order to |PI_ctrl_1|, |PI_ctrl_2|, |Pos_Command_Arbitration|.> % # <matlab:RTWDemos.pcgd_open_pcg_model(3,1) Open the test harness.> % # <matlab:RTWDemos.pcgd_runTestHarn(1,3) Run the test harness.> % # <matlab:RTWDemos.pcgd_set_exec_order(3,2) Change the execution order to |Pos_Command_Arbitration|, |PI_ctrl_1|, |PI_ctrl_2|.> % # <matlab:RTWDemos.pcgd_runTestHarn(1,3) Run the test harness.> % % The simulation results (throttle position over time) vary slightly % depending on the order of execution. You can see the difference most clearly when the throttle request changes. % % <<../execution_order_effects.jpg>> % % For the next example in this series, see % <docid:ecoder_examples.example-rtwdemo_pcgd_stage_4_p1_script>. % % Copyright 2007-2015 The MathWorks, Inc.