Studio:Interfacing Sample: Difference between revisions

From STRIDE Wiki
Jump to navigation Jump to search
 
(73 intermediate revisions by 6 users not shown)
Line 1: Line 1:
==Introduction==
==Introduction==


The following content relates to the sample files and workspaces installed in ''%STRIDE_DIR%\Samples\Scripting\AutoScript''.  This sample consists of a [http://en.wikipedia.org/wiki/Microsoft_Visual_Studio Visual Studio] workspace for building an [[Windows_Off-Target_Apps| off-target simulator]], sample source code and test scripts, and a STRIDE workspace for sample code execution.
The following content relates to the sample files and workspaces installed in '''%STRIDE_DIR%\Samples\TestScripts\Interfacing'''.  This sample consists of a [http://en.wikipedia.org/wiki/Microsoft_Visual_Studio Visual Studio] workspace for building a [[Off-Target Test App|Windows Off-Target App]], sample source code and test scripts, and a STRIDE workspace for sample code execution.


==Getting Started==
==Getting Started==


To begin, open the Visual Studio Solution file in the sample directory. This solution (and corresponding project) were created for Visual Studio 2005.  If you have a later version of Visual Studio installed, you should be able to open this solution and it will be automatically upgraded if necessary. If you do not currently have any version of Visual Studio, we recommend that you install the current free version of [http://en.wikipedia.org/wiki/Visual_Studio_Express Visual Studio Express].
===Prerequisites===
Before starting the Interfacing Sample, the following prerequisites must be satisfied:
* STRIDE must be installed on the Windows PC to be used in the training, and any required licenses must be present.
* Active State Perl must be installed, and [[Studio:Desktop Installation#Perl|additional perl packages]] must be downloaded and installed.
* Microsoft Visual Studio 2005 or a later version must be installed. If you do not currently have any version of Visual Studio, we recommend that you install the current free version of [http://en.wikipedia.org/wiki/Visual_Studio_Express Visual Studio Express].
For details and instructions, see [[Studio:Desktop Installation]].


Once you have successfully opened the solution, rebuild it.  The build process has custom STRIDE build rules integrated and will produce a STRIDE database, intercept module source files, and an off-target simulator application that incorporates the sample source code.
===Basic Execution===


Once the build is complete, perform the following steps to run the sample scripts in the workspace:
To begin, open the Visual Studio Solution file in the sample directory.  This solution (and corresponding project) were created for Visual Studio 2005.  If you have a later version of Visual Studio installed, you should be able to open this solution and it will be automatically upgraded if necessary.


# launch the off-target simulator, Ascript_Samples.exeThis will run in a standard console window.
Once you have successfully opened the solution, rebuild itThe build process has custom STRIDE build rules integrated and will produce a STRIDE database, intercept module source files, and an Windows Off-Target App that incorporates the sample source code.
# open a command prompt window and change to this sample's directory.
# at the command prompt, run the command <tt>'''WorkspaceRun.pl -x setup -x teardown'''</tt>.  This will execute all of the sample test scripts in the workspace and displays the results. You may open a browser and display the report written to the Ascript_Samples.html file in the sample's directory .
# quit the Ascript_Samples.exe application by typing 'q' in its console window.


==Sample Tests==
Once the build is complete you can open the STRIDE workspace file and run all scripts using the [[image:Run_all.gif]] button.  The scripts in this workspace focus on scripting with the ascript object model.  For examples of using the reporter object model to add test case reporting to your scripts, please refer to the [[Reporting Sample]].


Now that you have built the off-target simulator and executed the scripting samples, you can take time to peruse the sample scripts and the corresponding results that each produces.  This section provides a brief description for each script.
==Sample Description==


===User Owner===
Now that you have built the Windows Off-Target App and executed the scripting samples, you can take time to peruse the sample scripts. This section provides a brief description for each category of example scripts. You can execute any of the scripts manually as long as you have the Windows Off-Target App (Interfacing.exe) running.
This folder contains scripts that implement both the user and owner sides of a function call. This sample is completely host based - no target simulator is required. Only the user script is executed by the Studio test runner; the owner script is started by the user script, running it with a non-blocking call (using the '''studio''' object, described in the Studio Online Help).  


The '''user.pl''' script first runs the '''owner.pl''' script, as described. Then it loops until it determines that the test function has been owner registered. Once this has occurred it calls the function, blocking until the call is returned.
The main focus of this sample is the use of your SCL qualified interfaces in script code.  The STRIDE object that enables this is [[AutoScript]] (declared as ''ascript'' when injected into Studio's script execution environment). These examples are provided in two functionally equivalent examples. One is in jscript and the other in perl. It is recommended that you try to follow one of the provided examples in whichever language you are most comfortable reading.


The '''owner.pl''' script registers as an owner of the test function and then enters an event wait loop where a blocking call to ''[[Events#WaitForEvent|WaitForEvent]]'' is made. '''WaitForEvent''' returns with a function call event when the the test function is called from the user script. From there the owner script sets the function [[Functions#OutPointers|OutPointer]] and return values, returns the call, and exits the loop and script.
'''Note:''' This sample does not cover the use of [[AutoScript#ascript.TestUnits|test units in ascript]]. For examples of how to invoke test units from script code, please refer to the [[Test Class Samples]].


===Register Override===
===Calling Functions===
This folder contains scripts that again implement both the user and owner sides of a function call. The difference here is that this time the scripted owner is registered as an ''[[Functions#Override_Owner|override]]'' owner - which will receive calls from the user instead of the original function owner. This sample is not completely host based - the target simulator is required to provide the original owner of the function. Only the user script is executed by the Studio test runner; the owner script is started by the user script, running it with a non-blocking call.


The '''regOverrideUser.pl''' script first calls the original owner of the function, which is the function implemented in the target simulator application, which should be running and connected at this time (the '''setup''' folder runs the console application, and the '''OnRunConnect''' property is set on the Register Override folder to connect before executing the scripts). Once the function call is returned, the user script starts the '''regOverrideOwner.pl''' script. After that the user script loops until it detects that the function has been registered override (for synching purposes with the owner script) and then it calls the function again.
Shows how to call functions that have been captured and qualified using STRIDE. These scripts make calls to functions that have been implemented in the Windows Off-Target App. The examples shows how to set-up and invoke the functions with a variety of input data types - much of the focus is on how to make use of the [[AutoScript Dynamic Objects]] interfaces.


The '''regOverrideOwner.pl''' script is started by the '''regOverrideUser.pl''' script, as described above. It immediately registers itself as an override owner for the test function and loops until the function call event is received. From there it sets the function [[Functions#OutPointers|OutPointer]] and return values, returns the call, and exits the loop and script.
====Scalars====


===Collections===
Shows how to make calls and receive and return values consisting of simple scalar values (int, float, char, etc.) that are passed by value.
This folder contains scripts that implement both the user and owner sides for multiple function calls. This sample shows how to access the [[Functions|AutoScript Functions]] collection. The sample is completely host based - no target simulator is required. Only the user script is executed by the Studio test runner; the owner script is started by the user script, running it with a non-blocking call.  


The '''MultiFnUser.pl''' script first runs the '''MultiFnOwner.pl''' script, then loops through the Functions collection, checking for each to be owner registered. '''''Note:''''' this is only necessary as a synching mechanism with the owner script. If the function owner is implemented on the target application then all interfaces are access class registered at the start of the application. <br>
====AsynchronousCall====
Once all the function owners have been registered, the user script loops through the Functions collection again, calling each Function through the [[Functions#Function_User|Function User]] interface. In the sample script, special  processing is done for the '''fMultiFnTestIntPtr''' function before the call is made. The integer pointer field in the [[AutoScript_Functions#ParameterList|ParameterList]] is set to NULL by accessing the synthesized PointerNuller object (for more details refer to the [[AutoScript_Dynamic_Objects#Pointer_auto-dereferencing|pointer auto-dereferencing]] section of the AutoScript reference.) Before the user script exits, it waits for the function owners to unregister prior to verifying the results, and generating the report.


The '''MultiFnOwner.pl''' script loops through the Functions collection and registers as an owner of each test function. Then the script enters an event wait loop where the blocking call to ''[[Events#WaitForEvent|WaitForEvent]]'' is made which will return when registered function calls events occur. Another event that will trigger a return from the WaitForEvent call is the timeout event, which was enabled earlier in the script by setting the AutoScript ''WaitTimeoutPeriod'' property to a positive, non-zero value. (See the [[AutoScript#Ascript_API|AutoScript API]] page for more details on WaitForEvent and WaitTimeoutPeriod.)
Shows how to make asynchronous function calls and wait for the return status. In this example, we illustrate the [[AutoScript_Functions#Asynchronous_Calls_.28non-blocking.29|asynchronous (or non-blocking)]] calls to a function using the simple ''f_cf_int'' function from the previous example. The [[AutoScript#ascript.Functions.Item.User|ParameterList]] items are assigned in exactly the same way as with synchronous calls. The call, however, is initiated using [[AutoScript#ascript.Functions.Item.User|CallNonBlocking]].  The response is retrieved by calling [[AutoScript_Events#WaitForEvent|WaitForEvent]]. By default, WaitForEvent blocks forever until an event is generated (such as function return status or a timer) - but you can change this behavior by setting the [[AutoScript#Ascript_API|WaitTimeoutPeriod]] value to something nonzero before calling WaitForEvent.
When each function call event is received, the owner script sets the function [[Functions#OutPointers|OutPointer]] and return values, and returns the call. When the timeout event is received, and the timeout period has elapsed, the event wait loop is exited. Before the script is exited, the Functions collection is traversed again, where each function is unregistered, thereby re-synching with the user script which is waiting for the function owner unregistration before verifying the function call results.


==Test Execution==
If you want to do other processing in the script while waiting for the function return status (or other event), you can code a polling loop and use the [[AutoScript#Ascript_API|IsEventPending]] property to check the event queue periodically.  The second example here illustrates this technique.


This sample demonstrates two different techniques for executing the sample test scripts.
====Structs====


===Command Line Execution===
Shows how to make calls to functions that accept and/or return structures by value. 


Command line execution for sample STRIDE test workspace is done using the [[WorkspaceRun.pl|WorkspaceRun utility]]. Here is an example of specific syntax to execute a test workspace. All of these commands can be invoked from a standard [http://en.wikipedia.org/wiki/Command_Prompt_(Windows) command shell] (or other shell of your choosing) and the arguments shown assume that the commands are executed with the sample's directory as the starting directory. You must have your Ascript_Samples.exe application running in order for the runner to be able to initiate a connection to the target simulator.
====Arrays====


  WorkspaceRun.pl -x setup -x teardown
Shows how to make calls to functions that have fixed size arrays in their input arguments.  The techniques used here to set individual array members are very similar to those used when working with Sized Pointers.


When you run this command, you should see console output like:
====ArrayDataXfer====


  Opening workspace C:\S2\Seaside\Samples\Scripting\AutoScript/Ascript_Samples.ssw..
Shows how to make use of the [[AutoScript_Dynamic_Objects#Bulk_unstructured_data_transfer|AutoScript Bulk Transfer]] interfaces for setting array data. These bulk transfer interfaces can provide '''better performance for setting large array payloads''' since all of the data is transferred to ascript using a single COM interface property assignment. For large array payloads, there can be undesirable COM call overhead performance penalty when using the ascript object model directly to set each array member value one-by-one (since each member will be set with a COM interface property invocation). These methods provide a means to mitigate that overhead.
  excluding folder setup in workspace C:\S2\Seaside\Samples\Scripting\AutoScript/Ascript_Samples.ssw
  running folder test in workspace C:\S2\Seaside\Samples\Scripting\AutoScript/Ascript_Samples.ssw
  excluding folder teardown in workspace C:\S2\Seaside\Samples\Scripting\AutoScript/Ascript_Samples.ssw
  Test results written to C:\S2\Seaside\Samples\Scripting\AutoScript\Ascript_Samples.html
  ***************************************************************************
  Results Summary
  ***************************************************************************
    Passed:              7
    Failed:              0
    In Progress:          0
    Not Applicable:      0
    ...in 5 suites.
  ***************************************************************************


===Workspace-Based Execution===
The bulk data transfer interfaces require that you provide strings that represent an entire array's worth of data - partial data is not allowed.  For multidimensional arrays, the data must be stored in the string in row-major order. This example uses the same interfaces and the Array example (above) but the data is assigned using the HexString, B64String, or SafeArray properties.


We provide a sample STRIDE workspace (.ssw file) that demonstrates the use of script execution with STRIDE Studio to manage the test order and hierarchy. The setup and teardown folders provide basic infrastructure scripts that start and stop the simulator application (Ascript_Samples.exe). The scripts that drive the testing are in the workspace '''test''' folder, and are described in the [[#Sample_Tests|Sample Tests]] section above. The test functions are declared in the header files under '''Source Files''' and are implemented in the target application, in the ".c" files that correspond to the header files in the sample workspace. Since these functions are owner registered by the test scripts, most of the functions implemented in the target application are never executed. The real purpose of the target application is to illustrate the ''RegisterOverride'' concept, explained in the [[#Sample_Tests|Sample Tests]] section above. Note: these ".c" files are part of the Visual Studio project, you may view these files in Visual Studio, or you may locate them on disk in the same directory as the sample header files, under the '''Tests''' directory under the installed sample directory.<br>
The first example (''f_cf_array_1'') requires a 3 element, 1 dimensional array of integers. Our target's integers are 4 bytes, thus 24 hex digits are required to represent the array's data.  Each 4 bytes (8 hex characters) in our example represents the integer value 10 in little endian byte order which is appropriate for our windows off-target app.


[[Category: Samples]]
The next example (''f_cf_array_2'') requires a 3x3 array of integers. Here we use a base64(see [http://tools.ietf.org/html/rfc2045 RFC 2045]) encoded string which requires 48 B64 characters to represent the 36 bytes of the array. Each element in the array again holds the value 10.
 
The third example (''f_cf_array_3'') uses a [http://msdn.microsoft.com/en-us/library/ms221482.aspx safearray] (also known as a COM array or a VBArray) to set the array elements. JScript does not natively support safearrays for writing/assignment, but the [http://msdn.microsoft.com/en-us/library/x4k5wbx4(VS.85).aspx Scripting.Dictionary object] provides a means for creating a safe-array from a hash table.
 
====Strings====
 
Shows how to use strings in function calls.
 
====Pointers====
 
Shows examples of basic pointer usage, as documented by [[Scl_ptr|scl_ptr]]. The first three examples show how to assign and read pointed-to values.  The last example shows how to set a pointer to NULL.  For more information on working with pointers in ascript, refer to [[AutoScript_Dynamic_Objects#Pointers|this article]].
 
====Opaque Pointers====
 
Shows how to call functions that have been qualified with [[Scl_ptr_opaque|scl_ptr_opaque]]. When working with opaque pointers, the ascript dynamic objects for that parameter refer to the pointer value and not the pointed-to value (as described in the aformentioned article).
 
==== Sized Pointers ====
 
 
Shows how to set-up parameters that have been qualified with [[Scl_ptr_sized|scl_ptr_sized]]. The first example (''f_cf_sized_pointer_1'') declares a size field in the pragma and the script must correctly set the size field. The second example (''f_cf_sized_pointer_2'') does not declare a size field, the data is assumed to be fixed size. The next example (''f_cf_sized_pointer_3'') shows how INOUT sized pointers are returned and how the resulting outpointers are accessed. The fourth example (''f_cf_sized_pointer_4'') shows how to access OUT sized pointers. In this example, we have also declared the the return value of the function as the size field for the OUT sized pointer. The last example (''f_cf_sized_pointer_5'') shows how to use RETURN sized pointers.
 
====Unions====
 
Shows how to call functions with union input parameters that have been qualified with [[Scl_union|scl_union]].  The first two examples show basic examples of calling discriminated unions.  The third example demonstrates the use of an enum discriminant value where [[Scl_union_activate|scl_union_activate]] has been used to map enum values to active indexes.  The last example shows a simple fixed-active member union.
 
====Values====
 
Shows how to make calls to interfaces with parameters that have been qualified with [[Scl_values|scl_values]]. The two examples show how to call interfaces with parameters that have been constrained by an enum or user-defined list of values.
 
====Timeout====
 
All of the synchronous function call examples so far have assumed the device is well-behaved that the functions will return in a reasonable amount of time.  If you want to make synchronous calls to a target that might fail to return for any reason (e.g. due to a system fault), then you should consider setting the [[AutoScript#Ascript_API|RspTimeoutPeriod]] value before making any function calls.
 
This example shows a simple use case for the call timeout.  We call a function that actually sleeps for 20 seconds. Prior to making the call, we have set the RspTimeoutPeriod to 5 seconds.  As expected, the function does not return in the specified time period, so ascript throws an exception from the Call method.
 
===Owning Functions===
 
Shows how a function implementation (aka [[AutoScript#ascript.Functions.Item.Owner|owner]]) can be scripted. The basic steps to implementing an owner in script are:
 
# Register for ownership of the function. More specifically, the autoscript method [[AutoScript#ascript.Functions.Item.Owner|Register()]] (or [[AutoScript#ascript.Functions.Item.Owner|OverrideRegister()]]) must be called.
# Call the autoscript API [[AutoScript_Events|WaitForEvent()]]. This will pause execution of the script until a caller invokes the method and the method call will be delivered to this script as an event. The event object's type will be FunctionOwner (subtype of [[AutoScript_Events|Event]]). This can be validated in script as the event Type field will have the value "FunctionOwner"
# Handle the call by checking the values of the parameters or setting return values.
# Return to the caller with the autoscript Return() method.
 
Ownership of five different functions is illustrated by the sample. The first function, f_owning_1() is a very simple interface taking a single int parameter and returning an int. The definition of it, like all the owning functions is found in OwningFunctions.h. The functions f_owning_2(), f_owning_3() and f_owning_4() illustrate owner handling of IN, OUT an INOUT pointers respectively. Finally, f_owning_5() illustrates owner handling of a function with two parameters.
 
For examples of source instrumentation requirements when owning and overriding functions see the [[Intercept_Module_Sample|Intecept Module Sample.]]
 
===Sending Messages===
 
====Send====
 
Shows how to send messages from script code on the host.  These messages are handled by a dedicated thread in the off-target app. This script shows examples of sending several message types (captured via [[Scl_msg|scl_msg]]): one-way command, two-way command/response, and broadcast.
 
===Receiving Messages===
 
====Receive====
 
Shows how to receive [[Scl_msg|messages]] in script, using the same messages as in the previous example.  The messages are sent by code that runs in the off-target app.
 
===Using Constants===
 
The AutoScript object model exposes preprocessor macros present in the compilation units given to the STRIDE compiler.  There are a number of rules that determine exactly how the macros are interpreted by the compiler (refer to SCL Language Reference for details).  The [[AutoScript#ascript.Constants|AutoScript Constants Object]] exposes the preprocessor macros as a collection of items with name an value properties.
 
====Macros====
This shows how to use the [[AutoScript#ascript.Constants.Item|Value]] field to refer to the interpreted value of the declared macro.  In many cases, this is just the string representation of the macro as declared in the source code.  In some cases, when the expression can be readily interpreted as an arithmetic or logical expression, the result of the expression is returned in the Value field instead.  Refer to the corresponding ''Constants.h'' source file when reviewing this example.
 
===Using Timers===
 
Both examples show how to create and receive timer events created using [[AutoScript#ascript.Timers|Ascript.Timers]]. Timers are created on a per script basis and only affect the event queue for the executing script in which they were created. Timers are treated as an event in the ascript object model, thus the handling of timers integrates well with other asynchronous processing (e.g. wait for function return status or receiving messages).
 
====OneShot====
 
Shows how to create a simple single-shot timer and wait for it to fire.
 
====Periodic====
 
Shows how to create a periodic timer.  We wait for the timer to fire 5 times in this example and then we quit.
 
=== Callbacks ===
 
This sample shows how to handle C-language callbacks. It illustrates two techniques that can be used in STRIDE: anonymous callbacks and named callbacks. The anonymous callback (also called "default") is used when the logic of the registration function is to be tested. This is usually used to verify that the callback function is called (or notified) at the appropriate times. The named callback technique is used when the callback function itself is the logic to be tested.
 
 
 
 
[[Category:Studio:Samples]]

Latest revision as of 23:01, 2 June 2010

Introduction

The following content relates to the sample files and workspaces installed in %STRIDE_DIR%\Samples\TestScripts\Interfacing. This sample consists of a Visual Studio workspace for building a Windows Off-Target App, sample source code and test scripts, and a STRIDE workspace for sample code execution.

Getting Started

Prerequisites

Before starting the Interfacing Sample, the following prerequisites must be satisfied:

  • STRIDE must be installed on the Windows PC to be used in the training, and any required licenses must be present.
  • Active State Perl must be installed, and additional perl packages must be downloaded and installed.
  • Microsoft Visual Studio 2005 or a later version must be installed. If you do not currently have any version of Visual Studio, we recommend that you install the current free version of Visual Studio Express.

For details and instructions, see Studio:Desktop Installation.

Basic Execution

To begin, open the Visual Studio Solution file in the sample directory. This solution (and corresponding project) were created for Visual Studio 2005. If you have a later version of Visual Studio installed, you should be able to open this solution and it will be automatically upgraded if necessary.

Once you have successfully opened the solution, rebuild it. The build process has custom STRIDE build rules integrated and will produce a STRIDE database, intercept module source files, and an Windows Off-Target App that incorporates the sample source code.

Once the build is complete you can open the STRIDE workspace file and run all scripts using the Run all.gif button. The scripts in this workspace focus on scripting with the ascript object model. For examples of using the reporter object model to add test case reporting to your scripts, please refer to the Reporting Sample.

Sample Description

Now that you have built the Windows Off-Target App and executed the scripting samples, you can take time to peruse the sample scripts. This section provides a brief description for each category of example scripts. You can execute any of the scripts manually as long as you have the Windows Off-Target App (Interfacing.exe) running.

The main focus of this sample is the use of your SCL qualified interfaces in script code. The STRIDE object that enables this is AutoScript (declared as ascript when injected into Studio's script execution environment). These examples are provided in two functionally equivalent examples. One is in jscript and the other in perl. It is recommended that you try to follow one of the provided examples in whichever language you are most comfortable reading.

Note: This sample does not cover the use of test units in ascript. For examples of how to invoke test units from script code, please refer to the Test Class Samples.

Calling Functions

Shows how to call functions that have been captured and qualified using STRIDE. These scripts make calls to functions that have been implemented in the Windows Off-Target App. The examples shows how to set-up and invoke the functions with a variety of input data types - much of the focus is on how to make use of the AutoScript Dynamic Objects interfaces.

Scalars

Shows how to make calls and receive and return values consisting of simple scalar values (int, float, char, etc.) that are passed by value.

AsynchronousCall

Shows how to make asynchronous function calls and wait for the return status. In this example, we illustrate the asynchronous (or non-blocking) calls to a function using the simple f_cf_int function from the previous example. The ParameterList items are assigned in exactly the same way as with synchronous calls. The call, however, is initiated using CallNonBlocking. The response is retrieved by calling WaitForEvent. By default, WaitForEvent blocks forever until an event is generated (such as function return status or a timer) - but you can change this behavior by setting the WaitTimeoutPeriod value to something nonzero before calling WaitForEvent.

If you want to do other processing in the script while waiting for the function return status (or other event), you can code a polling loop and use the IsEventPending property to check the event queue periodically. The second example here illustrates this technique.

Structs

Shows how to make calls to functions that accept and/or return structures by value.

Arrays

Shows how to make calls to functions that have fixed size arrays in their input arguments. The techniques used here to set individual array members are very similar to those used when working with Sized Pointers.

ArrayDataXfer

Shows how to make use of the AutoScript Bulk Transfer interfaces for setting array data. These bulk transfer interfaces can provide better performance for setting large array payloads since all of the data is transferred to ascript using a single COM interface property assignment. For large array payloads, there can be undesirable COM call overhead performance penalty when using the ascript object model directly to set each array member value one-by-one (since each member will be set with a COM interface property invocation). These methods provide a means to mitigate that overhead.

The bulk data transfer interfaces require that you provide strings that represent an entire array's worth of data - partial data is not allowed. For multidimensional arrays, the data must be stored in the string in row-major order. This example uses the same interfaces and the Array example (above) but the data is assigned using the HexString, B64String, or SafeArray properties.

The first example (f_cf_array_1) requires a 3 element, 1 dimensional array of integers. Our target's integers are 4 bytes, thus 24 hex digits are required to represent the array's data. Each 4 bytes (8 hex characters) in our example represents the integer value 10 in little endian byte order which is appropriate for our windows off-target app.

The next example (f_cf_array_2) requires a 3x3 array of integers. Here we use a base64(see RFC 2045) encoded string which requires 48 B64 characters to represent the 36 bytes of the array. Each element in the array again holds the value 10.

The third example (f_cf_array_3) uses a safearray (also known as a COM array or a VBArray) to set the array elements. JScript does not natively support safearrays for writing/assignment, but the Scripting.Dictionary object provides a means for creating a safe-array from a hash table.

Strings

Shows how to use strings in function calls.

Pointers

Shows examples of basic pointer usage, as documented by scl_ptr. The first three examples show how to assign and read pointed-to values. The last example shows how to set a pointer to NULL. For more information on working with pointers in ascript, refer to this article.

Opaque Pointers

Shows how to call functions that have been qualified with scl_ptr_opaque. When working with opaque pointers, the ascript dynamic objects for that parameter refer to the pointer value and not the pointed-to value (as described in the aformentioned article).

Sized Pointers

Shows how to set-up parameters that have been qualified with scl_ptr_sized. The first example (f_cf_sized_pointer_1) declares a size field in the pragma and the script must correctly set the size field. The second example (f_cf_sized_pointer_2) does not declare a size field, the data is assumed to be fixed size. The next example (f_cf_sized_pointer_3) shows how INOUT sized pointers are returned and how the resulting outpointers are accessed. The fourth example (f_cf_sized_pointer_4) shows how to access OUT sized pointers. In this example, we have also declared the the return value of the function as the size field for the OUT sized pointer. The last example (f_cf_sized_pointer_5) shows how to use RETURN sized pointers.

Unions

Shows how to call functions with union input parameters that have been qualified with scl_union. The first two examples show basic examples of calling discriminated unions. The third example demonstrates the use of an enum discriminant value where scl_union_activate has been used to map enum values to active indexes. The last example shows a simple fixed-active member union.

Values

Shows how to make calls to interfaces with parameters that have been qualified with scl_values. The two examples show how to call interfaces with parameters that have been constrained by an enum or user-defined list of values.

Timeout

All of the synchronous function call examples so far have assumed the device is well-behaved that the functions will return in a reasonable amount of time. If you want to make synchronous calls to a target that might fail to return for any reason (e.g. due to a system fault), then you should consider setting the RspTimeoutPeriod value before making any function calls.

This example shows a simple use case for the call timeout. We call a function that actually sleeps for 20 seconds. Prior to making the call, we have set the RspTimeoutPeriod to 5 seconds. As expected, the function does not return in the specified time period, so ascript throws an exception from the Call method.

Owning Functions

Shows how a function implementation (aka owner) can be scripted. The basic steps to implementing an owner in script are:

  1. Register for ownership of the function. More specifically, the autoscript method Register() (or OverrideRegister()) must be called.
  2. Call the autoscript API WaitForEvent(). This will pause execution of the script until a caller invokes the method and the method call will be delivered to this script as an event. The event object's type will be FunctionOwner (subtype of Event). This can be validated in script as the event Type field will have the value "FunctionOwner"
  3. Handle the call by checking the values of the parameters or setting return values.
  4. Return to the caller with the autoscript Return() method.

Ownership of five different functions is illustrated by the sample. The first function, f_owning_1() is a very simple interface taking a single int parameter and returning an int. The definition of it, like all the owning functions is found in OwningFunctions.h. The functions f_owning_2(), f_owning_3() and f_owning_4() illustrate owner handling of IN, OUT an INOUT pointers respectively. Finally, f_owning_5() illustrates owner handling of a function with two parameters.

For examples of source instrumentation requirements when owning and overriding functions see the Intecept Module Sample.

Sending Messages

Send

Shows how to send messages from script code on the host. These messages are handled by a dedicated thread in the off-target app. This script shows examples of sending several message types (captured via scl_msg): one-way command, two-way command/response, and broadcast.

Receiving Messages

Receive

Shows how to receive messages in script, using the same messages as in the previous example. The messages are sent by code that runs in the off-target app.

Using Constants

The AutoScript object model exposes preprocessor macros present in the compilation units given to the STRIDE compiler. There are a number of rules that determine exactly how the macros are interpreted by the compiler (refer to SCL Language Reference for details). The AutoScript Constants Object exposes the preprocessor macros as a collection of items with name an value properties.

Macros

This shows how to use the Value field to refer to the interpreted value of the declared macro. In many cases, this is just the string representation of the macro as declared in the source code. In some cases, when the expression can be readily interpreted as an arithmetic or logical expression, the result of the expression is returned in the Value field instead. Refer to the corresponding Constants.h source file when reviewing this example.

Using Timers

Both examples show how to create and receive timer events created using Ascript.Timers. Timers are created on a per script basis and only affect the event queue for the executing script in which they were created. Timers are treated as an event in the ascript object model, thus the handling of timers integrates well with other asynchronous processing (e.g. wait for function return status or receiving messages).

OneShot

Shows how to create a simple single-shot timer and wait for it to fire.

Periodic

Shows how to create a periodic timer. We wait for the timer to fire 5 times in this example and then we quit.

Callbacks

This sample shows how to handle C-language callbacks. It illustrates two techniques that can be used in STRIDE: anonymous callbacks and named callbacks. The anonymous callback (also called "default") is used when the logic of the registration function is to be tested. This is usually used to verify that the callback function is called (or notified) at the appropriate times. The named callback technique is used when the callback function itself is the logic to be tested.