daver@wombat.bungi.COM (Dave Rand) (08/31/90)
[In the message entitled "Interrupt 15, RxRDY interrupts, and DUART device drivers.." on Aug 30, 20:01, John Connin writes:] > > Is the ICU interrupt input /INT15 connected to anything other than the > pullup resistor pack RES13-1 ?? No, it isn't connected to anything else. IR15 should be used for software interrupts, or for RTC interrupts. > Also, could you generally comment on your design decision to provide > RxRDY interrupts. More specificly, is there any code available > which illustrates the 'perfered / best' way of controlling the > 2681 DUART's ?? Ok, here's the scoop on RXrdy... UNIX has the nasty habit of disabling interrupts for extended periods of time, usually sitting at SPL5 or SPL6. Most serial drivers just live with this (since they run at SPL6 or below), and drop characters, unless you have nasty, expensive NS16550A's with FIFO's in them. I'm here to tell you that you don't need to put up with this anymore! This problem exists only on receiving characters - you don't care (much) if the output from a serial port stops for a few milliseconds. You care a LOT when this happens on input, though! The Signetics 2681/2692 handles this with two different mechanisms on the PC532. The first technique is to offer a separate interrupt line for received characters. In the PC532 design, there is one "interrupt" and one "RXrdy/FFul" interrupt per DUART (two serial channels). In a properly designed operating system (non-UNIX), the serial channel interrupts would never be disable (except for short periods during queue updates). With two different interrupts from each DUART, we have the ability to externally prioritize the two interrupts. The transmit/modem interrupt should be set at a low priority, and the RXrdy interrupt at the highest priority (above the highest kernel interrupt priority). When a RXrdy interrupt occurs, the data is saved into a ring buffer (sized appropriately, not less than 7 * 70 bytes per port: 512 bytes is a good number). At the end of the interrupt service routine, a TIMEOUT count is posted to an internal variable. This variable is maintained on a per-port basis, and is decremented by a timer interrupt from the counter/timer in each DUART (handy, huh?). The timer interrupts should occur at the low-priority interrupt level, and at a fairly high rate (1-5 milliseconds). When the TIMEOUT variable reaches zero, indicating that data has not appeared for quite a few character times, the data in the ring buffer is transferred to the high level character queues through the line discipline (CLISTs). You can also pass data up if the ring buffer gets above a high water mark by setting the TIMEOUT to zero in the RX interrupt routine, although in practice this doesn't help much. (What's that? Too many interrupts? Can't work? I hate questions from the assembled masses... let me continue!) You may feel that taking interrupts from 8 sources (8 serial channels) at 38.4 KBps is quite a processor burden, what with context switches and all... it ain't so! First of all, we WIRE-OR the open collector RXrdy interrupts from each pair of serial channels (DUART) - this normally cuts the number of interrupts in half, with an expense of 'polling' each channel when you get an interrupt (a good idea anyway). Second, the 2681/2692 has a FIFO of its own. If you feel the processor is getting too busy, you can switch modes on the DUART, and get an interrupt every 3 characters instead of every character. You can tell when the processor is too loaded, since you will have more than one character available on each interrupt - by detecting this and switching modes, the interrupt burden will go down correspondingly. Third, this is a _very_ light-weight process. The interrupt handler will save the registers, read each of the DUART channels to see which port has data (or both, for that matter), read the status (check for parity), and read the data. The data will be saved in a ring buffer, the TIMEOUT value posted, restore registers and return. We're talking a hundred instructions, tops. The second way that the 2681/2692 DUART fixes overrun problems is with HARDWARE FLOW CONTROL (what a concept). When the DUART FIFO is about to overflow, it automatically deasserts the RTS line. Before transmitting a character, it looks at the status of the CTS line to ensure it is asserted. Even if the processor is so busy it just _can't_ get to the DUART in time, the hardware will still activate the flow control signals! This is the right DUART to use in all projects. Don't use NS16550A's. You can do it in software, with the right hardware help... I do have a nasty, grotty, unrolled, horrible driver that does all of these things. You need that when you are running 4 Trailblazers on a 0.75 MIPS machine... I'll hack it into the MINIX drivers (George is boggled at MINIX right now - he can't believe that he hardware is working!) and post it. -- Dave Rand dlr@bungi.com {sun|vsi1|pyramid|uunet}!daver!dlr
news@daver.bungi.com (08/31/90)
>[In the message entitled "Interrupt 15, RxRDY interrupts, and DUART device dri vers.." on Aug 30, 20:01, John Connin writes:] ... >> Also, could you generally comment on your design decision to provide >> RxRDY interrupts. >Ok, here's the scoop on RXrdy... UNIX has the nasty habit of disabling >interrupts for extended periods of time, usually sitting at SPL5 or SPL6. >Most serial drivers just live with this (since they run at SPL6 or >below), and drop characters, unless you have nasty, expensive NS16550A's >with FIFO's in them. I'm here to tell you that you don't need to put >up with this anymore! ... When a RXrdy interrupt occurs, >the data is saved into a ring buffer (sized appropriately, not less than >7 * 70 bytes per port: 512 bytes is a good number). At the end of the >interrupt service routine, a TIMEOUT count is posted to an internal >variable. Looks like a pretty good scheme; but what's magic about 70 * 7 ( = 490 ) bytes for the buffer size? PS. I'm still looking for a Public Domain scanf(). Any hints on where to find one? Many Thanks: Jonathan Ryshpan <...!uunet!hitachi!jon> M/S 420 (415) 244-7369 Hitachi America Ltd. 2000 Sierra Pt. Pkwy. Brisbane CA 94005-1819
dlr@daver.bungi.com (Dave Rand) (09/01/90)
[In the message entitled "Re: DUARTS etc" on Aug 31, 9:31, Jonathan Ryshpan writes:] > Looks like a pretty good scheme; but what's magic about 70 * 7 ( = 490 ) > bytes for the buffer size? > That's uucp g protocol, with a window of 7... Can you tell I have a fixation on uucp? :-) -- Dave Rand {pyramid|mips|bct|vsi1}!daver!dlr Internet: dlr@daver.bungi.com
greg@cheers.Bungi.COM (Greg Onufer) (09/03/90)
>> Looks like a pretty good scheme; but what's magic about 70 * 7 ( = 490 ) >> bytes for the buffer size? >That's uucp g protocol, with a window of 7... Can you tell I have a >fixation on uucp? :-) For the worst-case scenario, might as well make that 72*7 since the 4.3BSD UUCP has a feature/bug of sending two nulls after every packet. What if you're talking g-protocol with a 4k packet size? :-) Cheers!greg