Генератор кода производит алгоритмический код, как задано вашей моделью. Можно включать внешний (например, пользовательский или устаревший), код в модели при помощи методов, объясненных в, Выбирает External Code Integration Workflow.
Генератор кода также обеспечивает интерфейс, который выполняет сгенерированный типовой код. Интерфейсный и типовой кодекс скомпилирован вместе, чтобы создать исполняемую программу. Следующий рисунок показывает высокоуровневое объектно-ориентированное представление исполняемого файла.
Объектно-ориентированное представление программы в реальном времени
В общем случае концептуальный проект драйвера выполнения модели не изменяется между быстрым прототипированием и встроенным стилем сгенерированного кода. Следующие разделы описывают выполнение модели для однозадачных и многозадачных сред и для симуляции (нев реальном времени) и в течение реального времени. Для большей части типового кодекса многозадачная среда обеспечивает самое эффективное выполнение модели (то есть, самую быструю частоту дискретизации).
Следующие концепции полезны в описании, как типовой кодекс выполняется.
Initialization:
инициализирует интерфейсный код и типовой кодекс.model
_initialize
ModelOutputs: Вызовы блокируются в вашей модели, которые имеют демонстрационный хит в текущее время, и сделал, чтобы они произвели свой выход.
может быть сделан в главных или незначительных временных шагах. В главных временных шагах выход является данным шагом времени симуляции. В незначительных временных шагах интерфейс интегрирует производные, чтобы обновить непрерывные состояния.model
вывод
ModelUpdate:
блоки вызовов, которые имеют выборку, нападают на текущий момент времени, и сделал, чтобы они обновили свои дискретные состояния или подобные текстовые объекты.model
_update
ModelDerivatives: Вызовы блокируются в вашей модели, которые имеют непрерывные состояния, и сделал, чтобы они обновили свои производные.
только называется в незначительных временных шагах.model
_derivatives
ModelTerminate:
отключает программу, если она спроектирована, чтобы запуститься в течение конечного промежутка времени. Это уничтожает структуру данных модели реального времени, освобождает память и может записать данные к файлу.model
_terminate
Программа в реальном времени не может потребовать 100% процессорного времени. Это требование обеспечивает возможность запустить фоновые задачи в течение свободного времени.
Фоновые задачи включают операции, такие как записывание данные к буферу или файлу, предоставление доступа к данным о программе сторонними инструментами мониторинга данных или обновления параметров программы.
Важно, однако, чтобы программа смочь вытеснить фоновую задачу так типовой кодекс могла выполниться в режиме реального времени.
Путем программа справляется, задачи зависит от возможностей среды, в которой она действует.
Программы в реальном времени требуют тщательной синхронизации вызовов задачи (или при помощи прерывания или при помощи операционной системы реального времени, определяющей задачу примитивного) так, чтобы типовой кодекс выполнился к завершению, прежде чем другой вызов задачи произойдет. Синхронизация включает время, чтобы читать и записать данные к и от внешнего оборудования.
Следующая фигура иллюстрирует синхронизацию прерывания.
Синхронизация задачи
Демонстрационный интервал должен быть достаточно длинным, чтобы позволить выполнение типового кодекса между вызовами задачи.
На рисунке выше, время между двумя смежными вертикальными стрелками является демонстрационным интервалом. Пустые поля в верхней схеме показывают пример программы, которая может завершить один шаг в интервале и все еще позволить время для фоновой задачи. Серое поле в более низкой схеме указывает на то, что происходит, если демонстрационный интервал слишком короток. Другой вызов задачи происходит, прежде чем задача завершена. Такая синхронизация приводит к ошибке выполнения.
Если программа в реальном времени спроектирована, чтобы запуститься навсегда (то есть, итоговое время 0 или бесконечно так, чтобы while
цикл никогда не выходит), затем код завершения работы не выполняется.
Для получения дополнительной информации о том, как работает механизм синхронизации, смотрите Расчет Абсолютного и Прошедшего времени.
Режим 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
интегрирует производные непрерывных состояний, чтобы сгенерировать состояния в течение времени , где h является размером шага. Время затем продвигается к и повторения процесса.
Во время 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 для Функций Точки входа Модели.