I hastily cobbled together a program, in MzScheme / MrEd, to receive bytes on a serial port and display the values and the status bits they represent.
It runs fine on Linux.
On Windows (XP, SP2, all the latest patches), it appeared to be waking up and basically doing what I expected.
At the client site, for the first test with actual data coming in on the serial port (and with a somewhat older version of Windows, I think), it promptly aborted with an EOF on the serial port. Eh?
Fortunately, the Linux version was working, so I left them with that for the moment.
Back at home, and off the client's nickel, I decided to play with the Windows com-port thing. By this time, I'd advanced (on the Linux side) to opening the port with
(define-values (inport outport)
(open-input-output-file portname 'binary 'update))
for future applications in which there might be bidirectional communication. Seems to work fine on Linux, but then so would just opening the port once for input and once for output.
On Windows? Oops. The first (as far as I can tell) time I try (read-bytes 1 inport), the whole freakin' Scheme interpreter gets wedged, and takes several iterations of "End now" to make it stop.
Opening the port twice doesn't work on Windows, because opening a port gets exclusive access, even from yourself.
Interestingly, the Scheme interpreter also sometimes gets wedged when I open the port only for input, though at least it doesn't do so instantly the way it does when there are both input and output ports opened.
It's not a right-now-urgent kind of thing, but I figure someday I'll want to communicate both ways over a serial port, and to deliver the program to a Windows-only client.
Another thing to try to sort out in background mode, and try to figure out whose bug it is....
Further: Task Manager reports DrScheme using 0% CPU time in its wedged state. This makes sense, if it's wedged waiting for a character to arrive on the serial port. On the other hand, since it's doing the read in a background task, the foreground ought to be alive, and it isn't.
Update: By George, I think I've got it! Using open-input-output-file appears to be mandatory for serial ports under Windows; otherwise you get nothing but EOFs. Reading the input side of a pair will also return EOF most of the time, even if you'd just issued a MODE command that turned timeouts off. On receiving the EOF, it's necessary to sleep/yield for some fraction of a second and try again. This appears to do what I want.
(define (read-serial-port n p)
(let ((c (read-bytes n p)
))
(if (eof-object? c)
(begin
(sleep/yield 0.01)
(read-serial-port n p)
)
c
)))
"If it were easy, it wouldn't be Windows, would it?"
Update, later: Nope, that doesn't work on the client's machine. Now it doesn't work on my lab machine, either, following the Patch Tuesday reboot. In fact, the read-bytes appears to be blocking rather than returning EOF for a non-ready port... and, while it's blocked, the Scheme interpreter is completely wedged. Blocking is fine; blocking is what I expect... but for the interpreter to get wedged is just not useful.
This kind of thing is so simple under UN*X!
Comments