Serial port, unix calls, some thoughts

John M McIntosh johnmci at smalltalkconsulting.com
Tue May 27 05:34:32 UTC 2003


Dan asked me to add a better degree of serial support to the mac os-x  
VM, and it seems one just uses the Unix calls for this, versus apple  
specific stuff.

Now in looking at this I was thinking here I've all these calls like
cfgetispeed, cfgetospeed, cfmakeraw, cfsetispeed, cfsetospeed, open,  
close, read, write, ioctl
tcdrain, tcFlow,t cFlush, tcgetattr, tcsetattr, tcsendbreak

So I was thinking, why not make the actual primitives really sparse to  
avoid C code that would require
support and VM changes, and then produce implementation specific  
subclasses like so?

SerialPortExtended
SerialPortExtendedUnix
SerialPortExtendedUnixOSX

Which deal with implementation issues.  Usually in the past we would  
code up a generic plugin routine, which calls
a platform specific routine, which then requires maintenance usually  
done by only a few VM maintainers hidden in the
sourceforge source tree, versus an easily accessible chunk of Smalltalk  
code.

So for example
SerialPortExtendedUnix >>cancel
	"tcflush does a cancel and zaps the pending inbound and outbound bytes"
	| error |
	error _ self primitiveSerialPortUnixTcflush: fd action: self tcioflush.
	error isZero ifFalse: [SerialPortExtendedError signal: error asString]

SerialPlugin>>primitiveSerialPortUnixTcflush: fd action: aNumber
	| error |
	self primitive: 'primitiveSerialPortUnixTcflush'
		parameters: #(SmallInteger SmallInteger).
	self cCode: 'error = tcflush(fd,aNumber); if (error == -1) error =  
errno' inSmalltalk: [error _ 1].
	^ error asSmallIntegerObj

Mmm in the past this might have been just a call to a generic flush,  
which calls the unix serial port code, which does
the tcflush(fd,TCIOFLUSH). Now if some squeaker really wanted to do a  
tcflush(fd,TCOFLUSH) instead then well it's
easy to add that method call and primitive hookup, even to make it an  
enhancement and lobby to get it into
the base image. However past thinking would require a VM change, by the  
powers that be, or by managing your own personal VM.

{I'll note that I do capture errno in the C code, versus looking for it  
in the smalltalk, however my concern is that
going to get errno after the fact might return zero because someother  
unix call(s) could be made before our
process thread could retrieve it.}

On the downside, if for example your termios structure is different  
that the OSX one why then you need a
different subclass of the basetermios class which allows you to  
put/extract bytes/ints from the structure.
Normally that  problem would be hidden away in the C code and your  
platform specific vm would deal with the issues, so all is not happy.

Another example would be CTS/DTR control by exposing SerHShake for os9,  
and ioctl for os-x/unix.
which then exposes all sorts of other support so if someone really  
wants to see TIOCM_CAR then they
can without having someone build a new vm.

In some respects this begs the question about using FFI more since once  
could do a lot more with FFI.

For the open,close,read,write,ioctl calls, any thoughts on where they  
should go? They aren't serial port
specific, do we have a lightweight unix plugin we can hide them in?


PS as another example consider <primitive: 'primitiveFileRead' module:  
'FilePlugin'>
it really resolves after some time into a call to fread. But doesn't  
return or check ferror(). So on an I/O
error by the time things migrate up to smalltalk objects one can't  
discover why the error occurred. If that was a sparse
method call, someone might have gotten motivated and posted a changeset  
to call ferror()? in the non-existent
StandardFileStreamUnix class when they discovered fread returned zero.

So thoughts?

--
======================================================================== 
===
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
======================================================================== 
===



More information about the Squeak-dev mailing list