[comp.sys.amiga.tech] OpenDevice question

brianr@tekig5.PEN.TEK.COM (Brian Rhodefer) (01/04/89)

I'm writing an Amiga application which, in response to
Intuition gadget input, controls a network of external
devices via the Amiga's serial output, and I've come up
with a couple of questions about the use of Device I/O
that the printed manuals for the laity aren't too clear on.
Could some generous initiate offer some advice/insight?

Background:

 I want to use the serial port for output only.  Because I
 don't need to obtain any input, and am willing to believe
 that the serial device will always send every byte of the
 messages I pass it, I've decided to try to use an IOExtSerReq
 (OrWhatEverTheBleepItzCalled) whose ReplyPort field is NULL.

 A Vertical Blank server routine will peek at the Node type
 field, and signal a subtask every 50mS (3 vertical blanks)
 iff the Node is NOT of type NT_MESSAGE.  The subtask will be
 able to assume, whenever it awakens, that the serial transmitter
 (and IOExtSerReq block) is idle, and SendIO any applicable 
 precomputed new data, then compute a data buffer for next time.

 Two buffers are used for transmit data, but only one IOExtSerReq
 structure, whose appropriate io.Data field is pointed at the two
 buffers alternately.  This is out of concern for Matt Dillon's
 claim that the serial device is unable to cope with multiple
 posted transmit requests.  (Aside:  What's so hard about serial I/O
 that keeps computer makers from getting it quiiite right, anyway?)


Question(s):

 1) Will SendIO result in the IORequest's Message's Node type getting
    set to "NT_Message"?  Will the serial Device do a ReplyMsg, causing
    the Node type to be set to "NT_ReplyMsg"?

 2) So far, so good?  Or do I go to the State Home for the Naive?
    Is it kosher to watch the node type this way?  I hate to waste
    time with obvious questions like this, but I just read a posting
    by Randell Jesup in which he says:

      " DO NOT assume that a signal on the reply port for something
	that has been SendIO()ed or BeginIO()ed means the message has
	come back. <...deleted...> Welcome to the wonderful world of IO! ",

    and it kinda shook my faith in `the obvious'.

    Please understand this as a respectful question and not sarcasm:
     Whatever is `PA_SIGNAL' message port signalling FOR, then?


 3) As I said, I'd like to use an IORequest whose ReplyPort field is NULL.
    Can this IORequest block be used for the OpenDevice() call to open
    the serial device, and, later, for a DoIO() call to modify the baud rate? 


Enlightenment earnestly appreciated,

Brian Rhodefer   ....!tektronix!tekig5!brianr

jesup@cbmvax.UUCP (Randell Jesup) (01/05/89)

In article <3638@tekig5.PEN.TEK.COM> brianr@tekig5.PEN.TEK.COM (Brian Rhodefer) writes:
> I want to use the serial port for output only.  Because I
> don't need to obtain any input, and am willing to believe
> that the serial device will always send every byte of the
> messages I pass it, I've decided to try to use an IOExtSerReq
> (OrWhatEverTheBleepItzCalled) whose ReplyPort field is NULL.

	NULL??!!!  ALL IO requests must have the address of a valid port
in the ReplyPort field.  No exceptions.

> A Vertical Blank server routine will peek at the Node type
> field, and signal a subtask every 50mS (3 vertical blanks)
> iff the Node is NOT of type NT_MESSAGE.  The subtask will be
> able to assume, whenever it awakens, that the serial transmitter
> (and IOExtSerReq block) is idle, and SendIO any applicable 
> precomputed new data, then compute a data buffer for next time.

	GACK!  I'd advise NOT going around the io routines, use CheckIO()
instead of "peeking" at the node type.  There is no guarantee that node type
will always be used as the IO-completed flag, or that other things may not need
to be done.

	I'd advise signaling if CheckIO says the request has finished, and
have the subtask do a WaitIO() (which removes it from the port) before
reusing the message (it MUST be removed from the port before reuse).  GetMsg
can also be used if you KNOW there is only one outstanding message for that
port.

> Two buffers are used for transmit data, but only one IOExtSerReq
> structure, whose appropriate io.Data field is pointed at the two
> buffers alternately.  This is out of concern for Matt Dillon's
> claim that the serial device is unable to cope with multiple
> posted transmit requests.  (Aside:  What's so hard about serial I/O
> that keeps computer makers from getting it quiiite right, anyway?)

	Sounds OK, though I personally wasn't aware of the two-xmit packet
problem (though I believe it).  I'll make sure Bryce fixes it for 1.4.

>Question(s):
>
> 1) Will SendIO result in the IORequest's Message's Node type getting
>    set to "NT_Message"?  Will the serial Device do a ReplyMsg, causing
>    the Node type to be set to "NT_ReplyMsg"?

	Currently, but I'd advise against counting on it!

> 2) So far, so good?  Or do I go to the State Home for the Naive?
>    Is it kosher to watch the node type this way?  I hate to waste
>    time with obvious questions like this, but I just read a posting
>    by Randell Jesup in which he says:
>
>      " DO NOT assume that a signal on the reply port for something
>	that has been SendIO()ed or BeginIO()ed means the message has
>	come back. <...deleted...> Welcome to the wonderful world of IO! ",
>
>    and it kinda shook my faith in `the obvious'.
>
>    Please understand this as a respectful question and not sarcasm:
>     Whatever is `PA_SIGNAL' message port signalling FOR, then?

	To wake your process up when one or more messages arrive at the port.
The point behind that statement was that WaitIO is NOT guaranteed to clear
the signal - if the message has already been returned, it just removes it and
never waits.  Therefor it's safer to use the signal to know when to do a
CheckIO on outstanding messages (or whatever).  I've seen too many people
assume that the signal means they can do a GetMsg() without checking the
result.  The <deleted> bit above was the example of how to do it safely.

> 3) As I said, I'd like to use an IORequest whose ReplyPort field is NULL.
>    Can this IORequest block be used for the OpenDevice() call to open
>    the serial device, and, later, for a DoIO() call to modify the baud rate? 

	NULL is right out.  ReplyMsg on a message with a null replyport will
corrupt low memory, leading to a quick crash.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

brant@uf.msc.umn.edu (Gary Brant) (01/05/89)

In article <5625@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <3638@tekig5.PEN.TEK.COM> brianr@tekig5.PEN.TEK.COM (Brian Rhodefer) writes:
>> messages I pass it, I've decided to try to use an IOExtSerReq
>> (OrWhatEverTheBleepItzCalled) whose ReplyPort field is NULL.
>
>	NULL??!!!  ALL IO requests must have the address of a valid port
>in the ReplyPort field.  No exceptions.
>

[ lots of stuff deleted ]

>	NULL is right out.  ReplyMsg on a message with a null replyport will
>corrupt low memory, leading to a quick crash.

This is very odd.  I am looking at an example program in the RKM p.252 under 
timer.device which explicitly sets the ReplyPort = NULL.  I needed an
example for setting the system time/date (RTClock broke on Jan 1 doncha
know - some programmers who write clock programs & dont know how to handle
year boundary conditions flames deleted)  Anyway I have been running this 
prog in my startup sequence to adjust the system date every boot.  It 
hasn't appeared to lead to any instability... or am i missing someting?

>
>-- 
>Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup


-Gary Brant		ARPA: brant@uf.msc.umn.edu


(My employer doesn't know about my ravings)

jesup@cbmvax.UUCP (Randell Jesup) (01/06/89)

In article <10687@umn-cs.CS.UMN.EDU> brant@uf.msc.umn.edu (Gary Brant) writes:
>In article <5625@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>	NULL??!!!  ALL IO requests must have the address of a valid port
>>in the ReplyPort field.  No exceptions.
...
>>	NULL is right out.  ReplyMsg on a message with a null replyport will
>>corrupt low memory, leading to a quick crash.
>
>This is very odd.  I am looking at an example program in the RKM p.252 under 
>timer.device which explicitly sets the ReplyPort = NULL.  I needed an
>example for setting the system time/date [...] Anyway I have been running this 
>prog in my startup sequence to adjust the system date every boot.  It 
>hasn't appeared to lead to any instability... or am i missing someting?

	Well, it so happens that example uses DoIO, and DoIO always tries
quick IO.  If quick IO is tried and succeeds, the replyport field isn't
currently touched.  If it fails, the replyport WILL be used.  The example is
broken, but happens to work ok in this particular case for the time being.
There is NO guarantee that this is safe for any IO operation in any case. 
You'll note that the large timer example sets it up correctly.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup