Real-Time Workshop Embedded Coder | ![]() ![]() |
Overview of Operation
The operation of rt_OneStep
depends upon
SingleTasking
vs. MultiTasking
)
Table 2-3 summarizes the permitted solver modes for single-rate and multi-rate models. Note that for a single-rate model, only SingleTasking
solver mode is allowed.
The generated code for rt_OneStep
(and associated timing data structures and support functions) is tailored to the number of rates in the model and to the solver mode. The following sections discuss each possible case.
Single-Rate Singletasking Operation. Since by definition the only legal solver mode for a single-rate model is SingleTasking
, we refer to this case simply as "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 noninterruptible until the interrupt overflow flag has been checked.
Multi-Rate MultiTasking Operation. The following pseudocode shows the design of rt_OneStep
in a multi-rate multitasking program.
rt_OneStep() { Check for base-rate interrupt overflow Enable "rt_OneStep" interrupt Determine which rates need to run this time step 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 multi-rate multitasking system, the Real-Time Workshop Embedded Coder 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 NumTasks
tasks in the system, the range of task identifiers is 0..NumTasks
-1.
Tasks are prioritized, 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
NumTasks
-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
and model
_step
maintain 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 scheduling counters are maintained by the rate_monotonic_scheduler
function, which is called by model
_step
. 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. rt_OneStep
maintains the event flags via the model
_SetEventsForThisBaseStep
function.When a counter indicates that a task's sample period has elapsed, model
_SetEventsForThisBaseStep
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.
Multi-rate 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 noninterruptible until the base-rate interrupt overflow flag has been checked (see pseudocode above).
Multi-Rate Singletasking Operation. In a multi-rate singletasking program, by definition, all sample times in the model must be an integer multiple of the model's fixed-step size.
In a multi-rate singletasking program, blocks execute at different rates, but under the same task identifier. The operation of rt_OneStep
, in this case, is a simplified version of multi-rate multitasking operation. The only task is the base-rate task. On each clock tick, rt_OneStep
checks the overrun flag and calls model
_step
, passing in tid 0
.
The generated model
_step
code maintains scheduling counters on each clock tick, via the rate_monotonic_scheduler
function. There is one counter for each sample rate in the model. The counters are implemented as an array (model_M.cTaskTicks[]
) within rtM
.
The counters are, in effect, clock rate dividers that count up the sample period associated with each sample rate in the model. When a counter indicates that a sample period for a given rate has elapsed, rate_monotonic_scheduler
clears the counter. This condition indicates that all blocks running at that rate should execute on the next call to model
_step
.
model
_step
is responsible for checking the counters, using macros provided for the purpose (rtmIsSampleHit
and rtmIsSpecialSampleHit
).
Guidelines for Modifying rt_OneStep
rt_OneStep
does not require extensive modification. The only required modification is to reenable interrupts after the overrun flag(s) and error conditions have been checked. If applicable, you should also
rt_OneStep
.
model_step(0)
.
model_step(0)
.
model_step(tid)
in the sub-rate loop.
model_step(tid)
in the sub-rate loop.
Comments in rt_OneStep
indicate the appropriate place to add your code.
In multi-rate rt_OneStep
, you can improve performance by unrolling for
and while
loops.
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, event flags, or other timing data structures are set in rt_OneStep
, or in functions called from rt_OneStep
. The rt_OneStep
timing data structures (including rtM
) and logic are critical to correct operation of any Real-Time Workshop Embedded Coder program.
![]() | Main Program | VxWorks Example Main Program Execution | ![]() |