В этом примере показано, как симулировать и сгенерировать код для асинхронных событий в многозадачной системе в реальном времени.
Откройте модель rtwdemo_async_mdlreftop
в качестве примера.
open_system('rtwdemo_async_mdlreftop');
Модель симулирует источник прерывания и включает Async Interrupt
блокируйтесь и модель, на которую ссылаются. Async Interrupt
блок создает две процедуры обработки прерывания Еврокарты модуля Versa (VME) (ISRs), которые передают сигналы прерывания блокам 1 и 2 Inport модели, на которую ссылаются.
Можно поместить Async Interrupt
блокируйтесь между симулированным источником прерывания и одним из этих элементов модели:
Подсистема вызова функции
Task Sync
блок
Диаграмма Stateflow, сконфигурированная для вызова функции, ввела событие
Модель, на которую ссылаются, с Inport
блокируйтесь, который соединяется с одним из предыдущих элементов модели
В этой модели в качестве примера, Async Interrupt
блокируйте передачи асинхронные события (триггерные сигналы вызова функции), Interrupt1
и Interrupt2
, к модели, на которую ссылаются, через Inport
блоки 1 и 2.
Генератор кода производит код, который адаптируется для операционной системы VxWorks. Реконфигурируйте Async Interrupt
блокируйтесь, чтобы сгенерировать код для альтернативной среды выполнения приложения.
Откройте модель, на которую ссылаются. Модель, на которую ссылаются, включает два Inport
блоки, которые получают прерывания, каждый соединенный с Asynchronous Task Specification
блок, количество подсистем вызова функций и Алгоритм и Rate Transition
блоки. Asynchronous Task Specification
блокируйтесь, в сочетании с корневым уровнем Inport
блокируйтесь, позволяет образцу модели получать асинхронный вход вызова функции. Использовать блок:
Соедините Asynchronous Task Specification
блокируйте к выходному порту корневого уровня Inport
блокируйтесь это выводит триггер вызова функции.
Выберите параметр вызова Выходной функции Inport
блокируйтесь, чтобы указать, что это принимает сигналы вызова функции.
На диалоговом окне параметров для Asynchronous Task Specification
блокируйте, установите приоритет задач для асинхронной задачи, сопоставленной с Inport
блок. Задайте целое число или []. Если вы задаете целое число, оно должно совпадать с приоритетом прерывания, инициируемого Async Interrupt
блокируйтесь в родительской модели. Если вы задаете [], приоритеты не должны соответствовать.
Asynchronous Task Specification
блокируйтесь для более высокого приоритетного прерывания, interrupt1
, соедините с подсистемой вызова функций Count
количество
представляет простую процедуру обработки прерывания (ISR). Второй Asynchronous Task Specification
блок connect к подсистеме Algorithm
, который включает больше вещества. Это включает несколько блоков и производит два выходных значения. Обе подсистемы выполняются на уровне прерывания.
Для каждого уровня прерывания, заданного для Async Interrupt
блокируйтесь в родительской модели, блок генерирует ISR VME, который выполняет связанную подсистему, Task Sync
блокируйтесь, или график.
В топ-модели в качестве примера, Async Interrupt
блок сконфигурирован для прерываний 1 и 2 VME, использование вектора прерывания возмещает 192 и 193. Прерывание 1 соединено, чтобы инициировать subsystem Count
. Прерывание 2 соединено, чтобы инициировать подсистему Algorithm
.
Rate Transition
блоки обрабатывают передачи данных между портами, которые действуют на различных уровнях. В двух экземплярах блоки защищают передачи данных (препятствуйте тому, чтобы они были вытеснены и повреждены). В другом экземпляре не происходит никакое специальное поведение.
Передачи данных находятся между одной задачей считывания и одной задачей записи.
Операция чтения или операция записи на переменной размера байта являются атомарными.
Когда две задачи взаимодействуют, только один может вытеснить другой.
Для периодических задач задача с более быстрым уровнем имеет более высокий приоритет, чем задача с более медленным уровнем. Задача с более быстрым уровнем вытесняет задачи с более медленными уровнями.
Задачи работают на одном процессоре. Квантование времени не позволено.
Процессы не разрушают и перезапускают, особенно в то время как данные передаются между задачами.
Симулируйте модель. По умолчанию модель сконфигурирована, чтобы отобразить шаги расчета различными цветами. Дискретные шаги расчета для ввода и вывода кажутся красными и зелеными, соответственно. Константы являются пурпурным. Асинхронные прерывания являются фиолетовыми. Rate Transition
блоки, которые являются гибридом (шаги расчета ввода и вывода могут отличаться), кажутся желтыми.
Сгенерируйте код и отчет генерации кода для модели. Async Interrupt
блок и Task Sync
блокируйтесь сгенерированный код для примера RTOS (VxWorks). Однако можно изменить блоки, чтобы сгенерировать код для другой среды выполнения.
1. Создайте временную папку для сборки и инспекционного процесса.
currentDir = pwd; [~,cgDir] = rtwdemodir();
2. Создайте модель.
slbuild('rtwdemo_async_mdlreftop');
### Starting serial model reference 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: rtwdemo_async_mdlrefbot ### Starting build procedure for: rtwdemo_async_mdlreftop
Warning: Simulink Coder: The tornado.tlc target will be removed in a future release.
### Successful completion of code generation for: rtwdemo_async_mdlreftop Build Summary Code generation targets built: Model Action Rebuild Reason ==================================================================================== rtwdemo_async_mdlrefbot Code generated rtwdemo_async_mdlrefbot.c does not exist. Top model targets built: Model Action Rebuild Reason =========================================================================================== rtwdemo_async_mdlreftop Code generated Code generation information file does not exist. 2 of 2 models built (0 models already up to date) Build duration: 0h 0m 39.589s
Откройте сгенерированный исходный файл rtwdemo_async_mdlreftop.c
. Код инициализации соединяет и включает ISR isr_num1_vec192
для прерывания 1 и ISR isr_num2_vec193
для прерывания 2.
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c'); rtwdemodbtype(cfile, ... 'static void rtwdemo_async_mdlreftop_initialize(void)', ... '/* Model terminate function */', ... 1, 0);
static void rtwdemo_async_mdlreftop_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' */ /* SystemInitialize for 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' */ rtwdemo_async_mdlrefbot_Init(&rtwdemo_async_mdlreftop_Y.Out1); rtwdemo_async_mdlrefbot_Enable(); }
В сгенерированном исходном файле rtwdemo_async_mdlreftop.c
, рассмотрите код для isr_num1_vec192
ISRs и
isr_num2_vec293
. Каждый ISR:
Отключает прерывания.
Сохраняет контекст с плавающей точкой.
Вызывает код, сгенерированный для подсистемы, соединенной с моделью Inport
, на которую ссылаются, блокируйтесь, который получает прерывание.
Восстанавливает контекст с плавающей точкой.
Повторно включает прерывания.
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c'); rtwdemodbtype(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' */ 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' * Outport: '<Root>/Out1' * Outport: '<Root>/Out2' * Outport: '<Root>/Out3' */ rtwdemo_async_mdlrefbot_Interrupt2(); /* End of Outputs for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */ } /* restore floating point context */ fppRestore(&context); }
Task Sync
блок генерирует следующий код завершения.
cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c'); rtwdemodbtype(cfile, ... 'static void rtwdemo_async_mdlreftop_terminate(void)', ... '/*========================================================================*', ... 1, 0);
static void rtwdemo_async_mdlreftop_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' */ }
bdclose('rtwdemo_async_mdlreftop');
rtwdemoclean;
cd(currentDir)