%% 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.
%% About the Example Model
% Open the example model rtwdemo_async_mdlreftop.

open_system('rtwdemo_async_mdlreftop');

%
%
%
% 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 chart configured for a function call input event
% A referenced model with an 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 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 roo-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 the 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 parameters dialog box for the Asynchronous Task Specification block, 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, connect to function-call subsystem Count. Count represents a simple interrupt service routine (ISR). The second Asynchronous Task Specification block connect 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('rtwdemo_async_mdlreftop');

%
%% 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
% Async Interrupt
% Asynchronous Task Specification
% Generate Interrupt Service Routines
% Timers in Asynchronous Tasks
% Create a Customized Asynchronous Library
% Import Asynchronous Event Data for Simulation
% Load Data to Root-Level Input Ports
% Asynchronous Events
% Rate Transitions and Asynchronous Blocks
% Asynchronous Support Limitations

bdclose('rtwdemo_async_mdlreftop');
rtwdemoclean;
cd(currentDir)

%
% Copyright 2020 The MathWorks, Inc.