[Coco] drivewire serial port protocol - RFC
Aaron Wolfe
aawolfe at gmail.com
Fri Nov 13 23:56:16 EST 2009
Progress continues on the drivewire serial support additions. As I
make the driver more robust (getstat/setstat support, signals, etc) I
think I'll need to implement a way to communicate some port status
from the server side to the driver. At a bare minimum, I think the
coco should be able to initialize and term the PTY, rather than the
way it works now where you must do the server side manually. It would
be nice to support or emulate rs232 controls from host to coco
(DCD,DSR,RTS/CTS, Ring, etc). There may need to be support for out of
band data in order to implement a nice terminal interface, not sure on
this one yet.
I've also started to look at tuning for performance. 115,200bps is
really fast. I haven't done good tests yet on how fast data the Coco
can digest and get data into a terminal program or rzsz for example,
but getting the data into the driver's buffer at least is very, very
quick. I can quite easily fill the buffer more quickly than the
coco's console can print it out, that's about as far as I've gone in
actually processing it.
On the other hand, an interactive terminal session barely makes a
dent. I have to copy and paste data into the terminal program to even
trigger the READM operation (this op happens when more than 1 byte
exists in the server's input buffer). There's no need for a large
buffer on either side for these.
As I started laying out bits and bytes for the getstat and setstat
ops, I had some left over.. and that got me thinking.. why have only
one port? The poller has to run pretty often to provide decent
latency in interactive sessions, whether you've got one terminal user
or 10 doesn't make much difference.
It would be kind of cool to have a handful of OS-9 shells running in
different windows on my PC. I can see how having one port for
data/modem/internet things and another for an interactive shell could
be nice. A multiline OS-9 BBS would be easy to support (if software
for this exists.. I'm not very familiar with what is available under
OS-9)
Anyway, all of this brings me to defining a proper spec that at least
supports doing rs232 status, performance tuning based on application,
and possibly multiple virtual serial ports, 7 seem to fit nicely
without causing any extra bytes in most calls. Here's what I'm
thinking now, I would greatly appreciate ideas, comments and
criticism. Maybe I've gone off the deep end here, I'm open to that
possibility.
The port(s) can be in one of two modes:
Interactive mode - SCF features enabled, 18 byte buffer = 126 bytes
for 7 ports
Data stream mode - Pure pass through mode, no SCF signals. 1024
byte buffer.. max 1 port in data mode? (1024 bytes because at
115.2k, 1440 bytes could be transferred in 0.1 seconds, the current
polling interval. giving some time for overhead, 1K seemed nice. its
really just a guess at this point, the idea would be to maximize
throughput in any case. in a 512k machine I think 1k used for buffer
would be acceptable, if the coco can digest the data fast enough to
matter.)
Add get and set status OPs, change SERREAD,M, and WRITE to support
multiport(?). May want a WRITEM also, not sure
SERREAD (this is the poller, occurs 10 times per second currently but
can certainly change)
1 byte command (just the opcode)
2 byte response:
byte 1: first bit indicates the server thinks the client should do
a GETSTAT on highest priority port with data, 7 bits indicate which of
the seven ports have data in buffer, priority is just order of bits.
all 0 means nobody has anything waiting. The OS-9 driver can make
decisions based on which ports have data waiting, such as sending a
second SERREAD during this interrupt, etc.
byte 2: data byte for highest priority port that has data
This would allow SERREAD to perform exactly as it does now if only one
port is active, and I think it would perform well for multiple
interactive users too, without adding any bytes to the operation.
Since a vast majority of interactive sessions would never cause a
READM, it's basically equivalent there.
Since we are not returning the buffer size in the SERREAD, as it does
now, it means an additional call (GETSTAT). However, we'd have to use
some additional bytes to properly support a single port anyway (rs232
status bits, and the buffer size response needs to be bigger than 1
byte when in data stream mode).
So, when the server tells the driver it should do a GETSTAT, the
client should normally obey. The server could decide to mask the fact
that higher priority ports have data waiting when time critical status
changes occur on a lower priority port (ring indicator, port closed on
server side... probably would not really implement true DCD,RTS etc
but could simulate the effect to some degree). The basic idea would
be to have the server make suggestions to the client, since it has
more resources for figuring things out. The SERREAD response can tell
the driver: hey, you should really look at port X. There is no
requirement for the client to obey, everything is completely async/no
state etc.
SERGETSTAT - inquire port status,
2 byte command
op code
argument byte = 3 bits for port #, have lots of room for other
things, possibly a code for system status request?
2 byte response
waiting data size for requested port.. if max buf is 1024, 6
bits left for RI, DCD, CTS, mode (data/interactive), etc
? system status
0, seven bits for which ports are initialized
1, seven bits for port mode (data/interactive)
The driver can now take appropriate action, often to call SERREADM if
the port is in data mode. This scheme does add an extra exchange
between client/server for each block read. not sure if this matters,
some of the bytes are unavoidable although in a single port design the
second exchange could be eliminated.
SERSETSTAT - Open, close, change mode of a port
2 byte command
op code
5 bits
mode (interactive/stream)
RTS/CTS
DCD/DSR
etc
3 bits port selector, 7 = all?
1 byte response = echo arg byte back = confirmation, some
unlikely/impossible set of bits + remaining could indicate failure and
reason
setting the port to its exact current status could indicate a termination
Finally, SERREADM's arguments have to be extended to accomodate values
larger than 255 anyway, so the extra 3 bits for port select cost
nothing.
SERREADM
2 byte command
opcode
3 bits port #, msb,lsb amount (max 1024)
response = data bytes
Well, that's my idea for now..
-Aaron
More information about the Coco
mailing list