Stand-Alone Program Execution

Overview

By default, the Real-Time Workshop Embedded Coder software generates stand-alone programs that do not require an external real-time executive or operating system. A stand-alone program requires some minimal modification to be adapted to the target hardware; these modifications are described in the following sections. The stand-alone program architecture supports execution of models with either single or multiple sample rates.

To generate a stand-alone program:

  1. In the Custom templates subpane of the Real-Time Workshop/Templates pane of the Configuration Parameters dialog box, select the Generate an example main program option (this option is on by default).

  2. When Generate an example main program is selected, the Target operating system pop-up menu is enabled. Select BareBoardExample from this menu (this option is the default selection).

The core of a stand-alone program is the main loop. On each iteration, the main loop executes a background or null task and checks for a termination condition.

The main loop is periodically interrupted by a timer. The Real-Time Workshop function rt_OneStep is either installed as a timer interrupt service routine (ISR), or called from a timer ISR at each clock step.

The execution driver, rt_OneStep, sequences calls to the model_step function(s). The operation of rt_OneStep differs depending on whether the generating model is single-rate or multirate. In a single-rate model, rt_OneStep simply calls the model_step function. In a multirate model, rt_OneStep prioritizes and schedules execution of blocks according to the rates at which they run.

The Real-Time Workshop Embedded Coder software generates significantly different code for multirate models depending on the following factors:

These factors affect the scheduling algorithms used in generated code, and in some cases affect the API for the model entry point functions. The following sections discuss these variants.

Main Program

Overview of Operation

The following pseudocode shows the execution of a Real-Time Workshop Embedded Coder main program.

main()
{
  Initialization (including installation of rt_OneStep as an 
    interrupt service routine for a real-time clock)
  Initialize and start timer hardware
  Enable interupts
  While(not Error) and (time < final time)
    Background task
  EndWhile
  Disable interrupts (Disable rt_OneStep from executing)
  Complete any background tasks
  Shutdown
}

The pseudocode is a design for a harness program to drive your model. The ert_main.c or .cpp program only partially implements this design. You must modify it according to your specifications.

Guidelines for Modifying the Main Program

This section describes the minimal modifications you should make in your production version of ert_main.c or .cpp to implement your harness program.

rt_OneStep

Overview of Operation

The operation of rt_OneStep depends upon

Permitted Solver Modes for Real-Time Workshop Embedded Coder Targeted Models summarizes the permitted solver modes for single-rate and multirate models. Note that for a single-rate model, only SingleTasking solver mode is allowed.

Permitted Solver Modes for Real-Time Workshop Embedded Coder Targeted Models

ModeSingle-RateMultirate

SingleTasking

Allowed

Allowed

MultiTasking

Disallowed

Allowed

Auto

Allowed

(defaults to SingleTasking)

Allowed

(defaults to MultiTasking)

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

The only valid solver mode for a single-rate model is SingleTasking. Such models run in "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
  Model_Step()  -- Time step combines output,logging,update
}

For the single-rate case, the generated model_step function is

void model_step(void)

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 is 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.

Multirate Multitasking Operation

In a multirate multitasking system, the Real-Time Workshop Embedded Coder software uses a prioritized, preemptive multitasking scheme to execute the different sample rates in your model.

The following pseudocode shows the design of rt_OneStep in a multirate multitasking program.

rt_OneStep()
{
  Check for base-rate interrupt overrun
  Enable "rt_OneStep" interrupt
  Determine which rates need to run this time step

  Model_Step0()        -- run base-rate time step code

  For N=1:NumTasks-1   -- iterate over sub-rate tasks
    If (sub-rate task N is scheduled)
    Check for sub-rate interrupt overrun
      Model_StepN()    -- run sub-rate time step code
    EndIf
  EndFor
}

Task Identifiers.   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.

Prioritization of Base-Rate and Sub-Rate Tasks.   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.

Rate Grouping and Rate-Specific model_step Functions.   In a single-rate model, all block output computations are performed within a single function, model_step. For multirate, multitasking models, the Real-Time Workshop Embedded Coder software uses a different strategy (whenever possible). This strategy is called rate grouping. Rate grouping generates separate model_step functions for the base rate task and each sub-rate task in the model. The function naming convention for these functions is

model_stepN

where N is a task identifier. For example, for a model named my_model that has three rates, the following functions are generated:

void my_model_step0 (void);
void my_model_step1 (void);
void my_model_step2 (void);

Each model_stepN function executes all blocks sharing tid N; in other words, all block code that executes within task N is grouped into the associated model_stepN function.

Scheduling model_stepN Execution.   On each clock tick, rt_OneStep and model_step0 maintain scheduling counters and event flags for each sub-rate task. The counters are implemented in the Timing.TaskCounters.TIDn fields of rtModel. 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_step0 (that is, in the base-rate task). The function updates flags—an active task flag for each subrate and rate transition flags for tasks that exchange data—and assumes the use of a rate monotonic scheduler. The scheduling 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 based on a task counter that is maintained by code in the model's example main program (ert_main.c). When a counter indicates that a task's sample period has elapsed, the example main code sets the event flag for that task.

On each invocation, rt_OneStep updates its scheduling data structures and steps the base-rate task (rt_OneStep always calls model_step0 because the base-rate task must execute on every clock step). Then, rt_OneStep iterates over the scheduling flags in tid order, unconditionally calling model_stepN for any task whose flag is set. This ensures that tasks are executed in order of priority.

Preemption.   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).

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 preempt lower priority tasks. Upon return from interrupt, lower priority tasks resume in the previously scheduled order.

Overrun Detection.   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.

Multirate Singletasking Operation

In a multirate singletasking program, by definition, all sample times in the model must be an integer multiple of the model's fixed-step size.

In a multirate 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 multirate multitasking operation. Rate grouping is not used. The only task is the base-rate task. Therefore, only one model_step function is generated:

void model_step(int_T tid)

On each clock tick, rt_OneStep checks the overrun flag and calls model_step, passing in tid 0. The scheduling function for a multirate singletasking program is rate_scheduler (rather than rate_monotonic_scheduler). The scheduler maintains scheduling counters on each clock tick. There is one counter for each sample rate in the model. The counters are implemented in an array (indexed on tid) within the Timing structure within rtModel.

The counters are, in effect, clock rate dividers that count up the sample period associated with each sub-rate task. When a counter indicates that a sample period for a given rate has elapsed, rate_scheduler clears the counter. This condition indicates that all blocks running at that rate should execute on the next call to model_step, which is responsible for checking the counters.

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. If applicable, you should also

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.

In addition, you may choose to modify the overrun behavior to continue execution after error recovery is complete.

Please also observe the following cautionary guidelines:

  


 © 1984-2008- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS