Page 93 of 229 Start Back Next End ZBasic Language Reference 83 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 compiler’s 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.