Встроенные S-функции с TLC

Обзор примера timesN

Objective:, Чтобы понять, как TLC работает с S-функцией.

Folder: (открытый) matlabroot/toolbox/rtw/rtwdemos/tlctutorial/timesN

В этом примере вы генерируете версии кода С для существующей S-функции timesN.

Пример включает эти шаги:

  1. Noninlined Code Generation — Через SimStructs и типичный API

  2. Why Use TLC to Inline S-Functions? — Преимущества встраивания

  3. Create an Inlined S-Function — С помощью пользовательского кода TLC

Более поздний пример предоставляет информацию и практику с “переносящимися” S-функциями.

Невстроенная генерация кода

Учебная папка tlctutorial/timesN в вашей рабочей папке содержит Simulink® S-function timesN.c.

В этом осуществлении вы генерируете невстроенный код из модели sfun_xN.

  1. Найдите файл rename_timesN.tlc в tlctutorial/timesN. Переименуйте этот файл к timesN.tlc. Это позволяет вам генерировать код.

  2. В Командном окне MATLAB® создайте файл MEX для S-функции:

    mex timesN.c

    Это старается не брать версию, поставленную с Simulink.

  3. Откройте модель sfun_xN, которая использует S-функцию timesN. Блок-схема выглядит так.

  4. Откройте диалоговое окно Configuration Parameters и выберите панель Solver.

  5. Установите Stop time на 10.0.

  6. Установите Solver Options.

    • Type к Fixed-step

    • Solver к Discrete (no continuous states)

    • Fixed-step size к 0.01

  7. Выберите панель Optimization и убедитесь, что Default parameter behavior установлен в Tunable.

  8. Выберите Code Generation> панель Comments и заметьте, что Include comments проверяется по умолчанию.

  9. Выберите панель Code Generation и проверяйте Generate code only.

    Нажмите Apply.

  10. Нажмите Ctrl+B, чтобы сгенерировать код С для модели.

  11. Откройте получившийся файл sfun_xN_grt_rtw/sfun_xN.c и просмотрите фрагмент sfun_xN_output, показанный ниже.

/* Model output function */
static void sfun_xN_output(int_T tid)
{
  /* Sin: '<Root>/Sin' */
  sfun_xN_B.Sin = sin(sfun_xN_M->Timing.t[0] * sfun_xN_P.Sin_Freq +
                      sfun_xN_P.Sin_Phase) * sfun_xN_P.Sin_Amp +
    sfun_xN_P.Sin_Bias;

  /* S-Function Block: <Root>/S-Function */
  /* Multiply input by 3.0 */
  sfun_xN_B.timesN_output = sfun_xN_B.Sin * 3.0;

  /* Outport: '<Root>/Out' */
  sfun_xN_Y.Out = sfun_xN_B.timesN_output;
  UNUSED_PARAMETER(tid);
}

Комментарии появляются в коде, потому что, в Code Generation> панель Comments диалогового окна Configuration Parameters, Include comments выбран по умолчанию.

Почему использование TLC, чтобы встроить S-функции?

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

В окружении реального времени, особенно когда много шагов решения включены, типичные вызовы API могут быть неприемлемо медленными. Генератор кода может ускорить S-функции в автономных приложениях, которые он генерирует путем встраивания написанных пользователем алгоритмов в автоматически сгенерированных функциях, вместо того, чтобы косвенно вызвать S-функции через типичный API. Эта форма оптимизации называется inlining. TLC встраивает S-функции, приводящие к быстрее, оптимизированный код.

Необходимо понять, что TLC не является заменой для записи S-функций кода С. Чтобы вызвать авторские блоки в Simulink, все еще необходимо написать S-функции в C (или как файлы MATLAB), поскольку симуляции не используют файлы TLC. Можно, однако, подготовить файлы TLC, которые встраивают заданные S-функции, чтобы сделать целевой код намного более эффективным.

Создайте встроенную S-функцию

TLC создает inlined S-function каждый раз, когда он обнаруживает файл .tlc с тем же именем как S-функция. Принятие файла .tlc имеет ожидаемую форму, это направляет конструкцию кода, который функционально копирует внешнюю S-функцию, не подвергаясь API наверху. Смотрите, как этот процесс работает путем завершения следующих шагов:

  1. Если вы поэтому уже не сделали, найдите файл rename_timesN.tlc в tlctutorial/timesN. Переименуйте этот файл к timesN.tlc, таким образом, можно использовать его, чтобы сгенерировать код. Исполняемый фрагмент файла

    %implements "timesN" "C"
    
    %% Function: Outputs ===========================================================
    %%
    %function Outputs(block, system) Output
      %assign gain =SFcnParamSettings.myGain
      /* %<Type> Block: %<Name> */
      %%
      /* Multiply input by %<gain> */
      %assign rollVars = ["U", "Y"]
      %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
        %<LibBlockOutputSignal(0, "", lcv, idx)> = \
        %<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>;
      %endroll
    
    %endfunction
  2. Создайте встроенную версию S-функции.

    1. На панели Optimization диалогового окна Configuration Parameters, набор Default parameter behavior к Inlined, и нажимают Apply.

    2. Измените метку схемы от model: sfun_xN до model: sfun_xN_ilp.

    3. Сохраните модель как sfun_x2_ilp.

    4. Нажмите Ctrl+B. Исходные файлы создаются в новой подпапке под названием sfun_xN_ilp_grt_rtw.

    5. Осмотрите код в сгенерированном файле sfun_xN_ilp.c:

      /* Model output function */
      static void sfun_xN_ilp_output(int_T tid)
      {
        /* Sin: '<Root>/Sin' */
        sfun_xN_ilp_B.Sin = sin(sfun_xN_ilp_M->Timing.t[0]);
      
        /* S-Function Block: <Root>/S-Function */
        /* Multiply input by 3.0 */
        sfun_xN_ilp_B.timesN_output = sfun_xN_ilp_B.Sin * 3.0;
      
        /* Outport: '<Root>/Out' */
        sfun_xN_ilp_Y.Out = sfun_xN_ilp_B.timesN_output;
        UNUSED_PARAMETER(tid);
      }

      Примечание

      Когда генератор кода производит код и создает исполняемые файлы, это создает или использует определенную подпапку (названный папкой сборки), чтобы содержать источник, объект и make-файлы. По умолчанию папку сборки называют model_grt_rtw.

      Заметьте, что установка Default parameter behavior к Inlined не изменила код. Это вызвано тем, что TLC встраивает S-функции.

  3. Продолжите осуществление путем создания автономной симуляции.

    1. В панели Code Generation диалогового окна Configuration Parameters очистите Generate code only и нажмите Apply.

    2. В панели Data Import/Export диалогового окна Configuration Parameters проверяйте Output.

      Эта спецификация заставляет выходные данные модели быть зарегистрированными ваше рабочее пространство MATLAB.

    3. Нажмите Ctrl+B, чтобы сгенерировать код, скомпилировать и соединить модель в исполняемый файл, названный sfun_xN_ilp.exe (или, в системах UNIX®, sfun_xN_ilp).

    4. Подтвердите, что файл timesN.tlc производит ожидаемый выведенный путем выполнения независимого исполняемого файла. Чтобы запуститься это, в Окне Команды MATLAB, вводит

      !sfun_xN_ilp

      Следующий ответ появляется:

      ** starting the model **
      ** created sfun_xN_ilp.mat **
    5. Просмотрите или постройте содержимое файла sfun_xN_ilp.mat, чтобы проверить, что автономная модель сгенерировала синус вывод в пределах от-3 к +3. В Окне Команды MATLAB ввести

      load sfun_xN_ilp.mat
      plot (rt_yout)

Совет

Для платформ UNIX запустите исполняемый файл в Командном окне с синтаксисом !./ executable_name. Если предпочтено, выполнение исполняемый файл от ОС окружают с синтаксисом ./ executable_name. Для получения дополнительной информации смотрите Выполнение Внешние Команды, Скрипты и Программы (MATLAB).

Похожие темы