Addendum to SUMMARY: Sending break on serial port

From: Mike Galuza (mgaluza@dejarnette.com)
Date: Thu Aug 21 1997 - 11:24:04 CDT


Apparently there is some confusion as to how tcsendbreak() really
works (or at least how the duration parameter works). In reply to
my summary Casper Dik wrote:

> I think you've misread the manual page.
>
> If the terminal is using asynchronous serial data transmis-
> sion, tcsendbreak() will cause transmission of a continuous
> stream of zero-valued bits for a specific duration. If
> duration is 0, it will cause transmission of zero-valued
> bits for at least 0.25 seconds, and not more than 0.5
> seconds. If duration is not 0, it behaves in a way similar
> to tcdrain(3).
>
>
> I read this to mean as: if duration != 0, then we'll send a break that
> long and wait for teh output to be drained.
>
> (Tcsendbreak really is ioctl(fd, TCSBRK, duration))
>
>
> It's upto the serial device driver to correctly implement this.
>

Well I don't think I did misread the man page. If duration is 0 the
break lasts .25 to .5 secs. If it is not 0, tcsendbreak() behaves
like tcdrain(), it does NOT send a break for duration seconds AND
behave like tcdrain(). (For an implementation that DOES work that
way see SunOS 4.1.3 man pages for tcsendbreak()). Some experimentation
I've done backs up this claim. I tried the following code:

      clock_gettime(CLOCK_REALTIME, &begt);
      ttime = 0.0;
      while (ttime < 1.5) {
         if (tcsendbreak(dp->fd, 0) != 0){
            imlog(2, "Failed to send break, errno = %d\n", errno);
            dp->fd = -1;
            break;
         }
         clock_gettime(CLOCK_REALTIME, &endt);
         ttime = endt.tv_sec - begt.tv_sec +
                 ((endt.tv_nsec - begt.tv_nsec) / 1000000000.0);
         printf("ttime = %.2f\n", ttime);
      }

and got the following result:

ttime = 0.0
ttime = 0.25
ttime = 0.50
ttime = 0.75
ttime = 1.00
ttime = 1.25
ttime = 1.50

Apparently there is a mutex in the driver that holds off subsequent calls to
tcsendbreak() from executing until the previous one is finished. As you can
see, tcsendbreak() behaves as advertised in this case. Well, when I tried a
duration of 2000 the behavior was much different:

ttime = 0.0
ttime = 0.0
ttime = 0.0
ttime = 0.0
ttime = 0.0
ttime = 0.0
ttime = 0.01
ttime = 0.01
ttime = 0.01
ttime = 0.01
ttime = 0.01
ttime = 0.01
.
.
etc.
.
.
ttime = 1.50
ttime = 1.50
ttime = 1.50
ttime = 1.50
ttime = 1.50
ttime = 1.50

So obviously the break is not lasting 2000 seconds (or msecs, or
whatever the units of duration are). That is another thing in favor
of my interpretation of the man page: If duration had a meaningful
value other than 0, wouldn't the man page explain the units of
duration?

Another thing about my summary: apparently the ioctl's TIOCSBRK and
TIOCCBRK really aren't supported any longer supported. When I call
TIOCSBRK the call never returns. I even compiled and ran a sample
program someone sent me and it behaves this way.

Is there anyone from Sun out there listening who knows for sure:
1) The proper interpretation of tcsendbreak()'s duration parameter.
2) If TIOCSBRK should still work (maybe I'm doing something wrong)?
3) The true answer to my original question: How do I send a break for
1.5 seconds?

Thanks,
Mike

----------------------------------------------------------------------
Michael Galuza
DeJarnette Research Systems mgaluza@dejarnette.com
401 Washington Ave Suite 700 Voice: +1(410)583-0680 x691
Towson, MD 21204 Fax: +1(410)583-0696
----------------------------------------------------------------------



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:12:01 CDT