Real-Time Workshop User's Guide | ![]() ![]() |
Overview of Operation
The operation of rt_OneStep
depends upon whether your model is single-rate or multirate. Code compilation is controlled by the symbol NUMST
, which represents the number of sample times (i.e., rates) in the model. NUMST
is defined to be 1 for a single-rate model; otherwise NUMST
is greater than 1. NUMST
is defined in the generated makefile model
.mk
.
Single-Rate Operation. The following pseudocode shows the design of rt_OneStep
in a single-rate program.
rt_OneStep() { Check for interrupt overflow or other error Enable "rt_OneStep" (timer) interrupt ModelStep-- Time step combines output,logging,update. }
Single-rate rt_OneStep
is designed to execute model
_step
within a single clock period. To enforce this timing constraint, rt_OneStep
maintains and checks a timer overrun flag. On entry, timer interrupts are disabled until the overrun flag and other error conditions have been checked. If the overrun flag is clear, rt_OneStep
sets the flag, and proceeds with timer interrupts enabled.
The overrun flag is cleared only upon successful return from model
_step
. Therefore, if rt_OneStep
is reinterrupted before completing model
_step
, the reinterruption will be detected through the overrun flag.
Reinterruption of rt_OneStep
by the timer is an error condition. If this condition is detected rt_OneStep
signals an error and returns immediately. (Note that you can change this behavior if you want to handle the condition differently.)
Note that the design of rt_OneStep
assumes that interrupts are disabled before rt_OneStep
is called. rt_OneStep
should be non-interruptible until the interrupt overflow flag has been checked.
Multirate Operation. The following pseudocode shows the design of rt_OneStep
in a multirate program.
rt_OneStep() { Check for base-rate interrupt overflow Enable "rt_OneStep" interrupt ModelStep(tid
=0) --base-rate time step. For i=1:NumTasks -- iterate over sub-rate tasks Check for sub-rate interrupt overflow If (sub-rate task i is scheduled) ModelStep(tid
=i) --Sub-rate time step. EndIf EndFor }
In a multirate system, rt_OneStep
uses a prioritized, preemptive multitasking scheme to execute the different sample rates in your model.
The execution of blocks having different sample rates is broken into tasks. Each block that executes at a given sample rate is assigned a task identifier (tid
), which associates it with a task that executes at that rate. Where there are NUMST
tasks in the system, the range of task identifiers is 0..NUMST
-1.
rt_OneStep
prioritizes tasks, in descending order, by rate. The base-rate task is the task that runs at the fastest rate in the system (the hardware clock rate). The base-rate task has highest priority (tid
0) . The next fastest task (tid
1) has the next highest priority, and so on down to the slowest, lowest priority task (tid
NUMST
-1).
The slower tasks, running at submultiples of the base rate, are called sub-rate tasks.
On each invocation, rt_OneStep
makes one or more calls to model
_step
, passing in the appropriate tid
. The tid
informs model
_step
that all blocks having that tid
should execute. rt_OneStep
always calls model
_step
(tid = 0)
because the base-rate task must execute on every clock step.
On each clock tick, rt_OneStep
also maintains scheduling counters and event flags for each sub-rate task. Both the counters and the event flags are implemented as arrays, indexed on tid
.
The counters are, in effect, clock rate dividers that count up the sample period associated with each sub-rate task. The event flags indicate whether or not a given task is scheduled for execution. When a counter indicates that a task's sample period has elapsed, rt_OneStep
sets the event flag for that task.
After updating its scheduling data structures and stepping the base-rate task, rt_OneStep
iterates over the scheduling flags in tid
order, calling model
_step(tid)
for any task whose flag is set. This ensures that tasks are executed in order of priority.
The event flag array and loop variables used by rt_OneStep
are stored as local (stack) variables. This ensures that rt_OneStep
is reentrant. If rt_OneStep
is reinterrupted, higher priority tasks will preempt lower priority tasks. Upon return from interrupt, lower priority tasks will resume in the previously scheduled order.
Multirate rt_OneStep
also maintains an array of timer overrun flags. rt_OneStep
detects timer overrun, per task, by the same logic as single-rate rt_OneStep
.
Note that the design of rt_OneStep
assumes that interrupts are disabled before rt_OneStep
is called. rt_OneStep
should be non-interruptible until the base-rate interrupt overflow flag has been checked (see pseudo-code above).
Guidelines for Modifying rt_OneStep
rt_OneStep
does not require extensive modification. The only required modification is to re-enable interrupts after the overrun flag(s) and error conditions have been checked. Comments in rt_OneStep
indicate the appropriate place to add your code.
In multirate rt_OneStep
, you can improve performance by unrolling for
and while
loops.
You may also want to replace the MODEL_STEP
macro call(s) with model-specific call(s). If so, see How to Call the Entry Points Directly.
In addition, you may choose to modify the overrun behavior to continue execution after error recovery is complete.
You should not modify the way in which the counters are set in rt_OneStep
. The rt_OneStep
timing data structures (including the real-time object) and logic are critical to correct operation of any Real-Time Workshop Embedded Coder program.
![]() | Main Program | Model Entry Points | ![]() |