Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Glitches Eliminated using Interrupt Context Saving, BUT ... (http://www.chiefdelphi.com/forums/showthread.php?t=50413)

dcbrown 02-01-2007 12:45

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
[This is in reply to WPILib and interrupt latency issue re: GTS sensor]

One way of simulating multiple levels of interrupt priority is to utilize multiple ISRs tied to through the same interrupt vector.

static unsigned char slow_isr = 0;
static unsigned char slow_isr_0 = 0;
static unsigned char slow_isr_1 = 0;
static unsigned char slow_isr_2 = 0;
:
static unsigned char slow_isr_n = 0;

#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD
void InterruptHandlerLow ()
{
static unsigned char fast_isr;

// check "fast" interrupts here, like gts or other
// h/w time critical interrupts
// "fast" interrupts only use trusted interrupt drivers
// if "fast" interrupt serviced, set fast_isr flag
// these drivers will be from a trusted source, such
// as the default system drivers provided by the library.

<appropriate code for "fast" devices goes here>

// if we serviced a "fast" interrupt, return now.
// if there is another interrupt pending, we'll come right back.
if (fast_isr != 0) return;

// No fast interrupts processed, are there any "slow" ones pending?

// Now on to "slow" interrupt services
// determine if or which isr flags are set
// associated with "slow" type interrupt services,
// such as the system clock timer and capture
// them for the slow_isr routine's use/query.
<appropriate code to check, accumulate flag and clr IF>

// if slow isr routine is already running, then we're done - exit
if (slow_isr != 0) return;

// Turn interrupts back on and call
// the "Slow" service routine. Hardware
// dispatch of the h/w interrupt has occurred
// so we won't get immediately vectored again
// until the next interrupt.
while (0==0)
{
slow_isr = 0xFF; // show we're running slow isr
INTCONbits.GIEL = 1; // turn interrupts back on
InterruptHandlerLow_Slow(); // process bottom half of slow isr
INTCONbits.GIEL = 0;
if (slow_isr_0 != 0) continue;
if (slow_isr_1 != 0) continue;
:
slow_isr = 0;
break;
}
return;
}

#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD, TABLAT, TBLPTR, section(".tmpdata"), section=("MATH_DATA")
void InterruptHandlerLow_Slow()
{
while (0==0)
// The only routines that can run while this
// routine is executing is high priority interrupt
// service routine and the low priority (fast) drivers.
if (slow_isr_0 != 0)
{
slow_isr_0 = 0;
<process interrupt>
}
if (slow_isr_1 != 0)
{
slow_isr_1 = 0;
<process interrupt>
}
:

// Ok, at this point we believe we've processed all the
// pending slow type interrupts, time to leave!
INTCONbits.GIEL = 0;
// Check one more time with interrupts off,
// to see if another slow device interrupted
// requested service while or after we processed the
// current batch...
if (slow_isr_0 != 0) continue;
if (slow_isr_1 != 0) continue;
:
// nope, no new slow isr requests pending...
// Turn interrupts back on, this is a gamble in that interrupts
// requesting slow isr service can happen now, but the problem is
// restoring context just takes too long. We'll check again after
// context is restored.
INTCONbits.GIEL = 1;
return;
}
}

In this way interrupts requiring low interrupt latency are handled pretty much right away, even the save=PROD may not be needed. If the device interrupt is to be service by a user written routine, then it's servicing is deferred to the slow isr section. A small amount of application programmers interface needs to be documented for slow isr driver writers since the h/w bits such as the interrupt flag have already been cleared for it during fast device processing, but it will work and prevent the additional save context required from effecting latency. Essentially with this method you have two levels of IPL with minimal latency for the class of "fast" devices requiring minimal latency.

Bud

mluckham 08-01-2007 10:38

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
Hmm - recursive logic - you are turning interrupts on as you process the 'slow' ISR, and deferring the return-from-interrupt at the end of an original invocation of InterruptHandlerLow (). Very hairy indeed ... if your sample is from running code, I bet you debugged it using an ICE (in-circuit emulator)!

Could you not accomplish the same effect without the recursion, by simply calling 'slow' ISR routines using your technique of the separate _Slow() routine which has it's own #pragma for saving additional data sections?

And how about checking for and servicing multiple interrupt sources during the same interrupt?


Responding to Brad, I finally 'got' what he was waying - that he started this timer when the pulse began. I didn't implement that way because I was always planning to measure multiple pulse sources and didn't want to devote a separate timer to each.

I see that this year's gear tooth sensors are the same as last year (well no, I haven't ready the documentation on them yet!!). Although our team is going with quadrature encoders, I see no reason why the pulse-measurement approach should be abandoned by everyone.

Biff 08-01-2007 11:11

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
As far as "custom" circuts go BaneBots this year is offering both encoders and an Encoder Divider Kit ($10.00), encoders are a little more. This would get you one signal line for forward, backward and another for a string pulses that which can be straight or divided. Link to Bane's First page http://www.banebots.com/c/FIRST
Good luck to all
Biff

Alan Anderson 08-01-2007 11:23

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
Quote:

Originally Posted by mluckham (Post 551045)
I see that this year's gear tooth sensors are the same as last year (well no, I haven't ready the documentation on them yet!!). Although our team is going with quadrature encoders, I see no reason why the pulse-measurement approach should be abandoned by everyone.

Read the documentation and you'll find a reason. The Allegro sensor devices provided in the kit this year are not the fancy kind that give pulse-width-encoded information on gear tooth direction. They only provide tooth transition information. You will be able to measure how fast the gear is turning, but not which way.

dcbrown 08-01-2007 11:59

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
The sample code is only slightly recursive and only then to allow the fast isr to be called.

Q. Could you not accomplish the same effect without the recursion, by simply calling 'slow' ISR routines using your technique of the separate _Slow() routine which has it's own #pragma for saving additional data sections?

No. But I'll leave you to ponder why. Think latency. If you want more info, ask and I'll explain.

Q. And how about checking for and servicing multiple interrupt sources during the same interrupt?

Actually the code is ambiguous as to whether only one interrupt is processed or multiple. With the slow isr, all currently pending interrupts need to be serviced or they will be lost otherwise since they have already been dispatched (cleared) in hardware. In the fast isr it comes down to how many times overlapping interrupts are present with the time required to check for them vs the exit/entrance time into the isr. If overlapping interrupts only occur in 1:n cases where n is fairly large, then you are chewing up processor bandwidth for no gain.

As far as being hairy? Nah, after 3 decades of dealing with hardware this ain't hairy. Hairy is a 256bit ultrawide instruction word, 2 128bit input pipes, 1 256bit output pipe, 8-12 simultaneous operations, multi-delay branching all running at <10ns. Course that technology was 20 years ago now.

Grins,
Bud

mluckham 09-01-2007 14:43

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
Thanks Alan, I've read the sensor manual now. And noted that the Gyro and Accelerometer are to be mailed to us.


Does anyone think that any rule prevents use of last year's gear tooth sensors in this year's robot??


Bud - yes, your routine is quite clever and provides a two-priority interrupt priority scheme, that is not quite as recursive as I had thought on first glance, and that would reduce jitter caused by ISRs that consume larger quantities of instruction cycles (by placing less-frequently-called ISRs containing large code-blocks inside your slow_isr loop).

The result could be more accurate pulse-length measurements - the topic of this thread. Thanks for sharing the code with us.

Alan Anderson 09-01-2007 16:11

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
Quote:

Originally Posted by mluckham (Post 552221)
Does anyone think that any rule prevents use of last year's gear tooth sensors in this year's robot??

Last year's GTS board is not available for purchase. It does not meet the requirement for an off-the-shelf component or assembly. But you could create your own equivalent custom circuit this year using the actual sensor from Allegro. You'd have to account for the cost of it, though (even if you got it donated).

dcbrown 09-01-2007 17:19

Re: Glitches Eliminated using Interrupt Context Saving, BUT ...
 
To be even more clever...

Now that you have code executing asynchronously from user code driven by interrupts it is an easy matter to also add a general event handler, to say run something every 10ms or to run a routine every 10th time a sonar sensor completes a measurement... You can still starve off the real user code that is waiting for all this processing to complete, but it does make some things like collision detection a lot easier without having to poll and without further impacting interrupt latency. And besides, by the time slow isr is run you've already paid the penalty for saving off the .tmpdata and other sections.

I happen to have an asynchronous event handler written and bench tested...

Bud


All times are GMT -5. The time now is 20:45.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi