www.gusucode.com > ecoder 案例源码程序 matlab代码 > ecoder/SILPILVerificationExample.m
%% Test Generated Code with SIL and PIL Simulations % Test numerical equivalence between model components and production code that % you generate from the components by using software-in-the-loop (SIL) and % processor-in-the-loop (PIL) simulations. % % With a SIL simulation, you test source code on your development computer. % With a PIL simulation, you test the compiled object code that you intend % to deploy in production by running the object code on real target % hardware or an instruction set simulator. To determine whether model % components and generated code are numerically equivalent, compare SIL and % PIL results against normal mode results. % % There are three ways of running SIL and PIL simulations. You can use the % top model, Model blocks, or SIL and PIL blocks that you create from % a subsystem. See <docid:ecoder_ug.bsf5j6k>. % Copyright 2007-2016 The MathWorks, Inc. %% Target Connectivity Configuration for PIL % Before you can run PIL simulations, you must configure target % connectivity. The target connectivity configuration enables the PIL % simulation to: % % * Build the target application. % * Download, start, and stop the application on the target. % * Support communication between Simulink and the target. % % To produce a target connectivity configuration, you can use the supplied % target connectivity API. For details, see <docid:ecoder_ug.bruy_tf-1>. % % For supported hardware, you can use target support packages. For details, % see <docid:ecoder_ug.bufy301-1>. %% SIL or PIL Simulation with a Top Model % Test generated model code by running a top-model SIL or PIL simulation. % With this approach: % % * You test code generated from the top model, which uses the standalone code interface. % * You configure the model to load test vectors or stimulus inputs from the MATLAB workspace. % * You can easily switch the top model between the normal, SIL, and PIL simulation modes. % % Open a simple counter top model. model='rtwdemo_sil_topmodel'; close_system(model,0) open_system(model) %% % To focus on numerical equivalence testing, turn off: % % * Model coverage % * Code coverage % * Execution time profiling set_param(gcs, 'RecordCoverage','off'); coverageSettings = get_param(model, 'CodeCoverageSettings'); coverageSettings.CoverageTool='None'; set_param(model, 'CodeCoverageSettings',coverageSettings); set_param(model, 'CodeExecutionProfiling','off'); %% % Configure the input stimulus data. [ticks_to_count, reset, counter_mode, count_enable] = ... rtwdemo_sil_topmodel_data(T); %% % Configure logging options in the model. set_param(model, 'LoadExternalInput','on'); set_param(model, 'ExternalInput','ticks_to_count, reset, counter_mode, count_enable'); set_param(model, 'SignalLogging', 'on'); set_param(model, 'SignalLoggingName', 'logsOut'); %% % Run a normal mode mode simulation. set_param(model,'SimulationMode','normal') [~, ~, yout_normal] = sim(model,10); %% % Run a top-model SIL simulation. set_param(model,'SimulationMode','Software-in-the-Loop (SIL)') [~, ~, yout_sil] = sim(model,10); %% % Unless up-to-date code for this model exists, new code is generated and % compiled. The generated code runs as a separate process on your computer. %% % Plot and compare the results of the normal and SIL simulations. Observe % that the results match. fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), plot(yout_sil), title('Counter Output for SIL Simulation') subplot(3,1,3), plot(yout_normal-yout_sil), ... title('Difference Between Normal and SIL'); %% % Clean up. close_system(model,0); if ishandle(fig1), close(fig1), end clear fig1 simResults = {'yout_sil','yout_normal','model','T',... 'ticks_to_count','reset'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults') %% SIL or PIL Simulation with a Model Block % Test generated model code by using a test harness model that runs a Model % block in SIL mode. With this approach: % % * You can test code that is generated from a top model or a referenced % model. The code from the top model uses the standalone code interface. % The code from the referenced model uses the model reference code % interface. For more information, see <docid:ecoder_ug.brutuzj-1>. % * You use a test harness model or a system model to provide test vector % or stimulus inputs. % * You can easily switch a Model block between the normal, SIL, and PIL % simulation modes. % % Open an example model that has two Model blocks which reference the same % model. In a simulation, you run one Model block in SIL mode and the % other Model block in normal mode. model='rtwdemo_sil_modelblock'; open_system(model); %% % Turn off: % % * Code coverage % * Execution time profiling coverageSettings = get_param(model, 'CodeCoverageSettings'); coverageSettings.CoverageTool='None'; set_param(model, 'CodeCoverageSettings',coverageSettings); open_system('rtwdemo_sil_modelblock') set_param('rtwdemo_sil_modelblock', 'CodeExecutionProfiling','off'); open_system('rtwdemo_sil_counter') set_param('rtwdemo_sil_counter', 'CodeExecutionProfiling','off'); currentFolder=pwd; save_system('rtwdemo_sil_counter', fullfile(currentFolder,'rtwdemo_sil_counter.slx')) %% % *Test Top-Model Code* % % For the Model block in SIL mode, specify generation of top-model code, % which uses the standalone code interface. set_param([model '/CounterA'], 'CodeInterface', 'Top model'); %% % Run a simulation of the test harness model. out = sim(model,20); %% % The model block in SIL mode runs as a separate process on your % computer. In the working folder, you see that standalone code % is generated for the referenced model unless generated code from a % previous build exists. %% % Compare the behavior of Model blocks in normal and SIL modes. The results % match. yout = find(out,'logsOut'); yout_sil = yout.get('counterA').Values.Data; yout_normal = yout.get('counterB').Values.Data; fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), ... plot(yout_sil), title('Counter Output for Model Block SIL (Top-Model) Simulation') subplot(3,1,3), plot(yout_normal-yout_sil), ... title('Difference Between Normal and SIL'); %% % *Test Model Reference Code* % % For the Model block in SIL mode, specify generation of referenced model % code, which uses the model reference code interface. set_param([model '/CounterA'], 'CodeInterface', 'Model reference'); %% % Run a simulation of the test harness model. out2 = sim(model,20); %% % The model block in SIL mode runs as a separate process on your computer. % In the working folder, you see that model reference code is generated % unless code from a previous build exists. %% % Compare the behavior of Model blocks in normal and SIL modes. The results % match. yout2 = find(out2,'logsOut'); yout2_sil = yout2.get('counterA').Values.Data; yout2_normal = yout2.get('counterB').Values.Data; fig1 = figure; subplot(3,1,1), plot(yout2_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), ... plot(yout2_sil), title('Counter Output for Model Block SIL (Model Reference) Simulation') subplot(3,1,3), plot(yout2_normal-yout2_sil), ... title('Difference Between Normal and SIL'); %% % Clean up. close_system(model,0); if ishandle(fig1), close(fig1), end, clear fig1 simResults={'out','yout','yout_sil','yout_normal', ... 'out2','yout2','yout2_sil','yout2_normal', ... 'SilCounterBus','T','reset','ticks_to_count','Increment'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults') %% SIL or PIL Block Simulation % Test generated subsystem code by using a SIL or PIL block in a % simulation. With this approach: % % * You test code generated from subsystems, which uses the standalone code % interface. % * You provide a test harness or a system model to supply test vector or % stimulus inputs. % * You replace your original subsystem with the generated SIL or PIL % block. %% % Open a simple model, which consists of a control algorithm and a plant % model in a closed loop. The control algorithm regulates the output from % the plant. model='rtwdemo_sil_block'; close_system(model,0) open_system(model) %% % Run a normal mode simulation out = sim(model,10); yout_normal = find(out,'yout'); clear out %% % Configure the build process to create the SIL block for testing. set_param(model,'CreateSILPILBlock','SIL'); %% % To test the behavior on production hardware, specify a PIL block. %% % To create the SIL block, generate code for the control algorithm % subsystem. You see the SIL block at the end of the build process. Its % input and output ports match those of the control algorithm subsystem. close_system('untitled',0); rtwbuild([model '/Controller']) %% % Alternatively, you can right-click the subsystem and select % C/C++ Code > Build This Subsystem. In the dialog box that opens, % click Build. %% % To perform a SIL simulation of the controller and plant model in a % closed loop, replace the original control algorithm with the new SIL % block. To avoid losing your original subsystem, do not save your model % in this state. controllerBlock = [model '/Controller']; blockPosition = get_param(controllerBlock,'Position'); delete_block(controllerBlock); add_block('untitled/Controller',[controllerBlock '(SIL)'],... 'Position', blockPosition); close_system('untitled',0); clear controllerBlock blockPosition %% % Run the SIL simulation. out = sim(model,10); %% % The control algorithm uses single-precision, floating-point arithmetic. % You can expect the order of magnitude for differences between SIL and % normal simulations to be close to the machine precision for % single-precision data. % % Define an error tolerance for SIL simulation results that is based on % the machine precision for the single-precision, normal simulation % results. machine_precision = eps(single(yout_normal)); tolerance = 4 * machine_precision; %% % Compare normal and SIL simulation results. In the third plot, the % differences between the simulations lie well within the defined % error tolerance. yout_sil = find(out,'yout'); tout = find(out,'tout'); fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Controller Output for Normal Simulation') subplot(3,1,2), plot(yout_sil), title('Controller Output for SIL Simulation') subplot(3,1,3), plot(tout,abs(yout_normal-yout_sil),'g-', tout,tolerance,'r-'), ... title('Normal and SIL Difference and Error Tolerance'); %% % Clean up. close_system(model,0); if ishandle(fig1), close(fig1), end clear fig1 simResults={'out','yout_sil','yout_normal','tout','machine_precision'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults') %% Hardware Implementation Settings % When you run a SIL simulation, you must configure your hardware implementation % settings (characteristics such as native word sizes) to allow compilation % for your development computer. These settings can differ from the hardware % implementation settings that you use when building the model % for your production hardware. To avoid the need to change hardware % implementation settings between SIL and PIL simulations, enable portable % word sizes. For more information, see <docid:ecoder_ug.buty32q>.