Отладьте свой код TLC

tlcdebug Учебный обзор

Objective: Вводит отладчик TLC. Вы изучите, как установить точки останова и ознакомить себя с командами отладчика TLC.

Folder: matlabroot/toolbox/rtw/rtwdemos/tlctutorial/tlcdebug открытый

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

  1. Начало работы Запустите модель и смотрите выход

  2. Generate and Run Code from the Model — Сравните скомпилированные результаты с исходным выходом

  3. Start the Debugger and Use Its Commands — Вещи можно сделать с отладчиком

  4. Debug timesN.tlc — Узнайте то, что пошло не так, как надо

  5. Fix the Bug and Verify — Простые способы исправить ошибки и проверить фиксируют

Начало работы

  1. Скопируйте файлы с tlctutorial/tlcdebug к вашей текущей рабочей директории.

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

    mex timesN.c

    Это старается не брать версию, поставленную с вашим программным обеспечением Simulink®.

    Примечание

    Ошибка может произойти, если вы ранее не запустили mex -setup.

  3. Откройте модель simple_log. Модель выглядит так.

  4. В панели Data Import/Export диалогового окна Configuration Parameters проверяйте Time и Output. Это заставляет переменные модели регистрироваться к рабочему пространству MATLAB.

  5. Запустите модель. На вкладке Simulation нажмите Run. Переменные tout и yout появитесь в своем рабочем пространстве MATLAB.

  6. Дважды кликните yout в панели Workspace командного окна MATLAB. Редактор переменных отображается 6x1 массив выход от simple_log. Отображение выглядит так:

    Столбец 1 содержит дискретный импульсный выход для шести временных шагов (3 с и 0s), собранный в порте out1.

Затем вы генерируете автономную версию simple_log. Вы выполняете его и сравниваете его результаты с выходом от Simulink, отображенного выше.

Примечание

В целях этого осуществления, файл TLC, если, timesN.tlc, содержит ошибку. Эта версия должна быть в той же папке как модель, которая использует его.

Сгенерируйте и запущенный код из модели

  1. Нажмите Ctrl+B.

    Генератор кода производит, компилирует и соединяет исходный код C. Командное окно MATLAB показывает прогресс сборки, которая заканчивается этими сообщениями:

    ### Created executable: simple_log.exe  
    ### Successful completion of build procedure 
        for model: simple_log
  2. Запустите автономную модель, только созданную путем ввода

    !simple_log

    Это приводит к сообщениям

    ** starting the model **
    ** created simple_log.mat **
  3. Смотрите результаты путем размещения переменных в рабочую область. В панели Current Folder дважды кликните simple_log.mat, затем дважды кликните rt_yout (автономная версия переменной yout) в панели Workspace.

    Сравните rt_yout с yout. Вы замечаете различия? Можете вы предполагать то, что вызвало значения в rt_yout измениться?

    Взгляд на сгенерированный код C, что TLC, помещенный в вашу папку сборки (simple_log_grt_rtw) помогает идентифицировать проблему.

  4. Отредактируйте simple_log.c и посмотрите на его MdlOutputs функция, которая должна появиться как показано ниже:

    /* Model output function */
    static void simple_log_output(void)
    {
      /* DiscretePulseGenerator: '<Root>/Discrete Pulse Generator' */
      simple_log_B.DiscretePulseGenerator = (simple_log_DW.clockTickCounter < 1.0) &&
        (simple_log_DW.clockTickCounter >= 0) ? 1.0 : 0.0;
      if (simple_log_DW.clockTickCounter >= 2.0 - 1.0) {
        simple_log_DW.clockTickCounter = 0;
      } else {
        simple_log_DW.clockTickCounter++;
      }
    
      /* End of DiscretePulseGenerator: '<Root>/Discrete Pulse Generator' */
    
      /* S-Function (timesN): '<Root>/Gain1st' incorporates:
       *  Outport: '<Root>/Out1'
       */
      /* S-Function Block: <Root>/Gain1st */
      /* Multiply input by 3.0 */
      simple_log_Y.Out1 = simple_log_B.DiscretePulseGenerator * 1;
    }
    

Отметьте линию около конца:

simple_log_B.first_output = simple_log_B.DiscretePulseGenerator * 1;
Как неправильный продукт становился присвоенным к выходу, когда это, как предполагалось, получило переменную, которая чередуется между 3,0 и 0.0? Используйте отладчик, чтобы узнать.

Запустите отладчик и используйте его команды

Вы используете отладчик TLC, чтобы контролировать процесс генерации кода. Когда это не вызывается по умолчанию, необходимо запросить отладчик явным образом.

  1. Настройте среду отладки TLC и начните создавать приложение:

    1. Выберите Configuration Parameters> панель Code Generation и выберите опции Retain .rtw file и Start TLC debugger when generating code. Нажмите OK.

    2. Создайте модель.

      Командное окно MATLAB описывает процесс создания. Сборка останавливается в timesN.tlc файл и отображения командная строка:

      TLC-DEBUG>
  2. Ввод help перечислять команды отладчика TLC. Вот некоторые вещи, которые можно сделать в отладчике.

    • Просмотрите и запросите различные сущности в осциллографе TLC.

      TLC-DEBUG> whos CompiledModel
      TLC-DEBUG> print CompiledModel.NumSystems
      TLC-DEBUG> print TYPE(CompiledModel.NumSystems)
    • Исследуйте операторы в своем текущем контексте.

      TLC-DEBUG> list
      TLC-DEBUG> list 10,40
    • Переместитесь в следующую строку кода.

      TLC-DEBUG> next
    • Продвиньтесь в функцию.

      TLC-DEBUG> step
    • Присвойте постоянное значение переменной, такой как входной сигнал %<u>.

      TLC-DEBUG> assign u = 5.0
    • Установите точку останова, где вы или в некоторой другой части кода.

      TLC-DEBUG> break timesN.tlc:10
    • Выполнитесь до следующей точки останова.

      TLC-DEBUG> continue
    • Ясные точки останова вы установили.

      TLC-DEBUG> clear 1
      TLC-DEBUG> clear all
  3. Если вы попробовали команды отладчика TLC, выполняете остающийся код, чтобы закончить процесс сборки, то создайте simple_log снова. Сборка останавливается в timesN.tlc файл и отображения командная строка:

    TLC-DEBUG>

Отладьте timesN.tlc

Теперь озирайтесь, чтобы узнать что не так с кодом:

  1. Установите точку останова на линии 20 из timesN.tlc.

    TLC-DEBUG> break timesN.tlc:20
  2. Дайте отладчику TLC команду переходить к вашей точке останова.

    TLC-DEBUG> continue

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

    ### Loading TLC function libraries
    ...
    ### Initial pass through model to cache user defined code
    .
    ### Caching model source code
    .
    Breakpoint 1
    00020:   %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
  3. Используйте whos команда, чтобы видеть переменные в текущем осциллографе.

    TLC-DEBUG> whos
    Variables within: <BLOCK_LOCAL>
    gain                           Real
    rollVars                       Vector
    block                          Resolved
    system                         Resolved
  4. Смотрите переменные с помощью команды печати (имена являются чувствительными к регистру).

    TLC-DEBUG> print gain
    3.0
    
    TLC-DEBUG> print rollVars
    [U, Y]
  5. Выполните один шаг.

    TLC-DEBUG> step
    00021:     %<LibBlockOutputSignal(0, "", lcv, idx)> = \
  6. Поскольку это - встроенная функция, усовершенствование через next команда.

    TLC-DEBUG> next
    .
    00022:     %<LibBlockInputSignal(0, "", lcv, idx)> * 1;

    Это - источник оператора C, ответственного за ошибочный постоянный выход, simple_log_B.first_output = simple_log_B.DiscretePulseGenerator * 1;.

  7. Откажитесь от сборки путем выхода из отладчика TLC. Ввод

    TLC-DEBUG> quit

    Сообщение об ошибке отображено, показав, что вы остановили сборку при помощи отладчика TLC quit команда. Закройте ошибочное окно.

Исправьте ошибку и проверьте

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

%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)> * 1;
  %endroll

%endfunction

%% [EOF] timesN.tlc
  1. Чтобы зафиксировать ошибку кодирования, отредактируйте timesN.tlc. Линия

    %<LibBlockInputSignal(0, "", lcv, idx)> * 1;
    умножает оцененный вход на 1. Измените линию в
    %<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>;

    Сохраните timesN.tlc.

  2. Создайте автономную модель снова. Завершите сборку путем ввода continue в каждом TLC-DEBUG> подсказка.

  3. Выполните автономную модель путем ввода

    !simple_log
    Новая версия simple_log.mat создается содержащий его выход.

  4. Загрузите simple_log.mat и сравните переменную rt_yout рабочей области с yout, когда вы сделали прежде. Значения в первом столбце должны теперь соответствовать.

Похожие темы