tlcdebug
Objective: Вводит отладчик TLC. Вы изучите, как установить точки останова и ознакомить себя с командами отладчика TLC.
Folder: (открытый)
matlabroot/toolbox/rtw/rtwdemos/tlctutorial/tlcdebug
Можно заставить отладчик TLC быть вызванным каждый раз, когда процесс сборки вызывается. В этом примере вы используете его, чтобы обнаружить ошибку в файле .tlc
для модели под названием simple_log
. Ошибка заставляет сгенерированный код вывод от автономной версии модели отличаться от ее симуляции вывод. Пример проводит вас по следующим шагам:
Начало работы Запустите модель и осмотрите вывод
Generate and Run Code from the Model — Сравните скомпилированные результаты с исходным выводом
Start the Debugger and Use Its Commands — Вещи можно сделать с отладчиком
Debug timesN.tlc
— Узнайте то, что пошло не так, как надо
Fix the Bug and Verify — Простые способы исправить ошибки и проверить фиксируют
Скопируйте файлы от tlctutorial/tlcdebug
до вашей текущей рабочей директории.
В Командном окне MATLAB® создайте файл MEX для S-функции:
mex timesN.c
Это старается не брать версию, поставленную с вашим программным обеспечением Simulink®.
Ошибка может произойти, если вы ранее не запустили mex -setup
.
Откройте модель simple_log
. Модель выглядит так.
В панели Data Import/Export диалогового окна Configuration Parameters проверяйте Time и Output. Это заставляет образцовые переменные регистрироваться к рабочему пространству MATLAB.
Запустите модель путем выбора Run из меню Simulation. Переменные tout
и yout
появляются в вашем рабочем пространстве MATLAB.
Дважды кликните yout
в панели Workspace Окна Команды MATLAB. Редактор переменных отображается 6x1 массив вывод от simple_log
. Отображение выглядит так:
Столбец 1 содержит дискретный импульсный вывод для шести временных шагов (3 с и 0s), собранный в порте out1
.
Затем, вы генерируете автономную версию simple_log
. Вы выполняете его и сравниваете его результаты с выводом от Simulink, отображенного выше.
В целях этого осуществления, файл TLC, если, timesN.tlc
, содержит ошибку. Эта версия должна быть в той же папке как модель, которая использует его.
Нажмите Ctrl+B.
Генератор кода производит, компилирует и соединяет исходный код C. Окно Команды MATLAB показывает прогресс сборки, которая заканчивается этими сообщениями:
### Created executable: simple_log.exe ### Successful completion of build procedure for model: simple_log
Запустите автономную модель, только созданную путем ввода
!simple_log
Это приводит к сообщениям
** starting the model ** ** created simple_log.mat **
Осмотрите результаты путем размещения переменных в рабочую область. В панели Current Folder дважды кликните simple_log.mat
, затем дважды кликните rt_yout
(автономная версия переменной yout
) в панели Workspace.
Сравните rt_yout
с yout
. Вы замечаете различия? Можно ли предположить то, что заставило значения в rt_yout
изменяться?
Взгляд на сгенерированный код C, что TLC, помещенный в вашу папку сборки (simple_log_grt_rtw
), помогает идентифицировать проблему.
Отредактируйте 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;
Вы используете отладчик TLC, чтобы контролировать процесс генерации кода. Когда это не вызывается по умолчанию, необходимо запросить отладчик явным образом.
Настройте среду отладки TLC и начните создавать приложение:
Выберите Configuration Parameters> панель Code Generation и выберите опции Retain .rtw file и Start TLC debugger when generating code. Нажмите OK.
Создайте модель.
Окно Команды MATLAB описывает процесс создания. Сборка останавливает в файле timesN.tlc
и отображениях командную строку:
TLC-DEBUG>
Введите 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
Если вы попробовали команды отладчика TLC, выполняете остающийся код, чтобы закончить процесс сборки, то создайте simple_log
снова. Сборка останавливает в файле timesN.tlc
и отображениях командную строку:
TLC-DEBUG>
timesN.tlc
Теперь озирайтесь, чтобы узнать что не так с кодом:
Установите точку останова на строке 20 из timesN.tlc
.
TLC-DEBUG> break timesN.tlc:20
Дайте отладчику 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
Используйте команду whos
, чтобы видеть переменные в текущем осциллографе.
TLC-DEBUG> whos Variables within: <BLOCK_LOCAL> gain Real rollVars Vector block Resolved system Resolved
Осмотрите переменные с помощью команды печати (имена являются чувствительными к регистру).
TLC-DEBUG> print gain 3.0 TLC-DEBUG> print rollVars [U, Y]
Выполните один шаг.
TLC-DEBUG> step 00021: %<LibBlockOutputSignal(0, "", lcv, idx)> = \
Поскольку это - встроенная функция, усовершенствование через команду next
.
TLC-DEBUG> next . 00022: %<LibBlockInputSignal(0, "", lcv, idx)> * 1;
Это - источник оператора C, ответственного за ошибочный постоянный вывод, simple_log_B.first_output = simple_log_B.DiscretePulseGenerator * 1;
.
Откажитесь от сборки путем выхода из отладчика 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
Чтобы зафиксировать ошибку кодирования, отредактируйте timesN.tlc
. Строка
%<LibBlockInputSignal(0, "", lcv, idx)> * 1;
%<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>;
Сохраните timesN.tlc
.
Создайте автономную модель снова. Завершите сборку путем ввода continue
в каждой подсказке TLC-DEBUG>
.
Выполните автономную модель путем ввода
!simple_log
simple_log.mat
создается содержащий ее вывод.Загрузите simple_log.mat
и сравните переменную rt_yout
рабочей области с yout
, как вы сделали прежде. Значения в первом столбце должны теперь соответствовать.