将 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 将异步事件(函数调用触发信号)Interrupt1
和 Interrupt2
传递给引用模型。
代码生成器生成针对 VxWorks 操作系统自定义的代码。重新配置 Async Interrupt
模块以生成用于替代应用程序运行时环境的代码。
打开引用的模型。引用的模型包括两个接收中断的 Inport
模块,每个块连接到一个 Asynchronous Task Specification
模块、函数调用子系统 Count 和 Algorithm 以及 Rate Transition
模块。Asynchronous Task Specification
模块与根级 Inport
模块相结合,允许参考模型接收异步函数调用输入。要使用该模块:
将
Asynchronous Task Specification
模块连接到输出函数调用触发器的根级Inport
模块的输出端口。选择
Inport
模块的输出函数调用参数以指定它接受函数调用信号。在
Asynchronous Task Specification
模块的参数对话框中,设置与Inport
模块关联的异步任务的任务优先级。指定一个整数或 [].如果指定一个整数,它必须与父模型中Async Interrupt
模块发起的中断的优先级相匹配。如果指定 [],则优先级不必匹配。
Asynchronous Task Specification
模块代表较高优先级中断 interrupt1
,连接到函数调用子系统 Count
。Count
代表一个简单的中断服务例程 (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 Interrupt
和 Task 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_vec192
和 isr_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' */ }