From: Dave N. <n6...@ar...> - 2008-08-14 06:04:00
|
Matthias Trute wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Dave N6NZ schrieb: >> This evening I have been looking at the interrupt system trying to >> understand it. In reading amforth.asm, I see where the current interrupt >> number is stored away in 'intcur' and then interrupts are re-enabled. >> It seems to me that there is a race with multiple simultaneous >> interrupts -- if a second interrupt comes in before the value of >> 'intcur' has been consumed it will be over written and the interrupt >> will have been lost to forth. It seems to me like intcur should be a >> bit mask so that all pending interrupts could be represented, not a >> single interrupt number. Is there something that I am missing? > You hit all points. The interrupt system has been designed to have > access to timer interrupts. Later I extended it to play with other > interrupt sources that sometimes work sometimes dont. To be > honest: I never had the need to implement interrupts beyond the > timers in forth, and now exists an assembler in amforth with > an PS/2 keyboard example so I'm open for suggestions and patches > but not very motivated to implement a new interrupt system myself ;=) OK, thanks for the confirmation of my reading. When digging into a new source code I am always wary of making misguided assumptions. I've been thinking about the problem somewhat, but haven't had time to code up any alternatives. I did a quick study of a bit vector approach, where each interrupt maps to a bit in a double cell. While it is quick and simple to set the bit, I haven't yet found a fast, tight way to dispatch interrupts off a bit vector in DO_INTERRUPT. Another thought is to simply have ISR return with a RET instead of a RETI, thus interrupts are still locked out. DO_INTERRUPT would SEI just before rjmp'ing to DO_EXECUTE. The T but function could be replaced by simply testing the status of the I flag in DO_EXECUTE. Interrupts would be locked out for the duration of the interrupted word, which should be short. This method would require that no other word ever execute an SEI -- a word that needs to lock interrupts needs to deal with the case where interrupts are already disabled -- it would have to save the SREG before any CLI, and then restore the SREG to its previous state instead of doing a blind SEI. This method still allows (as the current method does) nested interrupts. Allowing nested interrupts may not be a good thing. And a third idea that I haven't thought about much at all is to essentially turn 'intcur' into a ring buffer instead of a simple variable. This should be nearly as quick at dispatching interrupts as the current scheme and is no fundamental change to the architecture. I believe this method can preclude nested interrupts, which eliminates a source of hard to find (hard to sensitize!) interrupt handler bugs. In any case, I'll need to address interrupts in some way. For my robotics applications, in addition to timers and serial comms, I want to track the wheel encoders with a pin change interrupt. For now, I will probably write a complete low level pin-change interrupt handler that keeps the encoder counts, and provide forth words to interface to the critical section that contains the counts. In many ways it makes sense to push the robot platform infrastructure down into the forth VM anyway. There are 4 of us now in the Homebrew Robotics Club trying out amforth. It's a very nice fit for our projects. -dave |