www.gusucode.com > simulinkcoder 案例源码程序 matlab代码 > simulinkcoder/AsynchronousEventModelingVxWorksROSExample.m

    %% Spawn and Synchronize Execution of RTOS Task
% This example shows how to simulate and generate code for asynchronous events 
% on a multitasking real-time operating system (VxWorks(R)). The model shows different techniques 
% for handling asynchronous events depending on the size of the triggered
% subsystems.
%
%% About the Example Model
% Open the example model |rtwdemo_async|.
%
model=('rtwdemo_async');
open_system(model);
%%
% The model simulates an interrupt source and includes an Async Interrupt block,
% a Task Sync block, function-call subsystems |Count| and |Algorithm|, and 
% Rate Transition blocks. The Async Interrupt block creates two Versa Module 
% Eurocard (VME) interrupt service routines (ISRs) that pass interrupt signals 
% to subsystem |Count| and the Task Sync block. You can place an Async
% Interrupt block between a simulated interrupt source and one of the
% following:
% 
% * Function call subsystem
% * Task Sync block
% * A Stateflow(R) chart configured for a function call input event
% * A referenced model with an Inport block that connects to one of the
% preceding model elements
% 
% The Async Interrupt and Task Sync blocks enable the subsystems to execute 
% asynchronously. 
%
% |Count| represents a simple interrupt service routine (ISR) that executes
% at interrupt level. It is best to keep ISRs as simple as possible. This 
% subsystem includes only a Discrete-Time Integrator block.  
%
% |Algorithm| includes more substance.  It includes multiple blocks and 
% produces two output values. Execution of larger subsystems at interrupt
% level can significantly impact response time for interrupts of equal and
% lower priority in the system. A better solution for larger subsystems is
% to use the Task Sync block to represent the ISR for the function-call subsystem.
% 
% The Async Interrupt block generates calls to ISRs. Place the block between 
% a simulated interrupt source and one of the following: 
% 
% * Function call subsystem
% * Task Sync block
% * A Stateflow(R) chart configured for a function call input event
%
% For each specified interrupt level, the block generates a Versa Module Eurocard 
% (VME) ISR that executes the connected subsystem, Task Sync block, or chart.  
%
% In the example model, the Async Interrupt block is configured for VME
% interrupts 1 and 2, by using interrupt vector offsets 192 and 193. Interrupt 1 
% connects directly to subsystem |Count|. Interrupt 2 connects to a Task Sync 
% block, which serves as the ISR for |Algorithm|. Place a Task Sync block 
% in one of the following locations:
%
% * Between an Async Interrupt block and a function-call subsystem or 
% Stateflow(R) chart.  
% * At the output port of a Stateflow(R) chart that has an event, |Output to
% Simulink|, that you configure as a function call. 
%  
% In the example model, the Task Sync block is between the Async Interrupt 
% block and function-call subsystem |Algorithm|. The Task Sync block 
% is configured with the task name |Task()|, a priority of 50, a stack size 
% of 8192, and data transfers of the task synchronized with the caller task. 
% The spawned task uses a semaphore to synchronize task execution. The Async
% Interrupt block triggers a release of the task semaphore. 
%
% Four Rate Transition blocks handle data transfers between ports that operate at
% different rates. In two instances, Protected Rate Transition blocks protect 
% data transfers (prevent them from being preempted and corrupted). In the 
% other two instances, Unprotected Rate Transition blocks introduce no special
% behavior. Their presence informs Simulink(R) of a rate transition.
%
% The code generated for the Async Interrupt and Task Sync blocks is tailored 
% for the example RTOS (VxWorks(R)). However, you can modify the blocks to 
% generate code specific to your run-time environment.
% 
%% Data Transfer Assumptions
% 
% * Data transfers occur between one reading task and one writing task.
% * A read or write operation on a byte-size 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 stop 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 reddish-blue. Asynchronous
% interrupts and tasks are purple. The Rate Transition Blocks, which are a 
% hybrid rate (their input and output sample times can differ), are yellow.
% 
%% Generate Code and Report
%
% Generate code and a code generation report for the model. Generated code for 
% the Async Interrupt and Task Sync blocks is for the example RTOS (VxWorks(R)). 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.c|. The initialization
% code:
%
% 1. Creates and initializes the synchronization semaphore |Task0_semaphore|.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    '/* Spawn task: Task0 with priority 50 */', ...
    'rtwdemo_async_DW.SFunction_IWORK.TaskID = taskSpawn("Task0",', ... 
    0, 0);
%%
% 2. Spawns task |task0| and assigns the task priority 50.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    'rtwdemo_async_DW.SFunction_IWORK.TaskID = taskSpawn("Task0",', ... 
    '/* End of Start for S-Function (vxinterrupt1): ''<Root>/Async Interrupt'' */', ... 
    1, 0);
%%
% 3. Connects and enables ISR |isr_num1_vec192| for interrupt 1 and ISR 
% |isr_num2_vec193| for interrupt 2.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    '/* End of Start for S-Function (vxinterrupt1): ''<Root>/Async Interrupt'' */', ... 
    '/* InitializeConditions for DiscretePulseGenerator: ''<Root>/20 Hz ISR'' */', ... 
    0, 0);
%%
% The order of these operations is important. Before the code generator enables 
% the interrupt that activates the task, it must spawn the task.
%
%% Review Task and Task Synchronization Code
%
% In the generated source file |rtwdemo_async.c|, review the task and task 
% synchronization code. 
%
% The code generator produces the code for function |Task0| from the Task 
% Sync block. That function includes a small amount of interrupt-level code
% and runs as an RTOS task.
%
% The task waits in an infinite |for| loop until the system releases a 
% synchronization semaphore. If the system releases the semaphore, the 
% function updates its task timer and calls the code generated for the 
% |Algorithm| subsystem.
%
% In the example model, the *Synchronize the data transfer of this task with  
% the caller task* parameter for the Task Sync block is set. This parameter 
% setting updates the timer associated with the Task Sync block 
% (|rtM->Timing.clockTick2|) with the value of the timer that the Async 
% Interrupt block (|rtM->Timing.clockTick3|) maintains. As a result, code 
% for blocks within the |Algorithm| subsystem use timer values that are based 
% on the time of the most recent interrupt, rather than the most recent 
% activation of |Task0|.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    'void Task0(void)', ... 
    'time_T rt_SimUpdateDiscreteEvents(', ... 
    0, 1);
%%
% The code generator produces code for ISRs |isr_num1_vec192| and 
% |isr_num2_vec293|. ISR |isr_num2_vec192|:
%
% * Disables interrupts.
% * Saves floating-point context.
% * Calls the code generated for the subsystem that connects 
% to the referenced model Inport block, which receives the interrupt.
% * Restores floating-point context.
% * Reenables interrupts. 
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    'void isr_num1_vec192(void)', ...
    'void isr_num2_vec193(void)', ... 
    1, 0);
%%
% ISR |isr_num2_vec293| maintains a timer that stores the tick count at the 
% time that the interrupt occurs. After updating the timer, the ISR releases  
% the semaphore that activates |Task0|.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    'void isr_num2_vec193(void)', ...
    '/* Spawned with priority: 50 */', ... 
    1, 0);
%
%% Review Task Termination Code
% The Task Sync block generates the following termination code.
%
cfile = fullfile(cgDir, 'rtwdemo_async_tornado_rtw', 'rtwdemo_async.c');
rtwdemodbtype(cfile, ...
    'static void rtwdemo_async_terminate(void)', ...
    '/*========================================================================*', ... 
    1, 0);
%% Related Information
% * <docid:rtw_ref.bu_98v5>
% * <docid:rtw_ref.bqnrjmx-1>
% * <docid:rtw_ug.f9453>
% * <docid:rtw_ug.f29370>
% * <docid:rtw_ug.f10041>
% * <docid:rtw_ug.bsyjz_c>
% * <docid:simulink_ug.bsuwmmp>
% * <docid:rtw_ug.f23284>
% * <docid:rtw_ug.f10930>
% * <docid:rtw_ug.bqpnsgq>
%%
bdclose(model);
rtwdemoclean;
cd(currentDir);