Передайте асинхронные события в RTOS как вход в ссылочную Модель

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

Об модели примера

Откройте пример модели rtwdemo_async_mdlreftop.

open_system('rtwdemo_async_mdlreftop');

Модель описывает источник прерывания и включает в себя Async Interrupt блочная и ссылочная модель. The Async Interrupt блок создает две служебные стандартные программы прерывания (ISR) Versa Module Eurocard (VME), которые передают сигналы прерывания в блоки Inport 1 и 2 ссылочных моделей.

Можно разместить Async Interrupt блок между моделируемым источником прерывания и одним из следующих элементов модели:

  • Подсистема вызова функции

  • Task Sync блок

  • Диаграмма Stateflow, сконфигурированная для входного события вызова функции

  • Ссылка на модель с Inport блок, который соединяется с одним из предыдущих элементов модели

В этой модели примера Async Interrupt блок передает асинхронные события (триггерные сигналы вызова функции), Interrupt1 и Interrupt2, на ссылку модели через Inport блоки 1 и 2.

Генератор кода производит код, адаптированный для операционной системы VxWorks. Перенастройте Async Interrupt блок для генерации кода для альтернативного окружения во время выполнения приложения.

Откройте ссылочную модель. Ссылочная модель включает два Inport блоки, которые получают прерывания, каждый соединяется с Asynchronous Task Specification блок, подсистемы вызова функций счетчик и алгоритм, и Rate Transition блоки. The Asynchronous Task Specification блок, в комбинации с корневым уровнем Inport блок, позволяет образцу модели принимать асинхронные входы вызова функции. Чтобы использовать блок:

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

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

  3. В диалоговом окне параметров для Asynchronous Task Specification блок, установите приоритет задачи для асинхронной задачи, связанной со Inport блок. Задайте целое число или []. Если вы задаете целое число, оно должно совпадать с приоритетом прерывания, инициируемого Async Interrupt блок в родительской модели. Если вы задаете [], приоритеты не должны совпадать.

The Asynchronous Task Specification блок для прерывания с более высоким приоритетом, interrupt1, соединяйтесь с подсистемой вызова функций Count. Count представляет простую стандартную программу обработки прерывания (ISR). Вторая Asynchronous Task Specification блочное соединение с подсистемой Algorithm, который включает больше вещества. Он включает несколько блоков и создает два выходных значения. Обе подсистемы выполняются на уровне прерывания.

Для каждого уровня прерывания, заданного для Async Interrupt блок в родительской модели, блок генерирует VME ISR, который выполняет подключенную подсистему, Task Sync блок, или график.

В примере верхней модели Async Interrupt блок сконфигурирован для прерываний 1 и 2 VME, с помощью смещений векторов прерывания 192 и 193. Прерывание 1 подключено для запуска подсистемы Count. Прерывание 2 подключено для запуска подсистемы Algorithm.

The Rate Transition блоки обрабатывают передачу данных между портами, которые работают с различными скоростями. В двух образцах блоки защищают передачу данных (препятствуют их упреждению и повреждению). В другом образце специального поведения не происходит.

Допущения к передаче данных

  • Передача данных происходит между одной задачей чтения и одной задачей записи.

  • Операция чтения или записи переменной размером в байт является атомарной.

  • Когда две задачи взаимодействуют, только одна может превентировать другую.

  • Для периодических задач задача с более высокой частотой имеет более высокий приоритет, чем задача с более низкой частотой. Задача с более высокой скоростью прерывает задачи с более медленными скоростями.

  • Задачи выполняются на одном процессоре. Квантование времени не разрешено.

  • Процессы не завершаются и не перезапускаются, особенно в то время как данные передаются между задачами.

Симулируйте модель

Симулируйте модель. По умолчанию модель сконфигурирована так, чтобы показывать шаги расчета в разных цветах. Дискретные шаги расчета для входа и выхода выглядят красным и зеленым, соответственно. Константы пурпурные. Асинхронные прерывания фиолетовые. The 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();
}

Просмотр кода ISR

В сгенерированном исходном файле rtwdemo_async_mdlreftop.c, проверьте код для ISRs isr_num1_vec192 и 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);
}

Проверьте код окончания задачи

The 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)

Похожие темы