You might need to detect and report error conditions in your TLC code. Error detection
and reporting are used most often in library functions. While rare, it is also possible to
encounter error conditions in block target file code if the S-function
mdlCheckParameters
function does not detect an unforeseen
condition.
To report an error condition detected in your TLC code, use the
LibBlockReportError
or LibBlockReportFatalError
utility functions. Here is an example of using LibBlockReportError
in
the paramlib.tlc
function LibBlockParameter
to
report the condition of an improper use of that function:
%if TYPE(param.Value) == "Matrix" %% exit if the parameter is a true matrix, %% i.e., has more than one row or columns. %if nRows > 1 %assign errTxt = "Must access parameter %<param.Name> using "... "LibBlockMatrixParameter." %<LibBlockReportError([], errTxt)> %endif %endif
Browse through the files in the folder
(open) for more examples
of the use of matlabroot
/rtw/c/tlcLibBlockReportError
.
To generate errors from TLC files, you can use the %exit
directive.
Alternatively, you can use one of the library functions described below that calls
%exit
for you. The two types of errors are
Usage errors | These can be caused by incorrect models. |
Fatal (internal) TLC coding errors | These cannot be caused by incorrect models. |
Usage errors are errors resulting from incorrect models or attributes defined on a model. For example, suppose you have an S-Function block and an inline TLC file for a specific D/A device. If a model can contain only one copy of this S-function, then an error needs to be generated for a model that contains two copies of this S-Function block.
Using Library Functions. To generate usage errors related to a specific block, use the library function
LibBlockReportError(block,"error string")
The block
argument is the block record if it isn't scoped. If the
block is currently scoped, then you can specify block
as [ ].
To generate general usage errors that are not related to a specific block, use
LibReportError("error string")
These library functions prefix the string Simulink Coder Error:
to the message you provide when reporting the error.
For a usage example of these functions, refer to gensfun.tlc
for
block errors and commonsetup.tlc
for common errors. There are other
files that use these functions in the TLC source folders within
(open.matlabroot
/rtw/c/tlc
Suppose you have an S-function that has a local function that can accept only numerical numbers. You might want to add an assert requiring that the inputs be only numerical numbers. These asserts can indicate fatal coding errors for which the user does not have a way of building a model or specifying attributes that can cause the error to occur.
Using Library Functions. The two available library functions are
LibBlockReportFatalError(block,"fatal coding error message")
where
is the offending block
record (or block
[]
if the block is already scoped), and
LibReportFatalError("fatal coding error message")
for error messages that are not block specific. For example, to add assert code you could use
%if TYPE(argument) != "Number" %<LibBlockReportFatalError(block,"unexpected argument type")> %endif
These library functions prefix the string Simulink Coder Fatal:
to the message you provide and display the call stack when reporting the error.
For a usage example of these functions, refer to gensfun.tlc
for
block errors and commonsetup.tlc
for common errors. There are other
files that use these functions in the folder
(open).matlabroot
/rtw/c/tlc
Using %exit. You can call %exit
to generate fatal error messages. However,
MathWorks suggests that you use one of the library functions described above.
When generating fatal error messages directly with %exit
, it is
good practice to give a stack trace with the error message. This lets you see the call
chain of functions that caused the error. To generate a stack trace, generate the
message using the format:
%setcommandswitch "-v1" %exit Simulink Coder Fatal: error string
If you want to display a formatted, multiple-line error message, create a local variable that contains the message text. For example:
%openfile message My message text with newlines %closefile message
After formatting your error message, use one of the error reporting library functions
described above, such as LibReportError
, to report your error when it
occurs. For example:
%<LibReportError(message)>
The error reporting library functions provide an error message prefix, such as
Simulink Coder Error:
.
It is strongly suggested that you test your error messages before releasing your new
TLC code. To test your error messages, copy the relevant code into a
test.tlc
file and run
tlc test.tlc
at the MATLAB® prompt.
This section lists and describes error messages generated by the Target Language Compiler. Use this reference to
Confirm that an error has been reported
Determine possible causes for an error
Determine possible ways to fix an error
In %closefile
or %selectfile
or
%flushfile
, the argument must be a valid file variable opened with
%openfile
.
Macros are not supported. You must rewrite macros as functions or inline them in your code.
text
Code containing the %error
directive generates this message. It
normally indicates some condition that the code was unable to handle and displays the text
following the %error
directive.
text
Code containing the %exit
directive causes this message. It typically
indicates some condition that the code was unable to handle and displays the text following
the %exit
directive. Note that this directive causes the Target Language
Compiler to terminate regardless of the -mnumber
command-line
option.
The user attempted to use the %filescope
directive more than once in
a file.
text
The %trace
directive produces this error message and displays the
text following the %trace
directive. Trace directives are reported only
when the -v
option (verbose mode) appears on the command line. Note that
%trace
directives are not considered errors and do not cause the Target
Language Compiler to stop processing.
text
The %warning
directive produces this error message and displays the
text following the %warning
directive. Note that
%warning
directives are not considered errors and do not cause the
Target Language Compiler to stop processing.
A block template file was found, but it did not contain an
%implements
directive. An %implements
directive is
required so that the expected language and type are implemented by this block template file.
See Object-Oriented Facility for Generating Target Code for more information.
The user has written a %switch
statement with multiple
%default
cases, as in the following example:
%switch expr %case 1 code... %break %default more code... %break %default %% error even more code... %break %endswitch
To use the GENERATE
or GENERATE_TYPE
built-in
functions, the Target Language Compiler requires that you first specify the language being
generated. This causes the block-level target file to implement the same language and type
as specified in the %language
directive.
The built-in GENERATE_FORMATTED_VALUE
can process only vectors that
have homogeneous elements (that is, vectors in which all the
elements have the same type).
identifier
— must use array index to refer to one of multiple scopesIn a repeated scope identifier from a database file, you must specify an index to disambiguate the reference. For example
Database file: block { Name "Abc2" Parameter { Name "foo" Value 2 } } block { Name "Abc3" Parameter { Name "foo" Value 3 } } TLC file: %<GETFIELD(block, "Name")>
In the preceding example, the reference to block
is ambiguous because
multiple repeated scopes named block
appear in the database file. Use an
index to disambiguate the references, as in:
%<GETFIELD(block[0], "Name")>
The user has written an %if
statement with multiple
%else
blocks, as in the following example:
%if expr code... %else more code... %else %% error even mode code... %endif
identifier
must be a stringThe following built-in functions expect a string and report this error if the argument passed is not a string.
CAST | GENERATE_FILENAME |
EXISTS | GENERATE_FUNCTION_EXISTS |
FEVAL | GENERATE_TYPE |
FILE_EXISTS | GET_COMMAND _SWITCH |
FORMAT | IDNUM |
GENERATE | SYSNAME |
directive
must be recordsArguments to %mergerecord
and %copyrecord
must be
records. Also, the first argument to the following built-in functions must be a record:
ISALIAS
REMOVEFIELD
FIELDNAMES
ISFIELD
GETFIELD
SETFIELD
An attempt was made to invoke the Target Language Compiler from MATLAB, but some of the arguments that were passed were not strings.
An expression in an %assert
statement evaluated to false.
identifier
is only
allowed when using the + operator to add membersScope assignment must be scope = scope + variable
.
A function cannot be defined twice. Make sure that you don't have the same function defined in separate TLC files.
The Target Language Compiler does not allow division by zero.
type
The Target Language Compiler cannot cast this expression from its current type to the specified type. For example, the Target Language Compiler cannot cast a string to a number, as in
%assign x = "1234" %assign y = CAST("Number", x );
dirname
) in O: filename
The -O
option did not specify a valid folder.
builtin
was expecting expression of type
type
, got one of type type
A built-in was passed an expression of incorrect type.
User is not allowed to undefine a TLC built-in or variable. For example
%undef FORMAT %% error
your_string
to a
numberCannot convert the string to a number.
identifier
from the RTW
fileYou have overwritten the value that appeared in the .rtw
file.
filename
The Target Language Compiler could not open the file specified on the command line.
error
There was an error while writing to the current output stream; error
contains the system specific error message.
This error message is the last error to be reported. It occurs when either
The number of error messages exceeds the error message threshold (5 by default).
Processing completes and errors have occurred.
It is illegal to nest expansion directives. For example,
%<foo(%<expr>)>
Instead, do the following:
%assign tmp = %<expr> %<foo(tmp)>
An expansion directive cannot span multiple lines. To work around this restriction, use the \ line continuation character. The following is incorrect:
%<CompiledModel.System[Sysidx].Block[BlkIdx].Name + "Hello">
Instead, use:
%<CompiledModel.System[Sysidx].Block[BlkIdx].Name + \ "Hello">
function-name
built-in function were ignored (Warning)The following built-in functions report this warning when too many arguments are passed to them:
CAST | NUMTLCFILES |
EXISTS | OUTPUT_LINES |
FILE_EXISTS | SIZE |
FORMAT | STRING |
GENERATE_FILENAME | STRINGOF |
GENERATE_FUNCTION_EXISTS | SYSNAME |
IDNUM | TLCFILES |
ISFINITE | TYPE |
ISINF | WHITE_SPACE |
ISNAN | WILL_ROLL |
dirname
, name =filename
)The specified filename
was too long. The default limits are
256 characters for filename
and 1024 characters for
dirname
, but the limits can be larger, depending on the
platform.
format
is not a legal format valueThe specified format was not legal for the %realformat
directive.
Valid format strings are "EXPONENTIAL"
and
"CONCISE"
.
function_name
expects number
argumentsWhen calling a function, too many or too few arguments were passed to it.
Functions that are not declared as void
or Output
must return a value. If a return value is not desired, declare the function as
void
, otherwise make it return a value.
Attempt to use a TLC function as a variable.
identifier
multiply defined. Second and
succeeding definitions ignored.The user is attempting to add the same field to a record more than once, as in the following code.
%createrecord err { foo 1; rec { val 2 } } %addtorecord err foo 2 %% error
identifier
used on a %foreach statement was already in scope (Warning)The argument to a %foreach
statement cannot be defined prior to
entering the %foreach
.
It is illegal to use evals in .rtw
files. There are also some places
where evals are not allowed in directives. For example:
%function %<foo>(a, b, c) void %% error %endfunction
An index used in a [ ] expression must be a nonnegative integer.
An index used in a [ ] expression must be an integer number.
An invalid handle was passed to the Target Language Compiler server mode.
string1
and
string2
must matchIn a range of signals, for example, u1:u10
, the identifier in the
first argument did not match the identifier in the second.
bound
) must be less than the upper bound (bound
)In a range of signals, for example, u1:u10
, the lower bound was
higher than the upper bound.
operator
Unary operators –
and +
require numeric types.
Unary operator –
requires an integral type. Unary operator
!
requires a numeric type.
type
An invalid type was passed to a built-in function.
A function value cannot be returned from a function call.
identifier
already exists
within this scope-identifier
; use %assign to change the
valueYou cannot use the block addition operator + to add a value that is already a member of
the indicated block. Use %assign
to change the value of an existing
value. This example produces this error:
%assign x = BLK { a 1; b 2 } %assign a = 3 %assign x = x + a
Use this instead:
%assign x.a = 3
Statements that appear inside a %switch
statement but precede
%case
statements are ignored, as in the following code:
%switch expr %assign x = 2 %% this statement will be ignored %case 1 code %break %endswitch
Only double and character arrays can be converted from MATLAB to the Target Language Compiler. This error can occur if the MATLAB function does not return a value (see %matlab
). For
example,
%assign a = FEVAL("int8",3) %matlab disp(a)
An attempt was made to receive multiple outputs from the MATLAB version of the Target Language Compiler.
The right-hand side of a string assignment using the [ ] operator must be a string of length 1. You can replace only a single character using this notation.
A cell containing nonstring data was passed as the third argument to
Query
or ExecString
in server mode.
In the [ ] notation to replace a row of a matrix, the row must be a vector of the same length as the existing rows.
identifier
opened with %openfile was not closedOutput files opened with %openfile
must be closed with
%closefile
. The
is the name of the variable
specified in the identifier
%openfile
directive.
Note
This might also occur a syntax error is present in a code section between an
openfile
and closefile
, or if you try to assign
the output of a function of type void
or Output
to a
variable.
You cannot repeat a range, identifier range, or repeat value. This prevents things like
[1@2@3]
.
'-switch
'
%setcommandswitch
does not recognize the specified switch, or cannot
modify it (e.g., -r
cannot be modified).
string
is not a recognized user defined property of this handleThe query performed on a TLC server mode handle is looking for an undefined property.
The indicated line contains a syntax error, for more information on syntax, see Target Language Compiler Directives.
The %break
directive can be used only in a
%foreach
, %for
, %roll
, or
%switch
statement.
A %case
or %default
directive can appear only
within a %switch
statement.
The %continue
directive can be used only in a
%foreach
, %for
, or %roll
statement.
The argument of a %foreach
must be a numeric type. For
example:
%foreach Index = [1 2 3 4] ... %endforeach
%foreach
cannot accept a vector as input.
The argument of an %if
statement must be a numeric type. For example,
%if [ 1 2 3 ] ... %endif
%if
cannot accept a vector as input.
You can use the %implements
directive to specify a string for the
language being implemented, or to indicate that it implements multiple languages by using a
vector of strings. You cannot specify any other argument type
to the %implements
directive.
type
where type
was expectedThe type specified in the %implements
directive must exactly match
the type specified in the block or on the GENERATE_TYPE
directive. If you
want to specify that the block accept multiple input types, use the %implements
*
directive, as in
%implements * "C" %% I accept any type and generate C code
language
)The language or languages specified in the %implements
directive must
exactly match the %language
directive.
A %return
statement can be only in the body of a function.
The == and != operator arguments must be the same type. You can use the
CAST()
built-in function to change them into the same type.
When you open an output file, the name specified for the file must be a valid string.
The argument to %with
must be a valid scope identifier. For example,
%assign x = 1 %with x ... %endwith
In this code, the %with
statement argument is a number and produces
this error message.
When you use the [ ] operator to index, the expression on the left of the brackets must be a vector, matrix, string, numeric constant, or a repeated scope identifier. When you use array indexing on a scalar, the constant is automatically scalar expanded and the value of the scalar is returned. For example,
%openfile x %assign y = x[0]
This example causes this error because x
is a file and is not valid
for indexing.
The argument to %addincludepath
must be a string.
The argument to the input file control directive must be a valid string with the filename given in double quotation marks.
These Target Language Compiler begin
directives must appear in the
same file as their corresponding end
directives:
%function
, %switch
, %foreach
,
%roll
, and %for
. Place the construct entirely within
one Target Language Compiler source file.
begin
directive on this line has no matching end
directiveFor block-scoped directives, this error is produced if a matching end
directive is missing. This error can occur for the following block-scoped Target Language
Compiler directives.
Begin Directive | End Directive | Description |
---|---|---|
%if | %endif | Conditional inclusion |
%for | %endfor | Looping |
%foreach | %endforeach | Looping |
%roll | %endroll | Loop rolling |
%with | %endwith | Scoping directive |
%switch | %endswitch | Switch directive |
%function | %endfunction | Function declaration directive |
{ | } | Record creation |
The error is reported on the line that opens the scope and does not have matching
end
scope.
Note
Nested scopes must be closed before their parent scopes. Failure to include an
end
for a nested scope often causes this error, as in
%if Block.Name == "Sin 3" %foreach idx = Block.Width %endif %% Error reported here that the %foreach was not terminated
function_name
(...) construct is illegal in standalone tlcYou cannot call MATLAB from stand-alone TLC.
Return values from MATLAB can have at most two dimensions.
Vectors passed to MATLAB can be numbers or strings. See FEVAL Function.
FEVAL
requires a function to call. This error appears only inside
MATLAB.
When you use %roll
, the final argument (prior to extra user-specified
arguments) must be a valid block scope. See %roll for a
description of this command.
The ? :
operator must have a Boolean expression as its first
operand.
When you call GENERATE
or GENERATE_TYPE
, the
first argument must be a valid scope. See the GENERATE and GENERATE_TYPE Functions for more information and examples.
name
requires at least number
argumentsUser is passing too few arguments to a function, as in the following code:
%function foo(a, b, c) %return a + b + c %endfunction %<foo(1, 2)> %% error
When you call the GENERATE
built-in function, the first two
arguments must be the block and the name of the function to call.
When you call the GENERATE_TYPE
built-in function, the first three
arguments must be the block, the name of the function to call, and the type.
These functions expect a Real
or complex value as the input
argument.
You cannot change the language using the %language
directive within a
block template file.
old-language
to new-language
(Warning)The language being implemented should not be changed in midstream because
GENERATE
function calls that appear prior to the
%language
directive can cause generate
functions
to load for the prior language. Only one language directive should appear in a given
file.
When you use the .
operator, the left-hand side of the
.
operator must be a valid in-scope identifier. For example:
%assign x = 1 %assign y = x.y
In this code, the reference to x.y
produces this error message
because x
is not defined as a scope.
Illegal left-hand side of assignment.
specified-columns
) did not match the actual number of columns
in the rows (actual-columns
)When you specify a Target Language Compiler matrix, the number of columns specified must match the actual number of columns in the matrix. For example,
%assign mat = Matrix(2,1) [[1,2];[2,3]]
In this case, the number of columns in the declaration of the matrix (1) did not match the number of columns seen in the matrix (2). Either change the number of columns in the matrix, or change the matrix declaration.
specified-rows
) did not match the actual number of rows seen
in the matrix (actual-rows
)When you specify a Target Language Compiler matrix, the number of rows must match the actual number of rows in the matrix. For example,
%assign mat = Matrix(1,2) [[1,2];[2,3]]
In this case, the number of rows in the declaration of the matrix (1) did not match the number of rows seen in the matrix (2). Either change the number of rows in the matrix or change the matrix declaration.
operator_name
operator only works on Boolean argumentsThe &&
and ||
operators work only on
Boolean values.
operator_name
operator only works on integral argumentsThe &
, ^
, |
,
<<
, >>
and %
operators work on numbers only.
operator_name
operator only works on numeric argumentsThe arguments to the following operators both must be either numeric or real:
<
, <=
, >
,
>=
, -
, *
,
/
. This error can also occur when you use +
as a unary
operator. In addition, the FORMAT
built-in function expects either a
numeric or real argument.
When you use %roll
, the RollHeader()
function
specified in Roller.tlc
must return a string value. See %roll for a
complete discussion of the %roll
construct.
When you use %roll
, the roll
vector cannot be
empty and must contain numbers or ranges of numbers. See %roll for a
complete discussion of the %roll
construct.
In a range, for example, 1:10
, the lower bound was higher than the
upper bound.
index
) was out of the range 0 - number-of-elements - 1
This error occurs when you index into a nonscalar beyond the end of the variable. For example:
%assign x = [1 2 3] %assign y = x[3]
This example would cause this error. Remember, in the Target Language Compiler, array indices start at 0 and go to the number of elements minus 1.
The STRINGOF
function expects a vector of numbers. The function
treats each number as the ASCII value of a valid character.
xxx
/yyy
The SYSNAME
function takes a single string of the form
xxx
/yyy
as it appears in the .rtw
file and returns a vector of two strings, xxx
and yyy
.
If the input argument does not match this format, SYSNAME
returns this
error.
When you use %roll
, the roll threshold specified must be a single
number. See %roll for a complete discussion of the %roll
construct.
feature
is being deprecated and will not be supported in future versions of TLC. See the TLC manual for alternatives.The %define
and %generate
directives are not
recommended, as they are being replaced.
The WILL_ROLL
function requires both arguments cited in the
message.
The global context table has filled up while the TLC server mode is in use.
The scope specified to GENERATE
must include a
Type
parameter that indicates which template file should be used to
generate code for the specified scope. For example:
%assign scope = block { Name "foo" } %<GENERATE( scope, "Output" )>
This example produces the error message because the scope does not include the parameter
Type
. See the GENERATE and GENERATE_TYPE Functions for more information
and examples.
The user is trying to modify a field of a record in a %with
block
without qualifying the left-hand side, as in this example:
%createrecord foo { field 1 } %with foo %assign field = 2 %% error %endwith
Instead, use
%createrecord foo { field 1 } %with foo %assign foo.field = 2 %endwith
number
symbols. You may have created a cyclic record. If this not the case then please report this leak to The MathWorks.There has been a memory leak while running TLC. The most common cause of this is having cyclic records.
identifier
within the scope-identifier
scopeThe given identifier was not found in the scope specified. For example,
%assign scope = ascope { x 5 } %assign y = scope.y
In this code, the reference to scope.y
produces this error
message.
filename
The file included in an %include
directive was not found on the path.
Either move the file to a location on the current path, or use the -I
command-line option or the %addincludepath
directive to specify the
folder that contains the file.
filename
from GENERATE or GENERATE_TYPEYou specified GENERATE
but the given filename was not found on the
Target Language Compiler path. You can
Add the file to a folder on the path.
Use the %generatefile
directive to specify an alternative
filename for this block type that is on the path.
Add the folder in which this file appears to the search path using the
-I
command-line option or the %addincludepath
directive.
filename
The specified output file could not be opened. Either an invalid filename was specified or the file was read only.
identifier_name
The identifier specified in this expression was undefined.
type
in CAST
expressionWhen you call the CAST
built-in function, the type must be a valid
type from the Target Language Value Types table.
switch
You queried the current state of a switch, but the switch specified was not recognized.
directive-name
seenAn illegal %
directive was encountered. The valid directives are
shown below.
%addincludepath | %addtorecord |
%assert | %assign |
%break= | %case |
%closefile | %continue |
%copyrecord | %createrecord |
%default | %define |
%else | %elseif |
%endbody | %endfor |
%endforeach | %endfunction |
%endif | %endroll |
%endswitch | %endwith |
%error | %exit |
%filescope | %for |
%foreach | %function |
%generate | %generatefile |
%if | %implements |
%include | %language |
%matlab | %mergerecord |
%openfile | %realformat |
%return | %roll |
%selectfile | %setcommandswitch |
%switch | %trace |
%undef | %warning |
%with |
output-type
for functionThe function type modifier was not Output
or void
.
For functions that do not produce output, the default without a type modifier indicates that
the function should not produce output.
A multiline comment (i.e., /% %/) does not have a terminator, as in the following code:
/% my comment %assign x = 2 %assign y = x * 7
A string must be closed prior to the end of an expansion directive or the end of a line.
A command-line problem has occurred. The error message contains a list of the available options.
feature
incurs a performance hit, please see TLC manual for possible
workarounds.The %undef
and expansion (i.e., %<expr>
)
features can degrade performance.
type
type cannot be comparedValues of the specified
cannot be
compared.type
specified_type
type cannot be expandedThe specified type cannot be used on an expansion directive. Files and scopes cannot be expanded. This error can also occur when you expand a function without any arguments. If you use
%<Function>
call it with the required arguments.
Values of the types listed in the message cannot converted to MATLAB variables.
You can specify the append
option for a buffer stream only if the
variable currently exists as a string. Do not use the append
option if
the variable does not exist or is not a string. This example produces this error.
%assign x = 1 %openfile x , "a" %closefile x
The functions in the TLC function library can generate many error messages that are not documented. These messages are sufficiently self-descriptive so that they do not need additional explanation. However, if you encounter an error message that does not provide enough description to resolve your problem, contact our technical support staff.