MATLAB Examples

Pass Asynchronous Events in RTOS as Input To a Referenced Model

This example shows how to simulate and generate code for a model that triggers asynchronous events in an example RTOS (VxWorks®) that get passed as input to a referenced model.

Contents

Open Example Model

Open the example model rtwdemo_async_mdlreftop.

Warning: Undefined function 'LibraryBrowserCustomizer' for
input arguments of type 'DAStudio.CustomizationManager'. 

The model simulates an interrupt source and includes an Async Interrupt block and referenced model. The Async Interrupt block creates two Versa Module Eurocard (VME) interrupt service routines (ISRs) that pass interrupt signals to Inport blocks 1 and 2 of the referenced model. 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® chart configured for a function call input event
  • A referenced model with a Inport block that connects to one of the preceding model elements

In this example model, the Async Interrupt block passes asynchronous events (function-call trigger signals), Interrupt1 and Interrupt2, to the referenced model through Inport blocks 1 and 2.

The code generated for the Async Interrupt block is tailored for the example real-time operating system (VxWorks). However, you can modify the block to generate code specific to your run-time environment.

Open the referenced model.

The referenced model includes the two Inport blocks that receive the interrupts, each connected to an Asynchronous Task Specification block, function-call subsystems Count and Algorithm, and Rate Transition blocks. The Asynchronous Task Specification block, in combination with a root-level Inport block, allows a reference model to receive asynchronous function-call input. To use the block:

  1. Connect the Asynchronous Task Specification block to the output port of a root-level Inport block that outputs a function-call trigger.
  2. Select the Output function call parameter of the Inport block to specify that it accepts function-call signals.
  3. On the Asynchronous Task Specification parameters dialog box, set the task priority for the asynchronous task associated with an Inport block. Specify an integer or []. If you specify an integer, it must match the priority of the interrupt initiated by the Async Interrupt block in the parent model. If you specify [], the priorities do not have to match.

The Asynchronous Task Specification block for the higher priority interrupt, interrupt1, connects to function-call subsystem Count. Count represents a simple interrupt service routine (ISR). The second Asynchronous Task Specification block connects to the subsystem Algorithm, which includes more substance. It includes multiple blocks and produces two output values. Both subsystems execute at interrupt level.

For each interrupt level specified for the Async Interrupt block in the parent model, the block generates a VME ISR that executes the connected subsystem, Task Sync block, or chart.

In the example top model, the Async Interrupt block is configured for VME interrupts 1 and 2, using interrupt vector offsets 192 and 193. Interrupt 1 is wired to trigger subsystem Count. Interrupt 2 is wired to trigger subsystem Algorithm.

The Rate Transition blocks handle data transfers between ports that operate at different rates. In two instances, the blocks protect data transfers (prevent them from being preempted and corrupted). In the other instance, no special behavior occurs.

Data Transfer Assumptions

  • Data transfers occur between one reading task and one writing task.
  • A read or write operation on a byte-sized 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 slower rates.
  • Tasks run on a single processor. Time slicing is not allowed.
  • Processes do not crash 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 magenta. Asynchronous interrupts are purple. The Rate Transition Blocks, which are hybrid (input and output sample times can differ), appear yellow.

Generate Code and Report

Generate code and a code generation report for the model. Async Interrupt block and Task Sync block generated code is for the example RTOS (VxWorks). 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.

2. Build the model.

Warning:  Simulink Coder: The tornado.tlc target will be removed in a future release.

### Wrapping unrecognized make command (angle brackets added)
###    <make>
### in default batch file
### Successfully updated the model reference RTW target for model: rtwdemo_async_mdlrefbot
### Starting build procedure for model: rtwdemo_async_mdlreftop
Warning:  Simulink Coder: The tornado.tlc target will be removed in a future release.

### Wrapping unrecognized make command (angle brackets added)
###    <make>
### in default batch file
### Successful completion of code generation for model: rtwdemo_async_mdlreftop

Review Initialization Code

Open the generated source file rtwdemo_async_mdlreftop.c. The initialization code connects and enables ISR isr_num1_vec192 for interrupt 1 and ISR isr_num2_vec193 for interrupt 2.

static void rtwdemo_async_mdlreftop_initialize(void)
{
  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Connect and enable ISR function: isr_num1_vec192 */
  if (intConnect(INUM_TO_IVEC(192), isr_num1_vec192, 0) != OK) {
    printf("intConnect failed for ISR 1.\n");
  }

  sysIntEnable(1);

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Connect and enable ISR function: isr_num2_vec193 */
  if (intConnect(INUM_TO_IVEC(193), isr_num2_vec193, 0) != OK) {
    printf("intConnect failed for ISR 2.\n");
  }

  sysIntEnable(2);

  /* SystemInitialize for ModelReference: '<Root>/Model' */
  rtwdemo_async_mdlrefbot_Init(&rtwdemo_async_mdlreftop_Y.Out1);

  /* Enable for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

  /* Enable for ModelReference: '<Root>/Model' incorporates:
   *  Enable for Inport: '<Root>/In1_60hz'
   *  Enable for Inport: '<Root>/In2_60_hz'
   *  Enable for Inport: '<Root>/In3_60hz'
   */
  rtwdemo_async_mdlrefbot_Interrupt1_Enable();
  rtwdemo_async_mdlrefbot_Interrupt2_Enable();

  /* End of Enable for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
}

Review ISR Code

In the generated source file rtwdemo_async_mdlreftop.c, review the code for ISRs isr_num1_vec192 and isr_num2_vec293. Each ISR:

  • Disables interrupts.
  • Saves floating-point context.
  • Calls the code generated for the subsystem connected to the referenced model Inport block that receives the interrupt.
  • Restores floating-point context.
  • Reenables interrupts.
void isr_num1_vec192(void)
{
  int_T lock;
  FP_CONTEXT context;

  /* disable interrupts (system is configured as non-preemptive) */
  lock = intLock();

  /* save floating point context */
  fppSave(&context);

  /* Call the system: '<Root>/Model' */
  {
    /* S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

    /* ModelReference: '<Root>/Model' incorporates:
     *  Inport: '<Root>/In1_60hz'
     *  Inport: '<Root>/In2_60_hz'
     *  Inport: '<Root>/In3_60hz'
     */
    rtwdemo_async_mdlrefbot_Interrupt1(&rtwdemo_async_mdlreftop_Y.Out1);

    /* End of Outputs for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
  }

  /* restore floating point context */
  fppRestore(&context);

  /* re-enable interrupts */
  intUnlock(lock);
}

/* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
void isr_num2_vec193(void)
{
  FP_CONTEXT context;

  /* save floating point context */
  fppSave(&context);

  /* Call the system: '<Root>/Model' */
  {
    /* S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

    /* ModelReference: '<Root>/Model' incorporates:
     *  Inport: '<Root>/In1_60hz'
     *  Inport: '<Root>/In2_60_hz'
     *  Inport: '<Root>/In3_60hz'
     */
    rtwdemo_async_mdlrefbot_Interrupt2();

    /* End of Outputs for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
  }

  /* restore floating point context */
  fppRestore(&context);
}

Review Task Termination Code

The Task Sync block generates the following termination code.

static void rtwdemo_async_mdlreftop_terminate(void)
{
  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Disable interrupt for ISR system: isr_num1_vec192 */
  sysIntDisable(1);

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Disable interrupt for ISR system: isr_num2_vec193 */
  sysIntDisable(2);
}

Related Information