UNICAT logo XOR-UNI
A University - National laboratory - Industry Collaborative Access Team at the Advanced Photon Source now operated by APS X-Ray Operations & Research (XOR)
Advanced Photon Source at Argonne National Laboratory
Scientific Programs    Instruments   Forms & Schedules  Photos   Controls 
Argonne Home > Advanced Photon Source > UNICAT >

Table of Contents

Serial Port Console Log

by Pete R. Jemian, UNICAT 
last updated: 26 June 1998  
For questions about this URL, send mail to jemian@anl.gov 

Table of Contents

Description

Some computer systems provide diagnostic output on a dedicated console (RS-232) port.  When used in an embedded system, these computers often do not have a display to show these messages.  It is sometimes desirable to log any information from these console ports to a file for later examination.

The serial port console log script was designed to record ASCII text input from a serial port on a UNIX workstation.  It has been tested on SunOS 4.1.4, Solaris 2.5.1, Linux Slackware v2, and RedHat Linux v5.0.  The input is (presumably) from a console port of some other computer (such as VxWorks) connected via an RS-232 connection.

The script can be run either as a foreground or background task and writes its output to stdout.

Requirements

These scripts were designed to run only on a UNIX workstation.

Access to the serial ports of a UNIX workstation is often restricted to the root account.  You will probably need to assign the read/write permission to the serial ports to make effective use of these scripts.  For example, have your system administrator issue the command:

unix prompt> chmod 666 /dev/ttya

Also, you'll need the expect language which relies on having the Tcl language installed.  See below for these details.  Check the expect home page (see below) to see if the most recent version is compatible with Tcl 8 yet.  Otherwise, you'll need Tcl v7.6.

Installation

Be sure that you have met all the system requirements above.  Especially, make sure you have expect installed (this means you will also have Tcl installed).

Copy the source code below (using cut and paste from your WWW browser) into a directory on your executable path.  Name the file serialWatch.exp.  Give the file executable permissions with the UNIX command.

unix prompt> chmod +x serialWatch.exp

As long as you execute serialWatch.exp from a directory where expect is on the executable path, then the first four lines should automagically find expect and start the console port logger.  Otherwise, remove the first four lines of the script (script should begin with "#!/usr/local..." line) and replace "/usr/local/bin/expect" with the full path to the expect executable.

If you wish to log serial port data to a common directory (such as shown in example 3 below) then you'll need to create that directory, as well.

To change the serial port parameters, you'll need to edit the script a little more.  Look at the line that reads "set baud 9600" and the few lines afterward.  Consult the UNIX man page for "stty" and make proper adjustments.
 

Serial Port Console Log Script source code (written in Expect)

Here is the complete expect script necessary to log text that comes in on one of the serial ports.  It assumes that the text is terminated by a new line (\n) character for each line.  Each line is then time-stamped and written out to a file.

#! /bin/sh
# the next line restarts using expect \
exec expect $0 ${1+"$@"}

#!/usr/local/bin/expect -f
#
# serialWatch.exp
#   Connect up to a device on a serial port
#   Time stamp any incoming lines to stdout

       # port is any serial port (omit the /dev/ prefix)
       # e.g. ttya, cua0, serialA, serialB, boca01 - boca16

if {$argc != 1} {
  puts "$argc, $argv"
  puts "usage: serial.exp port"
  exit
}

proc timeStamp {} {
  global tcl_version
  if {$tcl_version >= 7.5} {
    # "clock" command requires Tcl v7.5 or greater
    # internal routine a little faster than making a system call
    set stamp [clock format [clock seconds] -format %Y-%m-%d,%T]
  } else {
    # fall back to standard UNIX system call
    set stamp [exec /bin/date +%Y-%m-%d,%T]
  }
  return $stamp
}

puts "\n[timeStamp] Log starting..."
set port /dev/$argv
set spawned [spawn -open [open $port w+]]
puts "[timeStamp]: [string trim $spawned \r\n]"
set baud 9600
    # -parenb means don't use a parity bit
    # -cstopb means "not 2 stop bits, but 1"
    # cs8 means 8 bits
    # -echo means no echo (full duplex?)
stty ispeed $baud ospeed $baud raw -echo cs8 -parenb -cstopb onlcr < $port
log_user 0

# log each input line
#  add a timeStamp at the beginning of each line
while {1} {
  expect "\n" {
    puts "[timeStamp]: [string trim $expect_out(buffer) \r\n]"
  }
}
 

Examples

1 Simple example

Here is an example script to start logging a serial port.  Output will appear on stdout (usually your screen).

unix prompt> serialWatch.exp ttya

You should see output that looks like

1998-06-26,11:51:15 Log starting...
spawn [open ...]
1998-06-26,11:51:15: 0

As more information comes in, you will see lines that look like
1998-06-22,13:26:35: ldpp < bin/hideosLib
1998-06-22,13:26:39: value = 7467180 = 0x71f0ac
1998-06-22,13:26:39: #bpLoad 1, "bin/xfd_app"
1998-06-22,13:26:39: hideos_main
1998-06-22,13:26:39: Hideos welcomes you
1998-06-22,13:26:39: hideosDebug=005d0aec

Each line is time-stamped and has the complete information received since the previous \n character.

You can stop this simple example by typing Control-C (^C).

2 Directing output to a file

Continuing from example 1, stdout can be redirected to a file and the logger will be run in the background.

unix prompt> serialWatch.exp ttya >>& ttya.log &
[1] 15268

The process ID number (PID) of the background process is 15268.

Stopping this example is a bit more difficult.  First you must find out the UNIX process ID number (pid), then kill the process.  Here's how that would look.

unix prompt> ps
  PID TTY STAT  TIME COMMAND
12466  p0 S     0:00 -tcsh
15131  p0 R     0:00 ps
24267  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp ttya
unix prompt> kill 24267
 

3 UNICAT VxWorks Console Logs

Here is another example script to start logging several serial ports.  In this case, the serial ports are named /dev/boca01, /dev/boca02, ... /dev/boca16.  These ports have been added to a Linux-based PC using the BocaBoard BB2016 16-port serial expander.  The output goes into a specific subdirectory.  The data coming in on the serial ports are from the console ports of several VxWorks computers.  This is a script I call start-logs, which has UNIX permissions of 775.

#!/bin/csh
#
# start-logs

setenv BIN /usr/local/unicat/bin
setenv LOG /usr/local/unicat/logs/serial

$BIN/serialWatch.exp boca01 >>& $LOG/bwi_vxworks.log &
$BIN/serialWatch.exp boca02 >>& $LOG/iad_vxworks.log &
$BIN/serialWatch.exp boca05 >>& $LOG/jfk_vxworks.log &
$BIN/serialWatch.exp boca07 >>& $LOG/sfo_vxworks.log &
$BIN/serialWatch.exp boca08 >>& $LOG/lax_vxworks.log &

#$BIN/serialWatch.exp boca04 >>& $LOG/iad_aim.log &
#$BIN/serialWatch.exp boca06 >>& $LOG/jfk_aim.log &
 

Stopping this example is very much the same as for example 2.  First find the PIDs for the processes and then kill each PID.

unix prompt> ps
  PID TTY STAT  TIME COMMAND
12466  p0 S     0:00 -tcsh
15131  p0 R     0:00 ps
31198  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp boca01
31199  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp boca02
31200  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp boca05
31201  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp boca07
31202  ?  S     0:00 expect /usr/local/unicat/bin/serialWatch.exp boca08
unix prompt> kill 31198 31199 31200 31201 31202


To-do

  • Devise a better way to stop processes running in the background.  The drawback to doing this is that what works now is not all that bad.
  • Set a timeout on incomplete lines of incoming data so that devices which don't send a trailing \n (such as "\nThis is my next text string") can be logged in the file in a more timely fashion.
  • Port these scripts to other machines such as WinXX. Contingent on expect running on that platform.
  • Make configuring serial port parameters easier.  As-written, the script only handles one serial port configuration.
  • Check compatibility with Tcl v8. Is expect up to date?

Other links

Here are some links to other interesting sites that may be related to this page.
link description
http://expect.nist.gov/ Expect home page
http://expect.nist.gov/expect.tar.gz latest expect source code
http://www.scriptics.com Current home of new Tcl/Tk distributions
http://sunscript.sun.com Sun's home page for Tcl/Tk (updates ended 17 April 1998)
http://www.neosoft.com One of the many good sites for Tcl/Tk code
ftp://ftp.scriptics.com/pub/tcl/tcl7_6/tcl7.6p2.tar.gz Tcl 7.6 source code
ftp://ftp.scriptics.com/pub/tcl/tcl7_6/tk4.2p2.tar.gz Tk 4.2 source code (not needed by these scripts)
ftp://ftp.scriptics.com/pub/tcl/tcl8_0 Tcl 8.0 source code directory
 
 

For questions about this URL, send mail to jemian@anl.gov


University of Illinois at Urbana-Champaign    Oak Ridge National Laboratory    UOP, LLC    National Institute of Standards and Technology
Privacy & Security Notice  |   Contact Us | Phonebook    
This page last modified: 2005-05-18 3:14 PM