> I also tried the same on alpha vms 8.4 and alpha vms 7.3-2 with the same pr=
> oblem. =20
>
> I don't understand sys$qiow very well, but years ago i followed an example =
> to get data from a serial port and it has worked well for years. It was us=
> ually small messages...less than 50 bytes and I called qiow with a short ti=
> meout and 1 byte buffer size. I just recursively called qiow until i got t=
> he end byte that the device sent (ETX 0x03).
>
> Now i want to read from a newer serial device, the message is XML with tons=
> of wasted data. The message is 500-800 bytes and ends in EOT 0x04 or NAK=
> . I thought from reading the VMS I/O manual that qiow would use any escape=
> sequence as a terminator if I don't specify a terminator.
>
> I thought it best to use a single qiow call with timeout and larger buffer.=
> I've read some of the examples and gone over the VMS System REf manual an=
> d the I/O manual, but I must be missing something.
>
> If I send the following with a 1 byte buffer size and copy each byte to ano=
> ther string...it gets the 500+ bytes of data...but randomly drops bytes. =
> The TNA device/term is set ALTYPEAHD, in the past i think i got lucky as th=
> e message was always so small.
> iostatus =3D SYS$QIOW (0, dbchan, iofunct, &iostat, 0, 0, &ubuf, 1, time=
> out, 0, 0, 0);
>
> If I send the following with buffer size changing from 1 to 999, it seems t=
> o just timeout and get nothing.
> iostatus =3D SYS$QIOW (0, dbchan, iofunct, &iostat, 0, 0, &ubuf, sizeof(=
> ubuf), timeout, 0, 0, 0);
>
> If i send the following it also seems to timeout and get nothing. I'm not s=
> ure how to mask the quadword for terminators to setup EOT and NAK as the on=
> ly terminators.
> iofunct =3D IO$_READVBLK | IO$M_NOFILTR | IO$M_NOECHO | IO$M_TIMED;
> static const unsigned terminators[2] =3D { 0, 1 << 0x04 || 0x15 };
> iostatus =3D SYS$QIOW (0, dbchan, iofunct, &iostat, 0, 0, &ubuf, sizeof(=
> ubuf), timeout, terminators, 0, 0);
>
> In all instances i have a serial sniffer between my port and the serial dev=
> ice and the expected data is going both ways. I don't understand why a buf=
> fer size of 1 seems to get the data, but the larger buffer size does not.
>
> If you don't have the time to educate me, I understand.
>
> I found one of the examples in sys$examples that refers to the terminator b=
> its as follows:
> /* The terminator mask has the <i>-th bit on if ASCII character <i> i=
> s to
> ** terminate a read when entered. This could also be done as a bitfi=
> eld
> ** structure. */
>
> struct term_mask {
> unsigned long int first_4; /* first 4 bytes last 2 bytes =
> */
> unsigned short int last_2; /* Terminator mask includes */
> } mask =3D { 1 << 0x0d, /* carriage return */
> 1 << 4 }; /* and "$"*/
The terminal driver is capable of just about anything you
might think of asking of it with regard to communicating
with a serial device. And, yes, single character reads
can sometimes work rather well. Also, if you understand
how to do asynchronous I/O, and how to do it right, you
may find double buffering helpful.
Remember a few things, though:
o Know the difference between directive level failures
(status from the _issuance_ of the $qio) vs. iosb
level failures, remembering that the iosb is useless
if you have a failure issuing the command to begin
with.
o Know how to use event flags
o Know about the fact that realtime activities -
examining the buffer while the i/o is underway,
for example - run afoul of high level language
constructs and optimization in general unless
you take special precautions, including the
use of the 'volatile' keyword in C.
o Be aware that without flow control, you have
a tough row to hoe with regard to data integrity.
Data can and will be dropped without you being
aware of it. To work around it you can try a
large alt typeahead buffer, of course. And, if
your code is trustworthy and won't go into a
mode that effectively blocks everyone else, you
can run at high priority, including realtime
priorities. Be aware that locking pages in
memory may be necessary if you want to be
aboslutely certain you can read your data
into memory before typeahead buffer overruns
occur.
Often it's easier just to find a way to
do actual flow control. Or to at least use
a protocol with counts and checksums/CRC's
to assure integrity.
o Reading with escape sequence termination
is an option. The escape secquences should
follow the appropriate standard as specified
in the I/O users guide.
o Most important: if you have a protocol that
must pass binary and must use special terminators,
you may want to use PASTHRU, perhaps also turning
off software flow control, typically in both
directions. Special read functions are available
for passing through all characters except possibly
your terminator.
George