Пример в Использование отладчика TLC использовал отладчик, чтобы обнаружить проблему в одном разделе файла TLC. Поскольку экспериментальная модель может не охватывать все возможные случаи, существует метод, который отслеживает непроверенные случаи, опцию покрытие TLC.
Опция покрытия TLC обеспечивает более легкий способ определения того, что выполняются различные кодовые части (не пути) в коде. Чтобы задать отслеживание покрытия TLC, в диалоговом окне Параметров конфигурации выберите Start TLC покрытия при генерации кода.
Когда вы инициируете покрытие TLC, Target Language Compiler создает .log
файл для каждого целевого файла (*.tlc
Б/У. Эти .log
файлы помещаются в папку проекта, созданную для модели. Каждый .log
файл содержит информацию об использовании (количестве), сколько раз он сталкивается с каждой линией во время выполнения. Каждая линия начинается с количества раз, когда она встречается, за которым следует двоеточие, за которым следует код.
Вот файл журнала, который является результатом генерации кода для модели примера sfcndemo_sdotproduct
, находится в папке
(откройте). Эта модель inlines matlabroot
/ toolbox/simulink/simdemos/simfeaturessdotproduct
S-функция в TLC. TLC- файла, реализующий S-функцию, расположен в папке
(откройте). The 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
). Используя этот журнал как ссылку и создавая модели, которые выполняют неисполненные линии, можно убедиться, что ваш код более надежен.