Using ATEasy Procedure Data Type to Dynamically Call Commands and Procedures

Knowledge Base Article # Q200274

Read Prior Article Read Next Article
Summary This article includes a discussion on the usage of the procedure data type. The Procedure data type allow users to programmatically link to ATEasy procedures and commands.
The ATEasy Procedure data type allow users to programmatically link to procedures and commands, enabling the user to:
  • Call procedures or commands using a string that hold their name
  • Dynamically call commands of different driver Instances
  • Create scalable drivers

Procedure Data Type Basics

The ATEasy procedure data type is a pointer to a procedure. To assign data to a procedure variable you use the procedure name or procedure name string. For example, if proc is a variable of data type Procedure, the following code shows the use of the variable:

! proc: Procedure  ! declare a variable in variables

proc=GetLogString  ! assigns the internal library function GetLogString() pointer to proc variable
Print proc()       ! will call the GetLogString and will print the current log string

proc=System._Reset ! assigns System _Reset() procedure pointer to proc variable
proc()             ! will call the _Reset() procedure

proc=Abs           ! assigns the internal function Abs pointer to proc variable
print proc(-5)     ! calls Abs with a parameter of -5, this will print 5 to the log


When referencing a command with a procedure variable, the command statement is enclosed in quotes:


proc="TestExec Log Clear"  ! assigns the command 'TestExec Log Clear()' pointer to a procedure
proc()                     ! will clear the Test Executive's log


Procedure variables can also be assigned to string variables in case any string manipulation needs to be done:

! proc: Procedure
! s:String

proc="TestExec Log Append"
s=proc
s=s+" Message"
proc=s
proc("My note")  ! calls TestExec Log Append Message("My Note")


Using Procedures Variable to Call Multiple Module Instances

ATEasy supports multi UUT testing so that a single test program can be written to support testing of many devices in parallel or sequential modes. To achieve this functionality, we need to dynamically select to which Driver Shortcut to direct the commands.  In a recent application, a user has 16 data bus transceivers which the user tests by sending and receiving messages from the PC.  The communication with the UUTs is modeled with the UUT ATEasy driver and 16 instances of the driver are placed in the ATEasy System which the handles UUT1 through UUT16.

Since the same Program will be used for all 16 UUTs, the TPS must somehow differentiate between the various instruments. Using the internal AApp class  UutIndex property to differentiate between the UUT that the program talks to. This property returns the current instance of the UUT that is running.  With some procedural code in the Program module, the programmer can reference the proper driver instance as shown here:

Procedure UutMessageSend(sMessage): Void
--------------------------------------------------------------------------------
  sMessage: Val String
  proc: Procedure
{
  proc="UUT"+Str(App.UutIndex+1)+" Message Send"
  proc(sMessage)
}


For this test case, the programmer uses ATEasy's Multiple UUT testing mode and specifies parallel testing of 16 UUTs.  When the application is run, 16 instances of the program and driver are created by ATEasy and executed at the same time.  The instances are automatically assigned an AppIndex of 0 to 15.  When UutMessageSend() is called from the Program module, the command dynamically created is "UUT1 Message Send(sMessage)" to "UUT16 Message Send(sMessage)".

Arrays of Procedures

Another approach to the solving the problem of dynamically directing commands to various UUTs is to assemble a collection of procedure pointers into an array and use the UutIndex to differentiate between them.

! i: Long
! aprocUutMessageSend: Procedure[1] ! declare array of procedure

! Resize the procedure array
redim aprocUutMessageSend[App.UutCount]
! Loading the procedure array
for i=0 to App.UutCount-1
  aprocUutMessageSend[i]="UUT"+Str(i+1)+" Message Send"
next


The procedure array is loaded once during application initialization.  After the array is loaded, it can be called from within the Program module with a single call:

aprocReferences[App.UutIndex](sMessage)


Common Errors

Procedure Scope
Referenced procedures must be in scope.  If it is not, you will receive the following JIT compiler error.

Error Dialog that displays when a referenced procedure is out of scope


If you link a System procedure to a procedure variable in the Program module, the System procedure must be set to public.

Properties Editor showing Public Flag Checked


Procedure Not Compiled
If you assign a command to a procedure variable using quotation marks the reference will not be noticed and compiled when the application is built.  

Error Dialog that displays when a referenced procedure is not compiled


This issue can be resolved by checking the Compile checkbox in the Properties window for the procedure. Checking the Compile checkbox ensures that the procedure will be compiled, even if it is not used by your application.

Properties Editor showing Compile Flag Checked

Article Date 9/3/2015
Keywords Scalable, Scalability, Multiple, UUT, Parallel, Testing, ATEasy, Procedure, Function, Dynamically, Programatically

0 ratings | 0 out of 5
Read Prior Article Read Next Article