QTools  6.6.0
Customizing and Extending QSpyView

The QSpyView Front-End has been specifically designed for extensibility, so that you can quickly customize its behavior to your specific project. In fact, as mentioned in the section about running QSpyView, the qspyview.tcl script takes a command-line parameter, which is another Tcl script designed specifically to extend and customize the basic functionality. This section describes how to write this extension script, so that you can turn QSpyView into a powerful custom Human-Machine Interface (HMI) for your projects.

You don't need to change the qspyview.tcl script to customize and extend it for your project. The customization you make go into a separate script, which is specific to your project. That way, you can have many different customization scripts and you don't pollute (and possibly break) the original code.

QSpyView files

The QSpyView Front-End has a modular source code, consisting of the following files and folders:

  • qtools
    • qspyQSPY tool
      • qspyviewQSpyView sources
        • img — images used by QSpyView™
        • qspy.tcl — Tcl script for UDP communication with the QSPY Back-End
        • qspyview.tcl — QSpyView Tcl/Tk script
        • default.tcl — the default customization of the QSpyView Tcl/Tk script

As you can see, the QSpyView source code is broken down into three scripts. The qspy.tcl script implements the UDP communication with the QSPY Back-End. This script is specifically written in pure Tcl an no Tk, so that it can be used both with and without a GUI (head-less scripts). This script is not standalone but rather it needs to be included (sourceed) in other scripts.

The main functionality of QSpyView is implemented in the qspyview.tcl script, which uses Tk for the GUI. This script takes up to three optional command-line parameters: <cust-script>, <qspy-host>, and <qspy-UDP-port>. The <cust-script> the customization script that will be included (sourceed) by qspyview.tcl. If you don't provide this parameter, the default customization script default.tcl will be used.

The QSpyView folder does not contain the customization for the DPP example application, because it makes much more sense to co-locate this customization with the DPP project. Consequently, the dpp.tcl is located in the QP/C/C++ example directory <qpx>\examples\arm-cm\dpp_ek-tm4c123gxl\qspy, where <qpx> stands for QP/C or QP/C++ installation directory on your machine.

Your Customization Script

The easiest way to customize QSpyView is to copy the provided default.tcl script (or the dpp.tcl example), rename it, and add your own extensions.

When you open default.tcl, you will see that it consists of the following sections:

Adding Custom Commands

Custom commands can come in two forms: commands with and without user-supplied parameters. A command without parameter can be simply coded as a Tcl procedure, which will be attached to a menu item. A command requiring user-supplied input needs to be implemented as a dialog box. The qspyview.tcl script provides plenty of examples of such dialog boxes.

A command procedure typically will end with sending a packet to the Target or to the QSPY Back-End. The qspy.tcl script provides the procedure ::qspy::sendPkt for this purpose. Please refer to the example code (default.tcl or dpp.tcl) for examples of sending packets.

Additional Menu Options

Menu options can be added very simply. For example, the following line of Tcl adds the menu option "MyCommand" to the menu bar .mber.cust, which will call the procedure onMyCommand:

.mbar.cust add command -label "MyCommand" -command onMyCommand

Custom Canvas (HMI)

The Canvas view can provide a complete custom Human-Machine Interface (HMI) to your embedded Target. The Canvas can display the changing status of the application and also it can provide actuators to control the Target.

Custom Canvas for the DPP Application

The screen shot above shows the Canvas customization from the dpp.tcl script. Please note that the button in the center of the screen allows you to interact with the Target by sending commands to it. Please refer to this script code for the details of how various effects have been achieved.

Many Tk widget packages and libraries (e.g. BWidgets, IWidgets, etc.) are available to aid you in developing your custom canvas. With such widget libraries, you can display the data in an attractive form: as gauges, bars, graphs, and sliders. The attractiveness of the GUI is limited only by your creativity.

User Record Handlers

The User trace records are the application-specific trace records that are produced by your embedded application (as opposed to the QP framework). These trace records very likely require custom handling, because QSPY cannot really "know" what they represent.

The DPP project provides two examples of User trace records (PHILO_STAT and COMMAND_STAT, see bsp.c in the qpc\examples\arm-cm\dpp_ek-tm4c123gxl\qk directory). The following picture shows the structure of the PHILO_STAT trace record:

PHILO_STAT User trace record

As all trace records, user records start with the sequence number, followed by the record-ID. However, you should also known that all user records contain a time-stamp and that all data fields are preceded by a format-byte. This format byte helps QSPY to correctly display all data fields, but is really unnecessary for you, who knows the layout of the data.) As a concrete example, here is the complete User record handler for PHILO_STAT == QS_USER + 0 == 70:

1 # user record handlers [70..0x7C] --------------------------------------------
2 proc ::qspy::rec70 {} { ;# QS_USER
3  variable thePkt
4  variable theFmt
5  binary scan $thePkt xx$theFmt(tstamp)xcxa* \
6  tstamp philoNum stat
8  dispTxt [format "%010u Philo %1d is %s" $tstamp $philoNum $stat]
10  global thePhiloId
11  set img [string index $stat 0]
12  .canv.c itemconfigure [expr $thePhiloId + $philoNum] -image ::img::$img
13 }
  • line 2 The record-handler procedure is always starts with proc ::qspy::rec<num> {}, where <num> is the trace record number in decimal. The procedure takes no parameters.

  • line 3 The packet content is provided as variable $thePkt.

  • line 4 The formats of QSPY objects are provided as the (associative) array $theFmt. You will need the format of time-stamp to parse the User packet.

  • lines 5-6 The parsing of the packet is accomplished by the binary scan Tcl command. The meaning of the format fields is as follows: x skip sequence number, x skip record-ID, $theFmt(timestamp) extract the specified number of bytes and assign to the local variable tstamp, x skip the format byte, c extract a byte and assign to the local variable philoNum, x skip the format byte, a* extract a zero-terminated string and assign to local variable stat.

  • line 8 the dispTxt command (implemented in qspyview.tcl) displays the specified string in the text view.

  • line 12 the Canvas is updated with the new image of the "Philosopher", which reflects its current status. This accomplishes animation of the images on the Canvas.

Special Record Handlers

The custom script offers you an option to add your own customization for the special events, such as Reset of the Target and the arrival of the Target INFO. You can add your code inside the following procedures:

proc ::qspy::recRESET {} { ;# target reset callback
proc ::qspy::recINFO  {} { ;# target info callback

Standard Record Handlers

As mentioned before, the QSpyView Front-End receives all trace records produced by the Target. This includes all standard QS records (see QSpyRecords). All these record-handler procedures have the general form:

proc ::qspy::rec<num> {}

where <num> is a decimal trace record number in the range 1..69.

In order to parse the standard QS trace records, you could view the qspy.c implementation, where all the standard trace records are parsed and displayed to the screen.

Next: Revision History