6.3   Using Triggers

Using a Trigger to Start Log Collection

The main challenge in defining a trigger to start data collection is isolating an event which precedes the sequence of interest but is as close to the start of the sequence as possible. Examining your application code or collecting a broad log which incorporates the sequence of interest may allow you to identify unique events preceding that sequence that may be used as potential trigger points.

For instance, you may observe that, shortly before the sequence of interest, a semaphore is given. It may be possible to identify the task context from which the semGive( ) is performed and possibly the ID of the semaphore being given. These criteria can be used to define when the trigger which initiates logging fires.

However, this may not be sufficient to uniquely detect the start of the region of interest if this task takes and gives the same semaphore more than once. In this case it will be necessary to further refine the trigger by using a conditional qualification. This may be achieved by examining some variable (by symbol or address) for a specific value or range of values or by invoking a specific function and testing the result.

Note that it is possible to use functions written specifically for this purpose, by making the function available on the target and entering its function name as the condition item. (For a simple example, see Example 6-1.) These functions can also further assist in diagnosis by collecting data such as the value of the system tick count when the trigger fired or some internal value of the target application.

Once you have determined when the trigger will fire, set the action of the trigger to Start WV (start WindView logging). Calling StartWV more than once results in an error, so it is important to disable the trigger that starts logging after it fires. Defining a trigger which references WindView in this way will invoke the WindView tool and request its configuration if this has not already been done.

Using a Trigger to Stop Log Collection

Although not required, it is often desirable to define a trigger to stop log collection. This focuses the log on the sequence of interest and saves both resources and analysis effort.

Approach defining a trigger to stop log collection in the same way you defined the trigger to start collection: identify an event that will not occur until the sequence of interest has completed. One technique is to write a function that fires after a specified time period, for instance, by comparing the value of the system tick count against its value when the trigger to start the sequence fired.

Once you have defined when the trigger will fire, set the action of the trigger to StopWV (stop WindView logging). If you chain this trigger to the trigger that starts logging, you can ensure that this trigger can not fire before the log collection has been started.

Triggering Examples

Downloading Trigger Definitions

Example 6-1 and Example 6-2 demonstrate loading and running saved trigger configurations.

Example 6-1:  Simple Conditional Trigger

To run the trigger you loaded from the file simpleCond.trg (see Loading a Trigger Configuration File), you must download it. However, before downloading the simpleCond trigger, you need to prepare your target. The triggering implementation requires that all the variables and functions referred to in the trigger definition be declared before triggering is started.

Start WindSh and create the variables foo and helloString as follows:

-> foo=0 
new symbol "foo" added to symbol table. 
foo = 0x125980: value = 0 = 0x0 
-> helloString="hello\n" 
new symbol "helloString" added to symbol table. 
helloString = 0x125970: value = 1202552 = 0x125978 = helloString + 0x8

Before downloading your trigger, open the Trigger Maintenance dialog box and look again at the definition. Note that the Safe box must be checked since a call to printf( ) is not allowed in ISR or system context. See Figure 6-4.

Click the button. This compiles and downloads your trigger. The Target ID changes from "not set" to a hexadecimal ID number and the status is "Armed." (See Figure 6-3). To fire your trigger, the condition for foo must be met. Enter the following in WindSh:

-> foo = 1 
foo = 0x125980: value = 1 = 0x1

The string "hello" prints on the target console (or wherever you are directing target output). Click the button. The trigger status is updated to show that it has fired.

It is important to note that the following is not valid:

This is because the action function is expecting an integer argument, whereas "hello\n" is a string.

Example 6-2:  Chaining Triggers

To see a simple example of chained triggers, click and load the configuration file installDir/host/src/windview/samples/wv10secs.trg. These chained triggers start and stop WindView. If you have not already configured WindView, the Collection Configuration dialog box opens; configure WindView so it is ready to start when the first trigger fires. If you wish, click and review the specifications for triggers #0 and #1. Trigger #0 starts WindView logging when vxTicks is greater than 0x1800. Trigger #1 stops WindView logging when vxTicks is greater than 0x1a58.


*

NOTE: vxTicks is a global variable that counts ticks. Use the shell to find its current value and reset the values in the Trigger Maintenance dialog box to be greater than the current value. Otherwise, one or both triggers will fire immediately and the log you collect will be almost empty.

Click to download the triggers. Click the button until the Triggering window shows that both triggers have fired. Click to stop triggering. If you have WindView configured for deferred upload mode, the Control window shows that there is data in the buffer and the button is active. If you have WindView configured for continuous upload mode, there is a new view graph displayed.

Evaluating Conditions

Example 6-3, Example 6-4, and Example 6-5 demonstrate how conditional triggers are evaluated and highlight issues in creating conditional triggers. Because <operand2> is interpreted as a numeric constant, you may generate unexpected results by entering a symbol in this box.

Suppose we have the following identifiers in the symbol table:

foo1

 

address = 0x0a001000

 

value = 30

 

foo2

 

address = 0x0a001004

 

value = 20

 

pFoo

 

address = 0x0a001008

 

value = 0x0a001000

 

Specifying the conditional as shown causes the value of the variable foo1 to be compared with the constant 0x20. In this case, the trigger condition is not satisfied since the value of foo1 (30 decimal) is less than 0x20. This result is expected.

Specifying the conditional as foo2 has a less obvious result than Example 6-3. As in that example, the left-hand side evaluates to the current value of foo1,which is 30 decimal. Since the "foo1" is not numeric, the system performs a symbol table lookup every time the conditional clause is evaluated to find the identifier foo1 and resolve it to an address.

The symbol table is searched for foo2 and 0x0a001004 is obtained. Because <operand 2> is interpreted as a numeric constant, not the address of a variable, the value 0x0a001004 is used for the comparison.

The comparison therefore resolves to 30 >= 0x0a001004 which is clearly not satisfied at this time. Thus, if you were expecting the expression to be evaluated as 30 >= 20, your trigger would not fire when expected.

Specifying the conditional as shown is similar to Example 6-4, except that we treat the identifier pFoo a pointer. As before a symbol table lookup is performed for both sides of the operator. pFoo yields address 0x0a001008 and is de-referenced to value 0x0a001000. foo1 yields 0x0a001000, which is treated as an integer constant. The comparison therefore resolves to 0x0a001000 == 0x0a001000 and the condition is satisfied. If you expected the expression to be evaluated as 0x0a001000 == 30, your trigger would have fired unexpectedly.

Using trgEvent( ) to Start and Stop Logging

Example 6-6 shows a highly simplified situation which allows you to experiment with starting and stopping WindView using the triggering facility.

Example 6-6:  Controlling WindView Logging with Triggers

  1. Click to start triggering and then to open the Trigger Maintenance dialog box.

  1. Create a trigger #0 which is initially enabled, with event matches equal to User Event, event ID equal to 40010, and action equal to StartWV.


*

NOTE: The event ID must be in the range 40000-65535.

  1. Create a trigger #1 which is initially disabled (uncheck the Enabled box), with event matches equal to User Event, event ID equal to 40020, and action equal to StopWV.

  1. Double-click on trigger #0 in the Triggering list to reopen the Trigger Maintenance dialog box and chain trigger #1 to trigger #0.

  1. Click to download your triggers.

  1. Open a WindSh and create a user event:

% trgEvent(40010)
The Control window will show that WindView logging has started. If necessary, click to update the Control window.

  1. Create another user event:

% trgEvent(40020)
You will see that WindView logging stops.

  1. Click to stop triggering and (if you are using deferred upload mode) to upload your logfile data.

Specifying Trigger Actions

Example 6-7 shows how to write an action function for your trigger.

Example 6-7:  Specifying an Action with a Trigger

Example 6-1 showed an example of a very simple action resulting from a conditional trigger. The same result could have been obtained by writing an action function. While this would not be an efficient solution in this simple case, the function would allow you to specify additional processing if it were needed at this point. A simple action function could be written as follows:

int myActionFunc (int parm) 
    { 
    printf ("Trigger fired\n"); 
    /* any other code you desire */ 
    return 1;   /* return value is ignored */ 
    }

Compile and download the code onto the target. In the Action section of the Trigger Maintenance window, enter:


*

NOTE: The Safe box must be checked since a call to printf( ) is made within myActionFunc( ).

Other Uses of Triggering

Triggering is a flexible diagnostic tool in its own right. It has applications that extend beyond starting and stopping WindView logging. The methods described in previous sections can serve as building blocks for more complex actions by specifying a function call as the trigger action.