Пример в разделе Использование отладчика TLC использовал отладчик для обнаружения проблемы в одном разделе файла TLC. Поскольку тестовая модель может охватывать не все возможные случаи, существует метод, который отслеживает непроверенные случаи, опция покрытия TLC.
Опция покрытия TLC обеспечивает более простой способ проверки выполнения различных аналитических признаков (а не путей) в коде. Чтобы задать отслеживание покрытия TLC, в диалоговом окне Configuration Parameters выберите Start TLC coverage when generation code.
При инициировании покрытия TLC компилятор целевого языка создает .log для каждого целевого файла (*.tlcБ/У. Они .log файлы помещаются в папку проекта, созданную для модели. Каждый .log содержит информацию об использовании (количестве) в отношении того, сколько раз он встречается с каждой строкой во время выполнения. Каждая строка начинается с числа встречающихся строк, за которыми следует двоеточие, за которым следует код.
Вот файл журнала, который является результатом создания кода для примерной модели. sfcndemo_sdotproduct, находится в папке (открыто). Эта модель встраивает matlabroot/toolbox/simulink/simdemos/simfeaturessdotproduct S-функция в TLC. Файл TLC, реализующий S-функцию, находится в папке (открыто). matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c.log файл для sdotproduct.tlc является sdotproduct.log, которая помещена в папку сборки. Содержание sdotproduct.log аналогичны:
Source: E:\matlab\toolbox\simulink\simdemos\simfeatures\tlc_c\sdotproduct.tlc
0: %%
0: %% File : sdotproduct.tlc generated from sdotproduct.ttlc revision 1.6
0: %%
0: %% Abstract:
0: %% Dot product block target file.
1:
1: %implements sdotproduct "C"
1:
0: %% Function: FcnThriftedComplexMultiply
========================================
0: %% Abstract:
0: %% This function multiplies two numbers in the complex plane. If any of
0: %% the input arguments is only real, then the complex part is passed in
0: %% as "".
0: %%
1: %function FcnThriftedComplexConjMultiply(ar,ai,br,bi,cr,ci,op) void
2: %openfile buffer
0: %%
0: %% Compute Cr = Ar * Br + Ai * Bi
0: %%
2: %assign rhsStr = "%<ar> * %<br>"
2: %if !LibIsEqual(ai, "") && !LibIsEqual(bi, "")
0: %assign rhsStr = rhsStr + " + %<ai> * %<bi>"
0: %endif
2: %<cr> %<op> %<rhsStr>;
0: %%
0: %% Compute Ci = Ar * Bi - Ai * Br
0: %%
2: %if !LibIsEqual(ci, "")
0: %assign rhsStr = "0.0"
0: %if !LibIsEqual(bi, "")
0: %assign rhsStr = "%<ar> * %<bi>"
0: %endif
0: %if !LibIsEqual(ai, "")
0: %assign rhsStr = rhsStr + " - %<ai> * %<br>"
0: %endif
0: %<ci> %<op> %<rhsStr>;
0: %endif
0: %%
2: %closefile buffer
2: %return buffer
0: %endfunction %% FcnThriftedComplexMultiply
1:
1:
0: %% Function: Outputs
===========================================================
0: %% Abstract:
0: %% Y = U0' * U1, where U0' is the complex conjugate transpose of U0
0: %%
1: %function Outputs(block, system) Output
1: %assign sfcnName = ParamSettings.FunctionName
1: /* %<Type> Block (%<sfcnName>): %<LibParentMaskBlockName(block)> */
0: %%
1: %assign u0re = LibBlockInputSignal(0, "", "", "%<tRealPart>0")
1: %assign u0im = LibBlockInputSignal(0, "", "", "%<tImagPart>0")
1: %assign u1re = LibBlockInputSignal(1, "", "", "%<tRealPart>0")
1: %assign u1im = LibBlockInputSignal(1, "", "", "%<tImagPart>0")
0: %%
1: %assign yre = LibBlockOutputSignal(0, "", "", "%<tRealPart>0")
1: %assign yim = LibBlockOutputSignal(0, "", "", "%<tImagPart>0")
0: %%
0: %% Need to declare a temporary variable for u1re when the output is
0: %% being overwritten and u0im is nonzero
1: %assign outputOverWritesInput = ...
0: ((LibBlockInputSignalBufferDstPort(0) == 0) || ...
0: (LibBlockInputSignalBufferDstPort(1) == 0)) && ...
0: (LibBlockInputSignalIsComplex(0) && LibBlockInputSignalIsComplex(1))
0: %%
1: %if outputOverWritesInput
0: {
0: %assign dtName = LibBlockOutputSignalDataTypeName(0, tRealPart)
0: %<dtName> tmpVar;
0: \
0: %assign tmpVar = "tmpVar"
0: %else
1: %assign tmpVar = yre
0: %endif
0: %%
1: %<FcnThriftedComplexConjMultiply(u0re, u0im, u1re, u1im, tmpVar, yim, "=")>\
0: %%
1: %assign rollVars = ["U", "Y"]
1: %assign rollRegion = LibGetRollRegions1(RollRegions)
0: %%
1: %if LibIsEqual(rollRegion, [])
0: %if outputOverWritesInput
0: %<yre> = tmpVar;
0: %endif
0: %else
0: %% Continue with dot product for nonscalar case
1: %roll idx = rollRegion, lcv = RollThreshold, block, "Roller", rollVars
1: %assign u0re = LibBlockInputSignal(0,"",lcv,"%<tRealPart>%<idx>")
1: %assign u0im = LibBlockInputSignal(0,"",lcv,"%<tImagPart>%<idx>")
1: %assign u1re = LibBlockInputSignal(1,"",lcv,"%<tRealPart>%<idx>")
1: %assign u1im = LibBlockInputSignal(1,"",lcv,"%<tImagPart>%<idx>")
0: %%
1: %assign yre = LibBlockOutputSignal(0,"",lcv,"%<tRealPart>%<idx>")
1: %assign yim = LibBlockOutputSignal(0,"",lcv,"%<tImagPart>%<idx>")
0: %%
1: %<FcnThriftedComplexConjMultiply(u0re, u0im, u1re, u1im, yre, yim, "+=")>\
0: %endroll
0: %endif
1: %if outputOverWritesInput
0: }
0: %endif
1:
0: %endfunction
1:
0: %% [EOF] sdotproduct.tlcЭта структура позволяет легко идентифицировать непринятые ветви и разработать новые тесты, которые могут использовать неиспользуемые части целевых файлов.
Глядя на sdotproduct.log файл, вы можете видеть, что код не использовался для назначения значений по умолчанию параметрам (например, первая часть кода для функции FcnThriftedComplexConjMultiply). Используя этот журнал в качестве ссылки и создавая модели, выполняющие нереализованные строки, можно убедиться, что код более надежен.