![]() ZBasic Language Reference
85
ZBasic Microcontrollers
Declare Sub <name> ( [<parameter-list>] ) Based <addr-expr>
Declare Function <name> ( [<parameter-list>] ) As <type> Based <addr-expr>
As with based variables, the <addr-expr> giving the address of the procedure to be invoked must have
an integral type and can be either constant or non-constant (i.e., computed at run time). The based
procedure declaration may be placed inside a subroutine or function in which case the declaration is
private to that routine. At the module level, the Declare keyword may be proceeded by Public or
Private and if neither is specified, the declaration will be public by default.
When using a based procedure, you must be very careful to be certain that the declaration matches the
actual procedure that exists at the address that is specified. If the address given is not the beginning of a
procedure that is the same type and has the same number and type of parameters, the result is
unpredictable but will likely cause your program to malfunction.
BasicX Compatibility Note
Based procedures are not available in BasicX compatibility mode.
One issue that arises in conjunction with based procedures is that the compilers algorithm for estimating
the stack use of each procedure cannot determine how much stack space is used by the set of actual
procedures that might be invoked by way of a based procedure. Consequently, the minimum task stack
size will be listed as indeterminate for any task that invokes a procedure that, directly or indirectly, uses
a based procedure.
As a solution to this problem, a special mechanism is provided for you to provide the compiler the set of
procedures that might be called via a based procedure. Assuming that a complete set of called
procedures is provided for each based procedure, the compiler will provide an accurate estimate of
minimum task stack size. The syntax for providing call target information is shown below.
#pragma CallTargets ( <based-procedure> : <procedure-list> )
The <procedure-list> element is a comma-separated list of procedure names and/or names of
initialized ProgMem data items. In the latter case, it is assumed that the ProgMem data item is an array
of procedure addresses.
Example
Dim procTbl as IntegerVectorData({ proc1.CodeAddress, proc2.CodeAddress })
Dim procAddr as UnsignedInteger
Declare Sub myProc() Based procAddr
#pragma CallTargets(myProc : procTbl, proc3.CodeAddress)
If the CallTargets pragma occurs at the module level, it will be visible throughout the module. If it
occurs within a procedure, it applies beginning at the line on which it occurs (overriding any
CallTargets pragma at the module level for the same based procedure) through the end of the
procedure or the next occurrence of a CallTargets pragma for the same based procedure. A special
form of the CallTargets pragma, with no <procedure-list>, may be used to terminate the validity
of an earlier occurring CallTargets pragma. This form is shown by example below.
#pragma CallTargets(myProc)
There is a special case where the compiler composes an implicit CallTargets list that may obviate the
need for explicitly specifying the CallTargets. If a based procedure is defined where the base expression
is a simple expression comprising an initialized ProgMem data item with an index, the compiler assumes
that all of the elements of the ProgMem data item are call targets.
You may also specify a global call target list that will be visible from any module using the syntax below.
The global call target list will be overridden by a non-global call target list present in a module or in a
procedure.
|