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

timesN Обзор руководства

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

<reservedrangesplaceholder1> <reservedrangesplaceholder0> / 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-функции timesN.c.

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

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

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

    mex timesN.c

    Это позволяет избежать выбора версии, поставляемой с Simulink.

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

  4. Откройте диалоговое окно Параметры конфигурации и выберите панель 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 inlines 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 панели диалогового окна Параметров конфигурации задайте 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);
      }

      Примечание

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

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

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

    1. На панели Code Generation диалогового окна Параметры конфигурации очистите 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. Для получения дополнительной информации см. раздел «Запуск внешних команд, скриптов и программ».

Похожие темы