主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

将 RTOS 中的异步事件作为输入传递给引用模型

此示例展示如何在实时多任务系统上仿真和生成异步事件的代码。

关于示例模型

打开示例模型 AsynchronousEventsTop

open_system('AsynchronousEventsTop');

该模型仿真中断源,包括 Async Interrupt 模块和参考模型。Async Interrupt 模块创建两个 Versa Module Eurocard (VME) 中断服务例程 (ISR),将中断信号传递给引用模型的 Inport 模块 1 和 2。

您可以在仿真中断源和以下模型元素之一之间放置一个 Async Interrupt 模块:

  • 函数调用子系统

  • Task Sync 模块

  • 为函数调用输入事件配置的 Stateflow® 图

  • 带有 Inport 模块的引用模型,该块连接到前面的模型元素之一

在这个示例模型中,Async Interrupt 模块通过 Inport 模块 1 和 2 将异步事件(函数调用触发信号)Interrupt1Interrupt2 传递给引用模型。

代码生成器生成针对 VxWorks 操作系统自定义的代码。重新配置 Async Interrupt 模块以生成用于替代应用程序运行时环境的代码。

打开引用的模型。引用的模型包括两个接收中断的 Inport 模块,每个块连接到一个 Asynchronous Task Specification 模块、函数调用子系统 Count 和 Algorithm 以及 Rate Transition 模块。Asynchronous Task Specification 模块与根级 Inport 模块相结合,允许参考模型接收异步函数调用输入。要使用该模块:

  1. Asynchronous Task Specification 模块连接到输出函数调用触发器的根级 Inport 模块的输出端口。

  2. 选择 Inport 模块的输出函数调用参数以指定它接受函数调用信号。

  3. Asynchronous Task Specification 模块的参数对话框中,设置与 Inport 模块关联的异步任务的任务优先级。指定一个整数或 [].如果指定一个整数,它必须与父模型中 Async Interrupt 模块发起的中断的优先级相匹配。如果指定 [],则优先级不必匹配。

Asynchronous Task Specification 模块代表较高优先级中断 interrupt1,连接到函数调用子系统 CountCount 代表一个简单的中断服务例程 (ISR)。第二个 Asynchronous Task Specification 模块连接到子系统 Algorithm,其中包含更多内容。它包含多个模块并产生两个输出值。两个子系统均在中断级别执行。

对于父模型中为 Async Interrupt 模块指定的每个中断级别,该模块都会生成一个 VME ISR,用于执行所连接的子系统、Task Sync 模块或图。

在示例顶层模型中,Async Interrupt 模块配置用于 VME 中断 1 和 2,使用中断向量偏移量 192 和 193。中断 1 连接到触发子系统 Count。中断 2 连接到触发子系统 Algorithm

Rate Transition 模块处理以不同速率运行的端口之间的数据传输。在两种情况下,这些模块可以保护数据传输(防止数据传输被抢占和破坏)。在另一个示例中,没有发生任何特殊行为。

数据传输假设

  • 数据传输发生在一个读任务和一个写任务之间。

  • 对字节大小变量的读或写操作是原子的。

  • 当两个任务交互时,只有一个任务可以抢占另一个任务。

  • 对于周期性任务,速率较快的任务比速率较慢的任务具有更高的优先级。速率较快的任务会抢占速率较慢的任务。

  • 任务在单个处理器上运行。不允许时间分片。

  • 进程不会崩溃和重新启动,尤其是在任务之间传输数据时。

仿真模型

仿真模型。默认情况下,模型配置为以不同的颜色显示采样时间。输入和输出的离散采样时间分别显示红色和绿色。常量是品红色。异步中断是紫色的。Rate Transition 模块是混合的(输入和输出采样时间可以不同),显示为黄色。

生成代码和报告

为模型生成代码和代码生成报告。为 Async InterruptTask Sync 模块生成的代码适用于示例 RTOS(VxWorks)。但是,您可以修改模块来为另一个运行时环境生成代码。

编译模型。

slbuild('AsynchronousEventsTop');
### Searching for referenced models in model 'AsynchronousEventsTop'.
### Total of 2 models to build.
### Starting serial code generation build.
Warning: Simulink Coder: The tornado.tlc target will be removed in a future release.
### Successfully updated the model reference code generation target for: AsynchronousEventsRef
### Starting build procedure for: AsynchronousEventsTop
Warning: Simulink Coder: The tornado.tlc target will be removed in a future release.
### Successful completion of code generation for: AsynchronousEventsTop

Build Summary

Model reference code generation targets:

Model                  Build Reason                                     Status           Build Duration
=======================================================================================================
AsynchronousEventsRef  Target (AsynchronousEventsRef.c) did not exist.  Code generated.  0h 0m 17.854s 

Top model targets:

Model                  Build Reason                                         Status           Build Duration
===========================================================================================================
AsynchronousEventsTop  Information cache folder or artifacts were missing.  Code generated.  0h 0m 8.9699s 

2 of 2 models built (0 models already up to date)
Build duration: 0h 0m 29.242s

审查初始化代码

打开生成的源文件 AsynchronousEventsTop.c。初始化代码连接并启用中断 1 的 ISR isr_num1_vec192 和中断 2 的 ISR isr_num2_vec193

cfile = fullfile('AsynchronousEventsTop_tornado_rtw', 'AsynchronousEventsTop.c');
coder.example.extractLines(cfile, ...
    'static void AsynchronousEventsTop_initialize(void)', ...
    '/* Model terminate function */', ... 
    1, 0);
static void AsynchronousEventsTop_initialize(void)
{
  /* Start for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

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

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

审查 ISR 代码

在生成的源文件 AsynchronousEventsTop.c 中,检查 ISR isr_num1_vec192isr_num2_vec293 的代码。每个 ISR:

  • 禁用中断。

  • 保存浮点上下文。

  • 调用为连接到接收中断的引用模型 Inport 模块的子系统生成的代码。

  • 恢复浮点上下文。

  • 重新启用中断。

cfile = fullfile('AsynchronousEventsTop_tornado_rtw', 'AsynchronousEventsTop.c');
coder.example.extractLines(cfile, ...
    'void isr_num1_vec192(void)', ...
    'time_T rt_SimUpdateDiscreteEvents', ... 
    1, 0);
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'
     *  Outport: '<Root>/Out1'
     *  Outport: '<Root>/Out2'
     *  Outport: '<Root>/Out3'
     */
    AsynchronousEventsRef_Interrupt1(&AsynchronousEventsTop_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'
     *  Outport: '<Root>/Out1'
     *  Outport: '<Root>/Out2'
     *  Outport: '<Root>/Out3'
     */
    AsynchronousEventsRef_Interrupt2();

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

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

审查任务终止代码

Task Sync 模块生成以下终止代码。

cfile = fullfile('AsynchronousEventsTop_tornado_rtw', 'AsynchronousEventsTop.c');
coder.example.extractLines(cfile, ...
    'static void AsynchronousEventsTop_terminate(void)', ...
    '/*========================================================================*', ... 
    1, 0);
static void AsynchronousEventsTop_terminate(void)
{
  /* Terminate for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

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

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

相关信息

另请参阅

主题