exponenta event banner

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

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

Сведения о примерной модели

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

open_system('rtwdemo_async_mdlreftop');

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

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

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

  • Task Sync блок

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

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

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

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

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

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

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

  3. В диалоговом окне параметров для 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 блок конфигурируется для прерываний 1 и 2 VME с использованием смещений 192 и 193 векторов прерываний. Прерывание 1 подключено к триггерной подсистеме 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();
}

Проверка кода ISR

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

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

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)

Связанные темы