On Sun, 2 May 2010 16:45:44 +0100 "Neil O'Brien"
<[email protected]> wrote:

> On Sun, May 02, 2010 at 20:56:36 +1000, Aaron Mason wrote:
> > On Sun, May 2, 2010 at 5:33 PM, Neil O'Brien
> > <[email protected]> wrote:
> > > On Sat, May 01, 2010 at 15:30:28 -0700, J.C. Roberts wrote:
> > >> >   status = tcsetattr(fd, TCSANOW, &options);
> > >>
> > >> How does it behave if you use "TCSAFLUSH" rather than "TCSANOW" ?
> > >
> > > I made that substitution and added a
> > > #define DEBUG 1
> > >
> > > The resulting binary sometimes fails to return and I then have to
> > > hit ctrl-c.  I've tried it several times, and not seen any
> > > (repeating) pattern in terms of when it works and when it fails.
> > >
> > Is the system running Linux running on the same type of board as
> > your OpenBSD system?  If not, try running Linux on a system
> > identical to the one you're using - see if it's the board causing
> > the problem.
> > 
> 
> Hi Aaron,
> 
> No, they are very different machines.  I don't have a spare ALIX
> system that I can load Linux onto for testing.  If I can't resolve it
> any other way I will switch my current machine to Linux; but having
> just got everything set up in OpenBSD, I'd like to avoid that if
> possible.
> 
> I have however tried the code in my initial email on a different
> OpenBSD machine (a Dell Optiplex Pentium II, dmesg is at
> http://www.tigerturnings.dyndns.dk/dmesg-dell)
> 
> In this case I used cua0, the onboard serial port, on an ns16550a
> controller.  Running the example from my initial post, with #define
> DEBUG 1 added and /dev/ttyU0 replaced by /dev/cua00, I get sporadic
> failures:
> 
> # time ./ex_obsd_now_cua0 ; sleep 3 ; time ./ex_obsd_now_cua0  
> Port has been opened and set up
> 1 bytes available, read: 6
>     0m0.12s real     0m0.00s user     0m0.00s system
> Port has been opened and set up
> ^C    0m7.00s real     0m0.00s user     0m0.00s system
> 
> If I replace TCSANOW with TCSAFLUSH on this machine, it doesn't help,
> though the instrument does sometimes send 21 (NAK) which I've never
> seen it do when using TCSANOW.
> 
> # time ./ex_obsd_flush_cua0           
> Port has been opened and set up
> 1 bytes available, read: 6
>     0m0.14s real     0m0.00s user     0m0.00s system
> # time ./ex_obsd_flush_cua0 
> Port has been opened and set up
> ^C    0m3.97s real     0m0.00s user     0m0.01s system
> 
> # time ./ex_obsd_flush_cua0 
> Port has been opened and set up
> ^C    0m3.65s real     0m0.00s user     0m0.00s system
> 
> # time ./ex_obsd_flush_cua0 
> Port has been opened and set up
> 1 bytes available, read: 21
> Expecting <ACK>, got 21
>     0m0.23s real     0m0.00s user     0m0.00s system
> 
> I think that this should rule out any problems with the USB-RS232
> converter or its drivers, and with the USB controller on the ALIX
> system.
> 
> I'd be grateful for any further ideas or suggestions.
> 
> -- Neil
> 

I should be able to figure this out, but my C language serial port
hacking skills are a bit rusty. These days, C is only used for
time-critical portions of instrument automation for test/mfg
environments, but for everything else, languages like perl, tcl or
custom/proprietary LabView executables are used.

Lots of instruments speak "skippy" (SCPI) otherwise known as Standard
Commands for Programmable Instruments. Your *UNNAMED* instrument might
speak a custom protocol as you claimed, or it might also speak "skippy"
either natively or with some configuration.

http://en.wikipedia.org/wiki/Standard_Commands_for_Programmable_Instrumentation

If your instrument can speak "skippy" then your life gets a whole lot
easier, so it's definitely worth checking. I'm not sure why you failed
to post the make and model number details of your instrument, but they
would be really helpful.

As I mentioned off list, TCSAFLUSH is often required, but more than
that, it's just good practice to flush the buffers to make sure you're
starting in a known state (e.g. no crap in the buffers).

Both your C code, and not understanding the behavior and output you
posted seems to indicate you followed one of the countless (poorly
written) how-to pages or books like:

http://www.easysw.com/~mike/serial/serial.html

The above has some good spots but it also has plenty of errors and
unfortunately, it is highly ranked by search engines. In your code you
seem to have inherited one of the mistakes, namely you think read(2)
gives you "bytes available" rather than "bytes read" as stated (twice)
in the read(2) man page.

    $ man 2 read
    ...
    Upon successful completion, read(), readv(), pread(), and preadv()
    return the number of bytes actually read and placed in the
    buffer.  The system guarantees to read the number of bytes requested
    if the descriptor references a normal file that has that many bytes
    left before the end-of- file, but in no other case.
    ...

The other problem is understanding what is happening. Unless you
specifically configured the descriptor to return immediately, your 
read(2) call will sleep until it gets the requested number of bytes from
the descriptor, until an interval timer expires, or until an error
occurs. Since the instrument is not sending you any data, it sleeps
until you lose your patience and hit CTL-C to end the program. --This
should not be a surprise. ;)

Whether or not you *want* read(2) to block until it gets data depends
on your instrument communicates and how you want to write your program.

Lastly, repeatedly sending the init string to the instrument without
power cycling it is bad juju. Most instruments are pretty stupid and
easily confused, but more importantly (yep you guessed it), you're not
starting from a known state. Of course, there also might be multiple
ways to initialize the instrument, and once initialized in a particular
way, the instrument might expect you to speak to it in a different way
(e.g. via scpi).

Speaking of bad juju, posting a private mail back onto the list is not
very polite. To *me* this doesn't look like an OpenBSD problem, so we
should take it off list rather than spam everyone subscribed with our
little adventure in "Serial Programming 101" ;)

        jcr

-- 
The OpenBSD Journal - http://www.undeadly.org

Reply via email to