top of page

Programming a device with Tcl

Here we have to change our approach as Impact does not have a Tcl interface. However, this does allow us to explore another way of controlling applications. Impact has the ability to run a script file that consists of a series of commands. These are not Tcl commands, but we can use Tcl to construct this file. We can then run Impact from with the Tcl script. Let's see how.
First we need to open a file that will become the Impact script. We do this with the open command:

if {[catch {set f_id [open $impact_script_filename w]} msg]} {
  puts "Can't create $impact_script_filename"
  puts $msg

What's going on here? The open command returns a handle to the file which we put in the variable "f_id". If open fails it would stop the script; this is probably the best thing to do here, but in general you may want to trap errors and continue with other things. That's what catch can do; it will return a non-zero error code if the command it runs (in this case the open) fails, and it places any error message from that command in the variable that here we have called "msg". Hence, if the open fails $msg will contain the reason why.
How do we write text to the file? With the puts command. Earlier we used it to write text to the console, but here we see an addition:

puts $f_id "addDevice -position 1 -file $bit_filename"

Well, it's not really an addition: the default destination of a puts command is the standard output, so if we leave off the second argument then STOUT is where the output goes. The line above uses a second argument, so the text is written to the file given by $f_id instead. After we have written the required command to the Impact script we should close the file.
Now we have to start Impact. There are several ways of calling external programs from Tcl; the easiest is to use the exec command, which runs the external program, waits for it to finish and returns all its output. This is acceptable for quick programs but not for anything more complicated, as you cannot direct any input to the program or control it while it is running. More flexibility is provided by using open, but this time as a pipe from the program:

set impact_p [open "|impact -batch $impact_script_filename" r]

This line starts Impact with the script, and returns its output to the variable "impact_p". The benefit of using the pipe is that we can now watch the STDOUT of the tool from within our Tcl script:

while {![eof $impact_p]} { gets $impact_p line ; puts $line }

This code writes each line of Impact's output to the Tcl script's own standard output. The command eof returns true when the external program finishes. This approach will not work if the external program requires some interaction because that program will not tell you when it requires some input. In our case, however, this is fine, because we want the Impact script to run until completion.

bottom of page