Передайте асинхронные События в RTOS как вход к модели, на которую ссылаются,

В этом примере показано, как симулировать и сгенерировать код для асинхронных событий в многозадачной системе в реальном времени.

О модели в качестве примера

Откройте модель 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 блокируйтесь, позволяет образцу модели получать асинхронный вход вызова функции. Использовать блок:

  1. Соедините Asynchronous Task Specification блокируйте к выходному порту корневого уровня Inport блокируйтесь это выводит триггер вызова функции.

  2. Выберите параметр вызова Выходной функции Inport блокируйтесь, чтобы указать, что это принимает сигналы вызова функции.

  3. На диалоговом окне параметров для 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. Создайте модель.

rtwbuild('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 35.401s

Рассмотрите код инициализации

Откройте сгенерированный исходный файл 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();
}

Рассмотрите код ISR

В сгенерированном исходном файле 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)

Похожие темы