%% Pass Asynchronous Events in RTOS as Input To a Referenced Model
% This example shows how to simulate and generate code for asynchronous 
% events on a real-time multitasking system. 
%
%% Open Example Model
% Open the example model |rtwdemo_async_mdlreftop|.
%
model=('rtwdemo_async_mdlreftop');
open_system(model);
%%

% The model simulates an interrupt source and includes an Async Interrupt 
% block and referenced model. The Async Interrupt block creates two Versa 
% Module Eurocard (VME) interrupt service routines (ISRs) that pass interrupt 
% signals to Inport blocks 1 and 2 of the referenced model. 

% You can place an Async Interrupt block between a simulated interrupt source 
% and one of these model elements:
% 
% * Function call subsystem
% * Task Sync block
% * A Stateflow(R) chart configured for a function call input event
% * A referenced model with a Inport block that connects to one of the
% preceding model elements
%
% In this example model, the Async Interrupt block passes asynchronous events 
% (function-call trigger signals), |Interrupt1| and |Interrupt2|, to the 
% referenced model through Inport blocks 1 and 2. 
%
% The code generator produces code that is tailored for the VxWorks(R) 
% operating system. Reconfigure the Async Interrupt block to generate code
% for an alternative application run-time environment. 
%
% Open the referenced model. The referenced model includes the two Inport 
% blocks that receive the interrupts, each connected to an Asynchronous 
% Task Specification block, function-call subsystems |Count| and |Algorithm|, 
% and Rate Transition blocks. The Asynchronous Task Specification block, 
% in combination with a root-level Inport block, allows a reference model 
% to receive asynchronous function-call input. To use the block:
%
% # Connect the Asynchronous Task Specification block to the output port 
% of a root-level Inport block that outputs a function-call trigger. 
% # Select the *Output function call* parameter of the Inport block to
% specify that it accepts function-call signals.
% # On the Asynchronous Task Specification parameters dialog box, set the 
% task priority for the asynchronous task associated with an Inport block.
% Specify an integer or []. If you specify an integer, it must match the
% priority of the interrupt initiated by the Async Interrupt block in the
% parent model. If you specify [], the priorities do not have to match. 
%
% The Asynchronous Task Specification block for the higher priority interrupt, 
% |interrupt1|, connects to function-call subsystem |Count|. |Count| represents 
% a simple interrupt service routine (ISR). The second Asynchronous Task 
% Specification block connects to the subsystem |Algorithm|, which includes 
% more substance.  It includes multiple blocks and produces two output values.
% Both subsystems execute at interrupt level.
%
% For each interrupt level specified for the Async Interrupt block in the parent
% model, the block generates a VME ISR that executes the connected subsystem, 
% Task Sync block, or chart.  
%
% In the example top model, the Async Interrupt block is configured for VME
% interrupts 1 and 2, using interrupt vector offsets 192 and 193. Interrupt 1 
% is wired to trigger subsystem |Count|. Interrupt 2 is wired to trigger
% subsystem |Algorithm|. 
%
% The Rate Transition blocks handle data transfers between ports that operate at
% different rates. In two instances, the blocks protect data transfers (prevent
% them from being preempted and corrupted). In the other instance, no special
% behavior occurs.
%
%% Data Transfer Assumptions
%
% * Data transfers occur between one reading task and one writing task.
% * A read or write operation on a byte-sized variable is atomic.
% * When two tasks interact, only one can preempt the other. 
% * For periodic tasks, the task with the faster rate has higher priority 
% than the task with the slower rate. The task with the faster rate preempts 
% the tasks with slower rates.
% * Tasks run on a single processor. Time slicing is not allowed.
% * Processes do not crash and restart, especially while data is being transferred 
% between tasks.
%
%% Simulate the Model
%
% Simulate the model. By default, the model is configured to show sample times 
% in different colors.  Discrete sample times for input and output appear 
% red and green, respectively. Constants are magenta. Asynchronous interrupts
% are purple. The Rate Transition Blocks, which are hybrid (input and output
% sample times can differ), appear yellow.
%
%% Generate Code and Report
%
% Generate code and a code generation report for the model. Async Interrupt block 
% and Task Sync block generated code is for the example RTOS (VxWorks). 
% However, you can modify the blocks to generate code for another 
% run-time environment.
%
% 1. Create a temporary folder for the build and inspection process.
%
currentDir = pwd;
[~,cgDir] = rtwdemodir();
%%
% 2. Build the model.
rtwbuild(model);
%% Review Initialization Code
%
% Open the generated source file |rtwdemo_async_mdlreftop.c|. The initialization
% code connects and enables ISR |isr_num1_vec192| for interrupt 1 and ISR 
% |isr_num2_vec193| for interrupt 2.
%
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'static void rtwdemo_async_mdlreftop_initialize(void)', ...
    '/* Model terminate function */', ... 
    1, 0);
%% Review ISR Code
%
% In the generated source file |rtwdemo_async_mdlreftop.c|, review the  
% code for ISRs |isr_num1_vec192| and |isr_num2_vec293|. Each ISR:
%
% * Disables interrupts.
% * Saves floating-point context.
% * Calls the code generated for the subsystem connected 
% to the referenced model Inport block that receives the interrupt.
% * Restores floating-point context.
% * Reenables interrupts.
%
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'void isr_num1_vec192(void)', ...
    'time_T rt_SimUpdateDiscreteEvents', ... 
    1, 0);
%% Review Task Termination Code
% The Task Sync block generates the following termination code.
%
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'static void rtwdemo_async_mdlreftop_terminate(void)', ...
    '/*========================================================================*', ... 
    1, 0);
%% Related Information
% * <docid:rtw_ref.bu_98v5 Async Interrupt>
% * <docid:rtw_ref.bssng6y-1 Asynchronous Task Specification>
% * <docid:rtw_ug.f9453 Generate Interrupt Service Routines>
% * <docid:rtw_ug.f29370 Timers in Asynchronous Tasks>
% * <docid:rtw_ug.f10041 Create a Customized Asynchronous Library>
% * <docid:rtw_ug.bsyjz_c Import Asynchronous Event Data for Simulation>
% * <docid:simulink_ug.bsuwmmp Load Data to Root-Level Input Ports>
% * <docid:rtw_ug.f23284 Asynchronous Events>
% * <docid:rtw_ug.f10930 Rate Transitions and Asynchronous Blocks>
% * <docid:rtw_ug.bqpnsgq Asynchronous Support Limitations>
%%
bdclose(model);
rtwdemoclean;
cd(currentDir)

%% 
% Copyright 2019 The MathWorks, Inc.