Speed
Kills
Copyright 1990,
Jack G. Ganssle
Abstract
Data comm over
cheap serial links might be more cost effective than other, faster, options.
Published in
Embedded Systems Programming, August 1990
I warned Tyler
Sperry, this magazine's Editor, that my column will occasionally address issues
that cross the border between software and
hardware. Ours is truly an interdisciplinary business. Often the line between
the software and hardware is a bit blurred, since in many
cases code replaces those functions traditionally assigned to hunks of metal
and silicon.
Data communications
is one of the stickiest thorns of this industry. Even in simple embedded systems
a lot of data moves between the
processor and each I/O device. Factory automation equipment might resemble
a complex nervous system, with dozens or hundreds of remote
sensors communicating with a central controller over synapses of cable or
optical fiber. These communications links absolutely must be
optimized to reduce costs (copper wire is expensive!) and improve reliability.
Simple, brute force approaches to moving data around are no
longer adequate.
Every office
now relies on a LAN. Serial networks of one form or another are starting to
permeate the embedded data communications world.
While for decades serial has been used as a point-to-point link (like from
one terminal to a mainframe), now smart links can handle
commands and data to and from lots of peripherals, all on one set of wires.
Consider modern
automobiles: long before the end of this decade most cars will be networks
of dozens of CPUs. Every simple function will
be assigned its own processor. The driving force behind this is not so much
to improve performance or to add features, but simply to save
the weight of the wiring! A serial communication link uses one pair of wires
to replace the ratsnest of cabling that pervades most cars.
I worked as a
consultant for several years. What a miserable job! Customers could just never
bring themselves to accept the expert advice
they paid us dearly for. Data communications was always one of the biggest
issues. My partner and I designed a new security system for the
White House during Reagan's first term. Dozens of identical 8085-based chassis
were to be connected to a remote mainframe computer. The
low data rates made serial the natural solution. Too high tech - the Secret
Service demanded a massively parallel bus consisting of several hundred wires
per chassis! Over a thousand large connectors were involved, creating a reliability
nightmare. Your tax dollars at work.
In another case,
we installed a large thickness measuring system in a Baltimore steel plant.
Quite a few 12 bit encoders were located up
to 1000 feet from the central computer (a pair of PDP-11s). We tried, oh how
we tried, to convince the customer to connect each encoder
with a single optical fiber pumping serial data. No luck. They were simply
afraid of the technology, and refused to even consider putting
an 8051 at each encoder site. We were forced to bring the data back in parallel,
installing a dozen differential line driver chips at each
encoder, transmitting the data over fantastically expensive inch-thick cables.
Fear of the unknown is a horrible thing.
Microprocessor
technology has changed the economics of design. Silicon is a lot cheaper than
copper. Transmitting data over long distances
on bundles of wire is almost always much more expensive than multiplexing
the same data onto a single wire or fiber. Multiconductor copper
wire (especially armored for factory environments) can cost over a dollar
a foot. The savings in copper will justify a one-chip micro that
converts parallel signals to one serial channel in most applications. A lot
more money is saved by connecting all of the remote devices on
the same serial cable, saving the cost of running a separate wire from each
sensor all the way back to the central computer.
Conceptually,
a multidrop serial link is quite simple. Every node (peripheral or computer)
is assigned a unique address. The remote device
ignores all transfers unless specifically addressed by a central controller,
in which case it gets sole access to the link. There are
hundreds of variations on this theme, all targeted at reducing cabling costs.
Signetics recognized
the problem some time ago. Even in situations where data is to be transferred
only a few inches (say from a CPU to a
peripheral chip on the same boa`d), the conventional parallel computer bus
is inefficient. A lot of CPU and peripheral chip pins must be
dedicated to the unglamorous task of communication. Pins are valuable - it's
much better to allocate them to useful functions like extra
I/O. If speed is not a problem, why not transfer data via a simple serial
protocol?
I**2 C is a serial
bus that communicates to any number of peripherals using only two wires. One
carries a clock signal that sequences the
timing of bits on the other line - the data wire. The clock indicates when
each data bit is stable, and is used to indicate special
conditions like data start and stop. This contrasts with RS-232 and other
common data transmission standards, where the data is self
clocking. In RS-232, given a known baud rate, data bits follow the start bit
in an exact time sequence. By adding a distinct clock line,
all communications become speed independent. The current bus master supplies
the clock that all other devices can synchronize to.
I**2 C also differs
from RS-232 in its signal levels. It was really designed for very short range
(on a PC board) communication, so
typically uses MOS levels. However, it's not hard to buffer the signals and
increase the communications range substantially.
I**2 C doesn't
force one controller to be the perpetual bus master. Any device can assume
control of the bus, so multiple processors can
be attached. An arbitration scheme resolves conflicts between simultaneous
requests for control of the bus.
For the purpose
of controller communications, probably the best advantage of I**2 C over RS-232
is its well defined protocol. RS-232 just
shoots data between two fixed devices - each had better know what proprietary
protocol, if any, is being used. I**2 C supports an
addressing scheme, so when many different devices are connected to the same
two wires a particular unit can be selected. Once a connection
is established between a device and the current bus master, then data is transferred
in precisely measured blocks; after the last block
another master can gain control of the bus. Thus, like IEEE-488 or SCSI, any
device that understands the communication protocol can be
connected to the I**2 C interface. Unlike SCSI, the communications protocol
is fairly simple, so real systems are pretty easy to
implement.
Refer to Signetics'
Microcontroller handbook for a good description of the I**2 C bus.
I**2 C supports
data rate up to 100 kbps. Need more speed? Last year Gazelle Microcircuits
(Santa Clara, CA) introduced a chip set called
(of course) the "Hot Rod" that communicates serially at
up to 1 billion bits/second. To get this sort of speed they employ a
gallium-arsenide (instead of silicon) substrate, the same exotic technology
that will soon bring us the Cray 3.
The Hot Rod differs
from I**2 C in that it is for point to point communication only. In other
words, there is no bus - the Hot Rod is a
dedicated chip set that connects two devices, and only two devices. The Hot
Rod is also a bit simpler to use, in that no programming is
needed. A transmitter chip takes a 40 bit parallel bus and converts it to
serial, transmitting it over coax or fiber optics to the
receiver chip where it is reconstituted into the original 40 bit parallel
bus. Sounds vaguely like Star Trek's transporter...
Why not carry
this a step further? After all, the Hot Rod can move data at tremendous rates
- suppose you could replace the massive (and
expensive) PC motherboard connectors with a simple two wire serial link? In
a way, this is the idea behind Apple's serial interface on the
Macintosh. Tie external devices to the main computer with a simple serial
cable that clocks fairly high speed data.
Gazelle's approach
is targeted at very high speed applications; the I**2 C bus is currently limited
to products from Signetics. The rest
of us can still take advantage of these de facto standards. I**2 C is particularly
well suited to smaller embedded systems, since it could
be implemented in an ASIC or even a PLD device with little trouble. Modern
high integration processors (like the 64180) have lots of
serial on board (including fast clocked channels) - perhaps it would be not
too difficult to kludge up an I**2 C interface using these
resources.
Since I**2 C
is speed-independent, ultra cheap systems can even use a processor's parallel
bits and lots of code to simulate a slow
version of I**2 C, although it will eat lots of CPU time. Look at Intel's
"Serial Interfacing on the 8085" application note for
more information about simulating serial this way. The Code
Serial does pose
some interesting software design problems. With traditional parallel I/O,
to get the setting of a switch you just read
the bit. This isn't so easy if the switch is located remotely and its value
communicated over a serial link.
One common approach
is to send a request for data as needed. This keeps the software simple, but
does mean that the controller will often
be kept waiting. Another method is to let the external peripherals transmit
current data at regular intervals. Perhaps remote sensor A
sends it's data ever 100 milliseconds. Then, the controller can consult its
current memory image of sensor A's last transmitted state.
An even better
approach is to program the remotes to transmit only when their data changes.
In the case of switches this will result in a
dramatic reduction in transmissions. If the data changes quickly (say from
a fast encoder) consider using the same technique found in a
mouse or trackball - send frequent bursts of data, with each transmission
containing a measure of the sensor's change from the last burst.
By all means
code the serial receive routine to be interrupt driven. Polled UART I/O will
bring the system to crawl. This does create yet
another problem - when is a block completely transferred? You can't let the
code work with incomplete transmissions.
If speed is not
an issue a low level interrupt service routine can copy entire blocks, when
received, to a stable buffer that (implicitly)
always contains correct data. Be sure to do this with interrupts disabled!
A somewhat better approach is to employ double buffers with
semaphores indicating which one contains valid data; the interrupt service
routine fills one and the code uses the other. Be sure to
isolate the data structures from your code with a driver routine, since every
data access will involve a semaphore test. Smart programmers
have used these object oriented techniques long before the fancy moniker was
invented.
Novices always
get burned by a common trait of UARTs. Receiving is easy: read the data when
the "receive data ready" interrupt
occurs - this clears the interrupt. Transmitting isn't quite as straightforward.
After the UART sends a byte it will assert a
"transmit data buffer empty" interrupt, which will stay
asserted until another byte is transmitted. If you don't mask off the
interrupt until you're ready to transmit again, then you'll get an infinite
stream of these interrupts. Be warned. Summary
When designing
a system look carefully at all remote data collection devices. Can you save
money by using serial communications? Sure, the
software will be a bit more complicated, but cabling costs go down, reliability
goes up, and, if optical fiber is used, noise immunity
skyrockets. Engineers often eschew serial due to the time it takes to multiplex
data onto the link. By all means, if speed is truly an
issue then use whatever means are needed to get it. You'll pay a heavy penalty
for it. Remember the old adage - speed kills.
A lot of embedded
work is undertaken by old smokestack industries trying to use modern controllers
to improve produtivity and cut costs.
These companies, the employers of many of this magazine's readers, really
don't understand software. When a new project is contemplated,
they huddle with hardware engineers, leaving software people out of the initial
system's specification phase. What a disaster!
All too often,
we software people abdicate our roles as expert advisors during a system's
initial design. Hardware guys frequently design
their little gems with little or no input from us, when we can help them with
the software tradeoffs that will yeild a better design. It's
important to get involved with all aspects of a project, to produce a product
that is more saleable, more reliable, and more elegant.