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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Обратите внимание также, что, если программа в реальном времени разработана, чтобы запуститься навсегда (то есть, итоговое время 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.

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

Похожие темы