Tcl, the tool command language, is the Tornado extension language; just as you use Tcl to customize other Tornado tools, you can use it to customize WindView.
For introductory information on the use of Tcl with Tornado (and for additional Tcl references), see the Tornado User's Guide: Tcl. For reference information about the Tcl facilities you can use to customize Tornado, including specialized Tcl calls for WindView, see the online Tornado API Reference>GUI Tcl Library.
If the WindView default configuration meets your needs, you can ignore the instructions in this appendix.
The site-wide Tcl initialization file for WindView, WindView.win32.tcl, is located in installDir/host/resource/tcl. This file contains the default Tcl configuration information for WindView, and must be present for WindView to run.
When you start up WindView (see 2.2 Running WindView), WindView.win32.tcl is read automatically. After that, the following initialization files are read, if they exist:
|
|
|||||||||||||||||||
As described in The wvEvent( ) Routine, you can generate user events with the wvEvent( ) routine.1 This user event can contain a buffer of data that is logged when the event occurs. You can customize the Show Event dialog box so that it displays this buffer in a format that is appropriate for your needs. To do this, you need to create a userEvents.tcl file. Figure D-1 shows how a sample event might appear in the Show Event dialog box before and after formatting.
The following example shows two structures; USER_EVENT is associated with wvEvent #5 and USER_EVENT2 with wvEvent #15. The second part of the example shows source code for generating these events.
#include <vxworks.h>
#include "string.h"
#include "stdio.h"
#include "wvLib.h"
#include "taskLib.h"
typedef struct
{
char name[10];
unsigned char x;
unsigned short y;
unsigned long z;
} USER_EVENT;
typedef struct
{
char name[8];
unsigned long z;
} USER_EVENT2;
/* Create some code to generate a user event */
void UE(unsigned char a, unsigned short b, unsigned long c)
{
USER_EVENT myEvent;
USER_EVENT2 myEvent2;
strcpy(myEvent.name, "UserEvent");
myEvent.x = a;
myEvent.y = b;
myEvent.z = c;
strcpy(myEvent2.name, "User15");
myEvent2.z = (unsigned long)a;
wvEvent(5, (char *)&myEvent, sizeof(USER_EVENT));
wvEvent(15, (char *)&myEvent2, sizeof(USER_EVENT2));
printf("You entered %c %d %d\n", a, b, c);
}
/* wrapper to call UE */
void doUE(void){
UE((unsigned char)'w', (unsigned short) 87, (unsigned long) 123456);
}
The next example shows a userEvents.tcl file for displaying these events. The procedure userEventFormat( ), which is used by this example, is defined in the installDir/host/resource/tcl/app-config/WindView/database.tcl.
# This is the Tcl proc to display data for the "alarm" event (user event
# 4) from the producer/consumer demo. It assumes a big-endian target and does
# not do any byte-swapping.
#
# It corresponds to the wvEvent() call in the application C code fragment
# below. Notice how a floating point value is put into a string on the
# target because the host side doesn't know how to format floating point:
#
# typedef struct {
# char condition[16];
# char val[16];
# } ALARM;
# .
# .
# .
# if ((testVal > MAX_ALLOWED_OUTPUT) || (testVal < (-MAX_ALLOWED_OUTPUT)))
# {
#
# /* indicate error through windview event */
#
# if (testVal > 0)
# {
# printf("ALARM: output data %f over limit\n",
# testVal);
# strncpy(alarm.condition,"OVER LIMIT",16);
# }
# else
# {
# printf("ALARM: output data %f under limit\n",
# testVal);
# strncpy(alarm.condition,"UNDER LIMIT",16);
# }
# nchars = sprintf (alarm.val, "%2.5f", testVal);
# wvEvent (4, (char *)&alarm, sizeof(alarm));
# .
# .
# .
#
# }
#
proc userFormat00004 {event} {
set data [userEventFormat $event {s16 s16}]
set string1 [lindex $data 0]
set string2 [lindex $data 1]
set returnMessage ""
append returnMessage [format "ALARM is %s
\noutputVal is %s" $string1 $string2]
return $returnMessage
}
# The next two Tcl procs are for the events (5 and 15) used in techtip569.c.
# Notice how the argument list passed to userEventFormat includes dummy formats
# to absorb the padding in the structure.
proc userFormat00005 {event} {
# name, uchar, padding, ushort, padding, ulong
set data [userEventFormat $event { s10 n1 n1 n2 n2 n4 }]
set name [lindex $data 0]
set ucdata [lindex $data 1]
set usdata [lindex $data 3]
set uldata [lindex $data 5]
# Add the following two lines for little-endian targets:
# set usdata [swapTargetShort $usdata]
# set uldata [swapTargetInt $uldata]
# Result is a formated string that contains a string, decimal, hex and decimal displayed values.
set result [format "name = %10s
\nuchar = %c
\nushort = 0x%x \
\nulong = %d" $name $ucdata $usdata $uldata]
return $result
}
proc userFormat00015 {event} {
set data [userEventFormat $event { s8 n4 } ]
set data1 [lindex $data 0]
set data2 [lindex $data 1]
# Add the following two lines for little-endian targets:
# set data2 [swapTargetInt $data2]
# messageBox "swapped data2 is $data2"
return "name = $data1
\nulong = $data2"
By default, the wvEvent( ) and e( ) routines generate the
icon, followed by the event number (for example,
). However, you can create your own icon to be displayed for each event number.
Store event icons for user-defined WindView events in installDir/.wind/windview. The file name for each event icon must be of the form userNumber.bmp, for example, user28.bmp. To create the icon, use any graphical editing program that can save bitmap (.bmp) files; you can use bitmaps up to 16 bits wide by 16 bits high, but they must be monochrome, one-bit-per-pixel. For example, you can use the Microsoft Paint accessory included with Windows to create a bitmap.
Once an appropriately named bitmap is available, whenever you call the wvEvent( ) or e( ) routine, the user event icon with the corresponding event number is displayed. For example, if you call wvEvent(28, NULL, 0), the icon described by the file user28 (if present) is displayed.
Users who write their own BSPs and drivers, or who use BSPs and drivers not supplied by Wind River Systems, need to update WindView calls in this code to make it compatible with WindView 2.2.
The code below shows the WindView 1.0.1 instrumentation point coded in an interrupt controller:
#ifdef INCLUDE_INSTRUMENTATION
/* windview instrumentation - log interrupt event.
* evtTimeStamp has the value taken during intEnt. intVec is
* obtained in this function and the two data are logged here
*/
if (evtLogTIsOn)
(* _func_evtLogT1_noTS) (EVENT_INT_ENT((int)intVec), evtTimeStamp);
#endif
#ifdef INCLUDE_WINDVIEW
/* windview instrumentation - log interrupt event.
* evtTimeStamp has the value taken during intEnt. intVec is
* obtained in this function and the two data are logged here
*/
if (ACTION_IS_SET)
{
if ( WV_EVTCLASS_IS_SET(WV_CLASS_1|WV_ON) )
(* _func_evtLogT1_noTS)(EVENT_INT_ENT((int)intVec),
evtTimeStamp);
if (TRG_EVTCLASS_IS_SET(TRG_CLASS_1|TRG_ON))
( * _func_trgCheck) (EVENT_INT_ENT((int)intVec),
TRG_CLASS1_INDEX, NULL, NULL, NULL, NULL, NULL, NULL);
}
#endif
1: You can also set eventpoints with the e( ) routine; see The e( ) Routine.