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);