Re: tricky challenge for getting round level-driven interrupt problem: help!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi: just a fyi.

i do not know, cannot tell, and do not care [ItNowWorks(tm)] why what i
have done manages to GetItToWork(tm) - i am merely providing you with
information such that _other people_ may dissect this issue, may look at
this in six months/years and go "oh yeah, maybe i should try that too".

in the write communications, i have REMOVED the use of interrupts and am
PURELY using the INTMR1 bit for polling purposes (!!!)

the code goes something like this:

int pic_misc_write( ..... char *data, int len)
{
	for (i = 0; i < data; i++)
	{
		pic_queue_byte(data[i]);
		pic_writable_int(0, 0, NULL);
	}
}

ha ha, i hear you say, very funny.

well, in pic_writable_int - which USED to be called as an interrupt
handler, i have this:

irq_return_t pic_writable_int(int irq, ....)
{
	/* check that the PIC is ready for us to proceed */
	while (!(clps_readl(INTMR) & 0x40)) {
	}
	...
	...

	/* place the byte on the 
	clps_writeb(pic_get_queued_byte(), PORT_A_DATA_REGISTER);

	/* this generates an interrupt to the PIC */
	clps_writeb(0x...., PORT_A_SOMETHING_REGISTER);

	/* ... which we sit there twiddling our thumbs waiting for
	   it to be cleared 
	 */
	while ((clps_readl(INTMR) & 0x40)) {
	}
}

ironically, it's _still_ not 100% reliable: about 1 in every 400 bytes
gets corrupted.

but that's probably due to bugs in the PIC assembly code, which i can
live with / get these guys to fix, or it's to do with the setup timing
of the port directions - again, i can deal with that.

... the question is - what the _hell_ is going on with the linux 2.6
level-based interrupt handling / my-braindead-way-of-using-them
that causes the above approach to be [virtually] 100% reliable
as compared to a 95%-reliable cock-up?

l.

On Wed, May 04, 2005 at 09:58:31PM +0100, Luke Kenneth Casson Leighton wrote:
> alan, thanks for responding directly.
> 
> the internet is down at the moment (at least, bt's bit is) so
> your continued direct responses, if you have the time, greatly
> appreciated.
> 
> i can't get http or ssh access to _anywhere_, but bizarrely,
> smtp is getting through.
> 
> [sod bt.  royally.]
> 
> On Wed, May 04, 2005 at 02:50:01AM +0100, Alan Cox wrote:
> 
> > On Maw, 2005-05-03 at 22:56, Luke Kenneth Casson Leighton wrote:
> > > it only does level-based interrupts and i need to create a driver
> > > that does two-way 8-bit data communication.
> > 
> > Level triggered is generally considered a feature by people less than
> > 200 years old 8)
>  
>  lots of experience, then, you'd say?  my experience with doing this
>  kind of stuff is kinda limited (doesn't stop me trying) so your
>  response is really appreciated.
> 
> > > i would genuinely appreciate some advice from people with
> > > more experience than i on how to go about getting round
> > > this stupid hardware design - in order to make a RELIABLE,
> > > non-race-conditioned kernel driver.
> > 
> > Assuming you are using the core Linux IRQ code 
> 
>  yep.
> 
> > then you shouldn't have
> > any great problem. The basic rules with level triggered IRQ are that 
> > 
> > - You must ack the IRQ on the device to clear it either specifically or
> > as part of some other process.
> > - The device must raise the IRQ again if the irq condition is present
> > *at* or after the point of the IRQ ack (or in many implementations 'just
> > before' in fact)
> > 
> > the core Linux code deals with masking on the controller to ensure IRQ's
> > dont get called recursively, and ensuring an IRQ gets rechecked/recalled
> > on the unmask/exit path if it is still asserted.
> > 
> > So an implementation is much like a serial port fifo, assert the IRQ
> > until the PC has fetched all the bits. In fact the IRQ line is
> > essentially "NOT(fifo_empty)" and rechecked each time a byte is fetched.
>  
>  okay.
> 
> > *WAY* simpler than nasty edge triggered stuff 8)
>  
>  bleh :)
> 
>  okay.
> 
>  i believe i get it: you raise a level-triggered interrupt which _stays_
>  raised until such time as your fifo is empty.
> 
>  the original protocol that was written [by somebody even less
>  experienced than i] was designed the way it is because the PIC chip
>  that's connected to the ARM only has *one* interrupt.
> 
>  that interrupt is triggered:
> 
>  * on a port read (there are four 8-bit ports!)
>  * on a port write 
>  * by the serial port
>  * by the timer
> 
>  [skip this bit if you're busy, it's just background info]
> 
> 	 so there's now a _thousand_ lines of hand-written assembly code
> 	 which took well over a year to write and debug on the PIC, that
> 	 implements the state-machine to deal with the GPS on the serial
> 	 port, interleaving the "device status" info into the GPS data
> 	 stream, getting the GPS data stream over the 8-bit port and
> 	 receiving LCD commands over the 8-bit port, interpreting them
> 	 and then feeding the LCD.
> 
>  okay.
> 
>  so.
> 
>  assuming that i can handle the pic having only a single interrupt, then
>  does the process go something like this (for read, e.g.):
> 
>  1) the ARM unmasks read interrupts when it's ready.
> 
>  2) when the PIC has data to be read (which is only ever a single byte),
>    it asserts the level-triggered read interrupt to the ARM.
> 
>  3) the ARM receives the interrupt, and reads the byte.  the _act_ of
>    reading the byte causes an edge-triggered interrupt to the PIC.
> 
> 
>  5) the first thing the PIC does in its [one] ISR is to de-assert the
>    read interrupt.  why? because there is only a one byte buffer.
> 
>  
>  we have an additional step in the chain - step 4 - which is:
> 
>  4) in the ISR, the ARM goes into a tight loop checking that the 
>     PIC has cleared the level-triggered interrupt.
>  
> 
>  the reason for checking this is so that when we come out of the
>  ISR on the ARM, the PIC is *SOOO* slow - it's only 6mhz after
>  all - that sometimes (frequently, in fact - about 1 in every
>  50 times) it hasn't got round to clearing the level-driven
>  interrupt by the time we come out of the ARM ISR (!)
> 
>  the problem we're having is actually worse than that.
> 
>  sometimes something goes screwy and _despite_ having this loop-check,
>  we get duplicated characters.
> 
>  sometimes, even worse, we lose sync, and the ARM sits there in the
>  loop...
> 
> 
>  i was getting _so_ fed up with this that i was thinking that there
>  was a problem with the approach being taken.
> 
>  hence the redesign to do alternate read-write-read-write, and making
>  reads exclusive of writes, etc.
> 
>  awful.  just awful :)
> 
> 
>  ... so - in your opinion, alan, is the old approach we had
>  actually _on_ the right lines?
> 
>  also, are you going to ukuug in august, it being _in_
>  aberystwyth and all :)
> 
>  l.
> 

-- 
--
<a href="http://lkcl.net";>http://lkcl.net</a>
--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux