apache tcl cgi script with serial port access

by Theo Verelst

I used this test script to drive a serially connected xilinx chip using a apache (2.0 Fedora Core4,64bit) and get 4 bytes of info back from it, it serves as a display and external signal reader/driver.

Basically, its just a cgi program which happens to be a tclsh script:

 # \
 exec tclsh "$0" "$@"

  # must supply meta type
  puts stdout "Content-type: text/html\n"
  puts stdout "<HTML>"
  puts stdout "<HEAD>"
  puts stdout "<TITLE>Test CGI Tcl script</TITLE>"
  puts stdout "</HEAD>"
  puts stdout "<BODY>"
  puts stdout "Test.\n"

  # open and set up serial port connection
  # possibly use chmod a+rw on it, because this script will be not root
  set fh [open /dev/ttyS0 RDWR]
  # the xilinx demo board I've programmed to have 10kB/s serial connection
  fconfigure $fh -blocking 0 -mode 115200,n,8,1 -translation binary -buffering full
  # put the responses from the board on the page when they come in
  fileevent $fh readable {
    set w [read $fh] ;
    foreach c [split $w {}] {
       binary scan $c H* a; set v $a
       # print in HEX
       puts " $v"
       # flush stdout

  # write a number of bytes to seriap port in binary from from a hex string
  proc w h {
    global fh
    puts -nonewline $fh [binary format H* "$h"] ; flush $fh

  # if any arguments are given to the url, print them
  puts "<P>\n"
  puts "$env(QUERY_STRING)\n<br>\n"

  # send a in this case fixed 4 bytes to the FPGA, which turn on the display here
  w 00000000
  after 1000
  # and another 4 byte data to turn it off
  w 40000000

  puts "</BODY>"
  puts "<HTML>"
  flush stdout

  # make the cgi end after a second
  after 1000 exit
  # meanwhile read the returning data bytes
  while {1} {
    flush $fh
    vwait v

 # should never be needed

The board:

I'll make the fpga programming file available when I've time, it can set leds, 4 led displays and read switches and communicate at least a 100 or so external signals using the spartan-3.

To run the script, put it in /var/www/cgi-bin/test.tcl or where youre apache's cgis are supposed to go, don't forget to make it readable by the servers' uid, and use this url to make it run: http://yourhost/cgi-bin/test.tcl

In my case:


assuming the setup is unchanged when you read this. Getting this url will flash the display on the board a few seconds and return the 8 switches setting as one byte of data, example output:


 00 52 15 00 40 52 15 00 

If anyone's got a good idea they want with this setup, send me a mail, I might make it for them, I'll have some of my own and its a good example. In fact the MSB of the first databyte can put a 20 watt ligthbulb on and off.

Depending on server load, the seconds delay is probably a gross exageration to get all the data back. If you don't need the serial port stuff, strip everything exept the puts commands. One can consider it an excercise to the reader to deal with the case of access conflict on a busy server for this page when two accesses to the serial port happen at the same time, opening the serial port should fail for all but one.

See Also : Bwise, a serial port tcl script and a Xilinx demo board