Подписание кода, сгенерированного из модели

Генератор кода производит алгоритмический код, как задано вашей моделью. Можно включать внешний (например, пользовательский или устаревший), код в модели при помощи методов, объясненных в, Выбирает External Code Integration Workflow.

Генератор кода также обеспечивает интерфейс, который выполняет сгенерированный типовой код. Интерфейсный и типовой кодекс скомпилирован вместе, чтобы создать исполняемую программу. Следующий рисунок показывает высокоуровневое объектно-ориентированное представление исполняемого файла.

Объектно-ориентированное представление программы в реальном времени

В общем случае концептуальный проект драйвера выполнения модели не изменяется между быстрым прототипированием и встроенным стилем сгенерированного кода. Следующие разделы описывают выполнение модели для однозадачных и многозадачных сред и для симуляции (нев реальном времени) и в течение реального времени. Для большей части типового кодекса многозадачная среда обеспечивает самое эффективное выполнение модели (то есть, самую быструю частоту дискретизации).

Следующие концепции полезны в описании, как типовой кодекс выполняется.

  • Initialization: model_initialize инициализирует интерфейсный код и типовой кодекс.

  • ModelOutputs: Вызовы блокируются в вашей модели, которые имеют демонстрационный хит в текущее время, и сделал, чтобы они произвели свой выход. modelвывод может быть сделан в главных или незначительных временных шагах. В главных временных шагах выход является данным шагом времени симуляции. В незначительных временных шагах интерфейс интегрирует производные, чтобы обновить непрерывные состояния.

  • ModelUpdate: model_update блоки вызовов, которые имеют выборку, нападают на текущий момент времени, и сделал, чтобы они обновили свои дискретные состояния или подобные текстовые объекты.

  • ModelDerivatives: Вызовы блокируются в вашей модели, которые имеют непрерывные состояния, и сделал, чтобы они обновили свои производные. model_derivatives только называется в незначительных временных шагах.

  • ModelTerminate: model_terminate отключает программу, если она спроектирована, чтобы запуститься в течение конечного промежутка времени. Это уничтожает структуру данных модели реального времени, освобождает память и может записать данные к файлу.

Выполнение программы

Программа в реальном времени не может потребовать 100% процессорного времени. Это требование обеспечивает возможность запустить фоновые задачи в течение свободного времени.

Фоновые задачи включают операции, такие как записывание данные к буферу или файлу, предоставление доступа к данным о программе сторонними инструментами мониторинга данных или обновления параметров программы.

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

Путем программа справляется, задачи зависит от возможностей среды, в которой она действует.

Синхронизация программы

Программы в реальном времени требуют тщательной синхронизации вызовов задачи (или при помощи прерывания или при помощи операционной системы реального времени, определяющей задачу примитивного) так, чтобы типовой кодекс выполнился к завершению, прежде чем другой вызов задачи произойдет. Синхронизация включает время, чтобы читать и записать данные к и от внешнего оборудования.

Следующая фигура иллюстрирует синхронизацию прерывания.

Синхронизация задачи

Демонстрационный интервал должен быть достаточно длинным, чтобы позволить выполнение типового кодекса между вызовами задачи.

На рисунке выше, время между двумя смежными вертикальными стрелками является демонстрационным интервалом. Пустые поля в верхней схеме показывают пример программы, которая может завершить один шаг в интервале и все еще позволить время для фоновой задачи. Серое поле в более низкой схеме указывает на то, что происходит, если демонстрационный интервал слишком короток. Другой вызов задачи происходит, прежде чем задача завершена. Такая синхронизация приводит к ошибке выполнения.

Если программа в реальном времени спроектирована, чтобы запуститься навсегда (то есть, итоговое время 0 или бесконечно так, чтобы while цикл никогда не выходит), затем код завершения работы не выполняется.

Для получения дополнительной информации о том, как работает механизм синхронизации, смотрите Расчет Абсолютного и Прошедшего времени.

Коммуникация режима external mode

Режим external mode позволяет связь между блок-схемой Simulink® и автономной программой, которая создается из сгенерированного кода. В этом режиме программа в реальном времени функционирует как сервер межпроцессного взаимодействия, отвечая на запросы от механизма Simulink.

Регистрация данных в однозадачном и многозадачном выполнении модели

Сконфигурируйте Модель для Отладки, объясняет, как можно сохранить системные состояния, выходные параметры, и время к MAT-файлу при завершении выполнения модели. LogTXY функция, которая выполняет регистрацию данных, действует по-другому в однозадачных и многозадачных средах.

Если вы исследуете как LogTXY называется в однозадачных и многозадачных средах, заметьте это для однозадачности LogTXY называется после ModelOutputs. Во время этого ModelOutputs вызовите, блоки, которые имеют хит во время t, выполняются, тогда как в многозадачности, LogTXY называется после ModelOutputs(tid=0), который выполняет только блоки, которые имеют хит во время t и которые имеют идентификатор задачи 0. Это приводит к различиям в регистрируемых значениях между однозадачным и многозадачным логгированием. А именно, рассмотрите модель с двумя шагами расчета, более быстрый шаг расчета, имеющий период 1,0 секунд и более медленного шага расчета, имеющего период 10,0 секунд. Во время t = k*10, k=0,1,2... оба быстрое (tid=0) и медленный (tid=1) блоки выполняются. При выполнении в многозадачном режиме, когда LogTXY называется, медленные блоки выполняются, но предыдущее значение регистрируется, тогда как в однозадачности текущее значение регистрируется.

Другое различие происходит при регистрации данных в активированной подсистеме. Рассмотрите активированную подсистему, которая имеет медленный сигнал, управляющий разрешать портом, и быстро блокируется в активированной подсистеме. В этом случае оценка разрешать сигнала происходит в медленной задаче, и быстрые блоки видят задержку одного периода расчета; таким образом регистрируемые значения покажут эти различия.

Чтобы обобщить различия в записанных данных между однозадачностью и многозадачностью, различия будут замечены когда

  • Корневой блок выходного порта имеет шаг расчета, который медленнее, чем самый быстрый шаг расчета

  • Блок с состояниями имеет шаг расчета, который медленнее, чем самый быстрый шаг расчета

  • Блок в активированной подсистеме, где сигнал, управляющий разрешать портом, медленнее, чем уровень блоков в активированной подсистеме

Для первых двух случаев, даже при том, что регистрируемые значения отличаются между однозадачностью и многозадачностью, результаты модели не отличаются. Единственная реальная разница - то, где (в какой момент времени) логгирование сделано. Третье (включил подсистему), результаты случая в задержке, которая видна в окружении реального времени.

Однозадачные системы нев реальном времени

Этот псевдокод показывает выполнение модели для однозадачной системы нев реальном времени.

main()
{
  Initialization
  While (time < final time)
    ModelOutputs     -- Major time step.
    LogTXY           -- Log time, states and root outports.
    ModelUpdate      -- Major time step.
    Integrate        -- Integration in minor time step for 
                     -- models with continuous states.
      ModelDerivatives
      Do 0 or more
        ModelOutputs
        ModelDerivatives
      EndDo -- Number of iterations depends upon the solver
      Integrate derivatives to update continuous states.
    EndIntegrate
  EndWhile
  Termination
}

Фаза инициализации начинается сначала. Это состоит из инициализации состояний модели и подготовки механизм выполнения. Модель затем выполняется, один шаг за один раз. Сначала ModelOutputs выполняется во время t, затем данные о вводе-выводе рабочей области регистрируются, и затем ModelUpdate обновляет дискретные состояния. Затем, если ваша модель имеет непрерывные состояния, ModelDerivatives интегрирует производные непрерывных состояний, чтобы сгенерировать состояния в течение времени tnew=t+h, где h является размером шага. Время затем продвигается к tnew и повторения процесса.

Во время ModelOutputs и ModelUpdate фазы выполнения модели, только блокирует ту досягаемость, которую выполняет текущий момент времени.

Многозадачные системы нев реальном времени

Этот псевдокод показывает выполнение модели для многозадачной системы нев реальном времени.

main()
{
  Initialization
  While (time < final time)
    ModelOutputs(tid=0)   -- Major time step.
    LogTXY                -- Log time, states, and root 
                          -- outports.
    ModelUpdate(tid=0)    -- Major time step.
    Integrate       -- Integration in minor time step for 
                    -- models with continuous states.
      ModelDerivatives
      Do 0 or more
        ModelOutputs(tid=0)
        ModelDerivatives
      EndDo (Number of iterations depends upon the solver.)
      Integrate derivatives to update continuous states.
    EndIntegrate
    For i=1:NumTids
      ModelOutputs(tid=i) -- Major time step.
      ModelUpdate(tid=i)  -- Major time step.
    EndFor
  EndWhile
  Termination
  }

Многозадачная операция является более комплексной, чем однозадачное выполнение, потому что функции выхода и обновления подразделены идентификатором задачи (tid) это передается в эти функции. Это допускает несколько вызовов этих функций с идентификаторами различной задачи с помощью перекрытых прерываний, или для нескольких задач при использовании операционной системы реального времени. В симуляции несколько задач эмулированы путем выполнения кода в порядке, который произошел бы, если бы вытеснение не существовало в системе реального времени.

Многозадачное выполнение принимает, что уровни задачи являются множителями базовой ставки. Продукт Simulink осуществляет это, когда вы создаете модель многозадачности фиксированного шага. Многозадачный цикл выполнения очень похож на ту из однозадачности, за исключением использования идентификатора задачи (tid) аргумент к ModelOutputs и ModelUpdate.

Вы не можете использовать tid значения из кода, сгенерированного конечным файлом а не Simulink Coder™. Simulink Coder отслеживает использование tid при генерации кода для определенной подсистемы или функционального типа. Когда вы генерируете код в конечном файле, этот аргумент не может быть прослежен, потому что осциллограф не имеет подсистемы или функционирует тип. Поэтому tid становится неопределенной переменной, и вашему конечному файлу не удается скомпилировать.

Однозадачные системы в реальном времени

Этот псевдокод показывает выполнение модели в однозадачной системе в реальном времени, куда модель запущена на уровне прерывания.

rtOneStep()
{
  Check for interrupt overflow
  Enable "rtOneStep" interrupt
  ModelOutputs    -- Major time step.
  LogTXY          -- Log time, states and root outports.
  ModelUpdate     -- Major time step.
  Integrate       -- Integration in minor time step for models 
                  -- with continuous states.
     ModelDerivatives
     Do 0 or more 
       ModelOutputs
       ModelDerivatives
     EndDo (Number of iterations depends upon the solver.)
     Integrate derivatives to update continuous states.
  EndIntegrate
}

main()
{
  Initialization (including installation of rtOneStep as an 
  interrupt service routine, ISR, for a real-time clock).
  While(time < final time)
    Background task.
  EndWhile
  Mask interrupts (Disable rtOneStep from executing.)
  Complete any background tasks.
  Shutdown
}

Однозадачное выполнение в реальном времени очень похоже на однозадачное выполнение нев реальном времени, за исключением того, что вместо свободного доступа код, rt_OneStep функция управляется периодическим прерыванием по таймеру.

В интервале, заданном основной частотой дискретизации программы, процедура обработки прерывания (ISR) вытесняет фоновую задачу выполнить типовой код. Основная частота дискретизации является самой быстрой в модели. Если модель имеет непрерывные блоки, то размер этапа интеграции определяет основную частоту дискретизации.

Например, если типовой кодекс является контроллером, действующим на уровне 100 Гц, то каждую 0.01 секунды фоновая задача прервана. Во время этого прерывания диспетчер читает его входные параметры из аналого-цифрового конвертера (ADC), вычисляет его выходные параметры, пишет эти выходные параметры в цифро-аналоговый преобразователь (DAC) и обновляет его состояния. Программное управление затем возвращается к фоновой задаче. Эти шаги должны произойти перед следующим прерыванием.

Многозадачные системы в реальном времени

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

rtOneStep()
{
  Check for interrupt overflow
  Enable "rtOneStep" interrupt
  ModelOutputs(tid=0)     -- Major time step.
  LogTXY                  -- Log time, states and root outports.
  ModelUpdate(tid=0)      -- Major time step.
  Integrate               -- Integration in minor time step for 
                          -- models with continuous states.
     ModelDerivatives
     Do 0 or more
       ModelOutputs(tid=0)
       ModelDerivatives
     EndDo (Number of iterations depends upon the solver.)
     Integrate derivatives and update continuous states.
  EndIntegrate
  For i=1:NumTasks
    If (hit in task i)
      ModelOutputs(tid=i)
      ModelUpdate(tid=i)
    EndIf
  EndFor
}

main()
{
  Initialization (including installation of rtOneStep as an 
    interrupt service routine, ISR, for a real-time clock).
  While(time < final time)
    Background task.
  EndWhile
  Mask interrupts (Disable rtOneStep from executing.) 
  Complete any background tasks.
  Shutdown
}

Под управлением модели на уровне прерывания в многозадачной среде в реальном времени очень похожи на предыдущую однозадачную среду, за исключением того, что перекрытые прерывания используются для параллельного выполнения задач.

Выполнение модели в однозадачной или многозадачной среде при использовании примитивов управления задачами операционной системы реального времени очень похоже на примеры уровня прерывания, обсужденные выше. Псевдокод ниже для однозадачной модели с помощью примитивов управления задачами в реальном времени.

tSingleRate()
{
  MainLoop:
    If clockSem already "given", then error out due to overflow.
    Wait on clockSem
    ModelOutputs            -- Major time step.
    LogTXY                  -- Log time, states and root 
                            -- outports
    ModelUpdate             -- Major time step
    Integrate               -- Integration in minor time step 
                            -- for models with continuous 
                            -- states.
      ModelDeriviatives
      Do 0 or more
        ModelOutputs
        ModelDerivatives
      EndDo (Number of iterations depends upon the solver.)
      Integrate derivatives to update continuous states.
    EndIntegrate
  EndMainLoop
}

main()
{
  Initialization
  Start/spawn task "tSingleRate".
  Start clock that does a "semGive" on a clockSem semaphore.
  Wait on "model-running" semaphore.
  Shutdown
}

В этой однозадачной среде модель выполняется как примитивы управления задачами операционной системы реального времени. В этой среде создайте одну задачу (tSingleRate) запускать типовой кодекс. Эта задача вызывается, когда такт системных часов происходит. Такт системных часов дает clockSem (синхронизируйте семафор) к задаче модели (tSingleRate). Задача модели ожидает семафора перед выполнением. Такты системных часов происходят в основном размере шага (базовая ставка) для вашей модели.

Многозадачные системы Используя примитивы управления задачами в реальном времени

Этот псевдокод для многозадачной модели с помощью примитивов управления задачами в реальном времени.

tSubRate(subTaskSem,i)
{
  Loop:
    Wait on semaphore subTaskSem.
    ModelOutputs(tid=i)
    ModelUpdate(tid=i)
  EndLoop
}
tBaseRate()
{
  MainLoop:
    If clockSem already "given", then error out due to overflow.
    Wait on clockSem
    For i=1:NumTasks
      If (hit in task i)
        If task i is currently executing, then error out due to 
          overflow.
        Do a "semGive" on subTaskSem for task i.
      EndIf
    EndFor
    ModelOutputs(tid=0)    -- major time step.
    LogTXY                 -- Log time, states and root outports.
    ModelUpdate(tid=0)     -- major time step.
    Loop:                  -- Integration in minor time step for 
                           -- models with continuous states.
      ModelDeriviatives
      Do 0 or more
        ModelOutputs(tid=0)
        ModelDerivatives
      EndDo (number of iterations depends upon the solver).
      Integrate derivatives to update continuous states.
    EndLoop
  EndMainLoop
}
main()
{
  Initialization
  Start/spawn task "tSubRate".
  Start/spawn task "tBaseRate".

  Start clock that does a "semGive" on a clockSem semaphore.
  Wait on "model-running" semaphore.
  Shutdown
}

В этой многозадачной среде модель выполняется с помощью примитивов управления задачами операционной системы реального времени. Такие среды требуют нескольких задач модели (tBaseRate и несколько tSubRate задачи), чтобы запустить типовой кодекс. Задача базовой ставки (tBaseRate) имеет более высокий приоритет, чем задачи подуровня. Задача подуровня for tid=1 имеет более высокий приоритет, чем задача подуровня для tid=2, и так далее. Задача базовой ставки вызывается, когда такт системных часов происходит. Такт системных часов дает clockSem к tBaseRate. Первая вещь tBaseRate делает, дают семафоры подзадачам, которые имеют напавший текущий момент времени. Поскольку задача базовой ставки имеет более высокий приоритет, она продолжает выполняться. Затем это выполняет самую быструю задачу (tid=0), состоя из блоков в вашей модели, которые имеют самый быстрый шаг расчета. После этого выполнения это продолжает ожидать семафора часов. Такты системных часов сконфигурированы, чтобы произойти в основном размере шага для вашей модели.

Быстрое прототипирование и встроенные различия в выполнении модели

Среда программы быстрого прототипирования обеспечивает общий интерфейс прикладного программирования (API), который не изменяется между определениями модели.

Продукт Embedded Coder® служит различной основой, названной встроенной средой программы. Встроенная среда программы обеспечивает оптимизированный API, который адаптируется в соответствии с вашей моделью. Когда вы используете встроенный стиль сгенерированного кода, вы моделируете, как вы хотели бы, чтобы ваш код выполнился в вашей встраиваемой системе. Поэтому определения, заданные в вашей модели, должны быть характерны для ваших целевых процессоров. Элементы, такие как имя модели, параметр и класс памяти сигнала включены как часть API для встроенного стиля кода.

Одно существенное различие между быстрым прототипированием и встроенным стилем сгенерированного кода - то, что последний содержит меньше функций точки входа. Встроенный стиль кода может быть сконфигурирован, чтобы иметь только одну функцию, model_step.

Таким образом код выполнения модели устраняет Loop...EndLoop операторы и группы ModelOutputs, LogTXY, и ModelUpdate в отдельного оператора, model_step.

Для получения дополнительной информации о том, как сгенерированный встроенный код выполняется, смотрите, Конфигурируют генерацию кода C для Функций Точки входа Модели.

Похожие темы