tlcdebug
Обзор руководстваObjective: Представляет отладчик TLC. Вы узнаете, как задать точки останова и ознакомиться с командами отладчика TLC.
<reservedrangesplaceholder1> <reservedrangesplaceholder0>
(открыто)/ toolbox/rtw/rtwdemos/tlctutorial/tlcdebug
Можно вызвать отладчик TLC при каждом вызове процесса сборки. В этом руководстве вы используете его, чтобы обнаружить ошибку в .tlc
файл для модели под названием simple_log
. Ошибка заставляет сгенерированный выход кода из автономной версии модели отличаться от его выхода симуляции. Учебное руководство поможет вам выполнить следующие шаги:
Getting Started - Запустите модель и осмотрите выход
Generate and Run Code from the Model - Сравнение скомпилированных результатов с исходным выходом
Start the Debugger and Use Its Commands - Вещи, которые вы можете сделать с отладчиком
<reservedrangesplaceholder1> <reservedrangesplaceholder0>
- Узнайте, что пошло не так
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.
Запустите модель. На вкладке Simulation нажмите Run. Переменные tout
и yout
появится в рабочем пространстве MATLAB.
Дважды кликните yout
на панели Workspace Командного окна MATLAB. Редактор переменных отображает выходы массива 6x1 из simple_log
. Выглядит отображение следующим образом:
Столбец 1 содержит дискретный импульсный выход для шести временных шагов (3с и 0с), собранных в порту 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
Просмотрите переменные с помощью команды print (имена учитываются в регистре).
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
Как и раньше. Теперь значения в первом столбце должны совпадать.