EmbeddedRelated.com
Forums
Memfault Beyond the Launch

ISR problem with Separate I&D spaces

Started by cma8691 March 30, 2004

Hi-
I've got a what I think is a simple problem here. I'm using Timer
B1 generating periodic interrupts with the isr incrementing a global
counter, and I can't get the program to work using "Separate I&D"
memory spaces. I'm using Dynamic C 7.30TSE on a RCM3200.

There is no problem when I call the isr directly (w/ Separate I&D),
so it seems like the problem lies with the SetVectIntern() call...

Any insight is greatly appreciated.

Chris Aldrich
caldrich@cald...
cma8691@cma8...

Here's the code:

root void isr_test();
char count;
main()
{
count = 0;
SetVectIntern(0x0B, isr_test);

WrPortI(TBCR, &TBCRShadow, 0x0a); // timer B with pclk/16
WrPortI(TBL1R, NULL, 0x00);
WrPortI(TBM1R, NULL, 0x00); // set initial match

WrPortI(TBCSR, &TBCSRShadow, 0x03); // enable timer B and
//B1 match interrupts
while (1)
{
costate task1 always_on
{
printf(" Count = %d\n", count);
waitfor( DelayMs( 500 ) );
}

}
}

#asm root nodebug
isr_test:

push af
push bc
push hl

ioi ld a, (TBCSR) ; clear interrupt condition

ld hl, count
inc (hl)

xor a
ioi ld (TBL1R), a ; reset timer

pop hl
pop bc
pop af
ipres
ret
#endasm





----------
> From: cma8691 <cma8691@cma8...>
> To: rabbit-semi@rabb...
> Subject: [rabbit-semi] ISR problem with Separate I&D spaces
> Date: Tuesday, March 30, 2004 9:22 AM > Hi-
> I've got a what I think is a simple problem here. I'm using Timer
> B1 generating periodic interrupts with the isr incrementing a global
> counter, and I can't get the program to work using "Separate I&D"
> memory spaces. I'm using Dynamic C 7.30TSE on a RCM3200.
>
> There is no problem when I call the isr directly (w/ Separate I&D),
> so it seems like the problem lies with the SetVectIntern() call...
>
> Any insight is greatly appreciated.

With separate I&D, there are two interrupt vector tables; one on flash, and
one in RAM. The one on flash plays juggling acts to call the one in root
RAM because normally, root RAM is data only, not instruction, so the 16
bytes allocated for an ISR in the IRQ table have to be accessed in a
special manner. This eats a lot of CPU cycles that may give you problems
with a high speed timer--calling the ISR in flash, it calls the ISR in RAM,
patches things up, and then returns. To get around this problem, ISR's
with separate I&D enabled allow you to directly specify a handler at
compile time so the handler is in flash and goes directly to your function.
For these interrupts, the default is to allow SetVectIntern to work, but
the overhead may hurt you to have the table in flash call the table in ram,
and then call your function. When using separate I&D, it is probably
better to use

interrupt_vector timerb_intvec MyTimerBISR;

This way, the table in flash calls MyTimerBISR directly.



Thanks a lot.
The documentation seems to imply the SetVectIntern() will still
work, albeit with 80 clocks of overhead--doesn't seem like it should
be a show stopper. Maybe something strange is happening on the very
first interrupt.

Anyway, using 'interrupt_vector' avoids the problem.

Such a strange compiler...'timerb_intvec' is simply an undefined
token until you enable 'Separate I&D' ... oh well.

Of course I was planning to change the ISR Routine dynamically...I
guess I can just have the ISR jump indirectly through a function
pointer to get to where I want to go--probably 10 or 15 clocks of
overhead. At least it works.

Thanks again.

--- In rabbit-semi@rabb..., "Robert Richter" <robertr@h...> -
-- In rabbit-semi@rabb..., "Robert Richter" <robertr@h...> >
>
> ----------
> > From: cma8691 <cma8691@y...>
> > To: rabbit-semi@rabb...
> > Subject: [rabbit-semi] ISR problem with Separate I&D spaces
> > Date: Tuesday, March 30, 2004 9:22 AM
> >
> >
> > Hi-
> > I've got a what I think is a simple problem here. I'm using
Timer
> > B1 generating periodic interrupts with the isr incrementing a
global
> > counter, and I can't get the program to work using "Separate
I&D"
> > memory spaces. I'm using Dynamic C 7.30TSE on a RCM3200.
> >
> > There is no problem when I call the isr directly (w/ Separate
I&D),
> > so it seems like the problem lies with the SetVectIntern()
call...
> >
> > Any insight is greatly appreciated.
>
> With separate I&D, there are two interrupt vector tables; one on
flash, and
> one in RAM. The one on flash plays juggling acts to call the one
in root
> RAM because normally, root RAM is data only, not instruction, so
the 16
> bytes allocated for an ISR in the IRQ table have to be accessed in
a
> special manner. This eats a lot of CPU cycles that may give you
problems
> with a high speed timer--calling the ISR in flash, it calls the
ISR in RAM,
> patches things up, and then returns. To get around this problem,
ISR's
> with separate I&D enabled allow you to directly specify a handler
at
> compile time so the handler is in flash and goes directly to your
function.
> For these interrupts, the default is to allow SetVectIntern to
work, but
> the overhead may hurt you to have the table in flash call the
table in ram,
> and then call your function. When using separate I&D, it is
probably
> better to use
>
> interrupt_vector timerb_intvec MyTimerBISR;
>
> This way, the table in flash calls MyTimerBISR directly.





Memfault Beyond the Launch