DSPRelated.com
Forums

[--SP]=RETI (Blackfin)

Started by Adrian Hey November 9, 2006
Hello folks,

I don't seem to be having much luck getting ADI technical
support talk sense and answer this simple question :-(

Can anyone tell me why (if), if I want nested interrupts,
the [--SP]=RETI instruction must be the *1st* instruction
in an interrupt handler (as stated in hardware ref. manuals).

My understanding is that interrupt handlers start out in a
non-interruptable state and it's the pushing of RETI that
enables other interrupts. If this is so then I can't think
of any reason why this must be the 1st instruction. Will
it really not work if it's the 9th instruction (say)? or
or are the hardware ref manuals just misleading?

Thanks
--
Adrian Hey
Tushar wrote:
> Hi Adrian,
> RETI has the return address -> where the control must return after
> servicing the interrupt.
> When you want nested interrupts, while one interrupt is being serviced,
> any-other interrupt can occur. Depending on your config, higher priority
> interrupts may have to be serviced and the current interrupt would be
> put on hold. Now when the control goes to higher priority interrupt,
> reti has the return address of your original interrupt.
> So it program flow control would end up in a lock state.
> Try to visualize it and you will get the answer.
> Warm regards,
> Tushar.

Thanks Tushar, but with all due respect this is precisely the kind of
non-answer I've been getting from ADI technical support. Do you
guys genuinely not understand the question I am asking :-)

I understand perfectly well what nested interrupts are and why RETI
must be saved if nesting is allowed. The question is why must the
[--SP]=RETI be the *1st* instruction (rather than the 9th say).

The ADI docs clearly state that nesting is prevented until
[--SP]=RETI has been executed, and this much certainly seems
to be true as I have written plenty of handlers that don't
save RETI at all (and the reason they work is that they are not
interrupted, I assume). But if it's true that executing
[--SP]=RETI is what enables nesting, then why does it have to
be the 1st instruction?

It should work just as well if it's the 9th or 999th instruction,
(unless there's some other undocumented gotcha somewhere).

Regards
--
Adrian Hey
Hi Adrian,

You rightly mentioned that the following is true.

> The ADI docs clearly state that nesting is prevented until
> [--SP]=RETI has been executed, and this much certainly seems
> to be true as I have written plenty of handlers that don't
> save RETI at all (and the reason they work is that they are not
> interrupted, I assume). But if it's true that executing
> [--SP]=RETI is what enables nesting, then why does it have to
> be the 1st instruction?

Now, as you know, interrupts occur at anytime and in an interrupt based system, the system timing is unpredictable.
So imagine a situation where program control enters your ISR in which [--SP]=RETI is the 9th instruction.
Lets say the program control reaches the 4th instruction and an higher priority interupt occurs.
System shud service this higher priority request immediately, but since [--SP]=RETI is 9th instruction, the higher priority request would be serviced only after execution of the 9th instruciton based on your system settings. Otherwise, the system would go in for a toss.

Warm regards,
Tushar.

----- Original Message ----
From: Adrian Hey
To: Tushar
Cc: a...
Sent: Saturday, November 11, 2006 2:05:47 AM
Subject: Re: [adsp] [--SP]=RETI (Blackfin)
Tushar wrote:
> Hi Adrian,
> RETI has the return address -> where the control must return after
> servicing the interrupt.
> When you want nested interrupts, while one interrupt is being serviced,
> any-other interrupt can occur. Depending on your config, higher priority
> interrupts may have to be serviced and the current interrupt would be
> put on hold. Now when the control goes to higher priority interrupt,
> reti has the return address of your original interrupt.
> So it program flow control would end up in a lock state.
> Try to visualize it and you will get the answer.
> Warm regards,
> Tushar.

Thanks Tushar, but with all due respect this is precisely the kind of
non-answer I've been getting from ADI technical support. Do you
guys genuinely not understand the question I am asking :-)

I understand perfectly well what nested interrupts are and why RETI
must be saved if nesting is allowed. The question is why must the
[--SP]=RETI be the *1st* instruction (rather than the 9th say).

The ADI docs clearly state that nesting is prevented until
[--SP]=RETI has been executed, and this much certainly seems
to be true as I have written plenty of handlers that don't
save RETI at all (and the reason they work is that they are not
interrupted, I assume). But if it's true that executing
[--SP]=RETI is what enables nesting, then why does it have to
be the 1st instruction?

It should work just as well if it's the 9th or 999th instruction,
(unless there's some other undocumented gotcha somewhere).

Regards
--
Adrian Hey
Hello again Tushar,

Tushar Agrawal wrote:
> Hi Adrian,
>
> You rightly mentioned that the following is true.
>
> > The ADI docs clearly state that nesting is prevented until
> > [--SP]=RETI has been executed, and this much certainly seems
> > to be true as I have written plenty of handlers that don't
> > save RETI at all (and the reason they work is that they are not
> > interrupted, I assume). But if it's true that executing
> > [--SP]=RETI is what enables nesting, then why does it have to
> > be the 1st instruction?
>
> Now, as you know, interrupts occur at anytime and in an interrupt based
> system, the system timing is unpredictable.

Yep.

> So imagine a situation where program control enters your ISR in which
> [--SP]=RETI is the 9th instruction.
> Lets say the program control reaches the 4th instruction and an higher
> priority interupt occurs.
> System shud service this higher priority request immediately,

Why?

> but since
> [--SP]=RETI is 9th instruction, the higher priority request would be
> serviced only after execution of the 9th instruciton based on your
> system settings.

Indeed, this is exactly the behaviour I want and would expect. It seems
to me to be entirely reasonable that the first 8 instructions of an
ISR are a critical section which must not be interrupted by *anything*
(even "higher priority" interrupts).

So I execute [--SP]=RETI as the 9th instruction, thereby enabling
nesting from the 10th instruction onwards (I hope). But if the Blackfin
hardware ref. manuals are to be believed, this will not work (for some
reason that is not explained).

What I have been trying to find out is is this constraint real, or is
it just a typo in the hardware ref. manuals. It seems from what
you're saying that it's not a real constraint (it's just a misleading
typo).

> Otherwise, the system would go in for a toss.

Eh? It does not. It just means the higher priority interrupt has to
wait a few bannana seconds. Timing wise it's no different from
globally disabling interrupts momentarily, just as you would around
any critical section.

I can see we're getting nowhere fast, though to be fair your latest
answer has made more sense than those I got from technical support.
But it seems the easiest way for me to find out for sure is going
to be the hard way (empirically).

Regards
--
Adrian Hey
Hi Adrian,

I've been using nested interrupts for some time in Blackfin, and as
far as I know you **may** use the [--SP]=RETI instruction **after**
saving other registers on the stack (in some cases, I myself do that).
The drawback is that if you have fast reentrant interrupts going on,
you may start to use a lot of your stack (and even have a stack
overflow) just because of those first "pushes" before the RETI push. I
understand that the RETI push instruction should be the 1st. one as a
recommendation, not as an obligation. Hey, group, if I'm wrong, please
let me know!

Hope this helps!

Regards,

Fabio
--- In a..., Adrian Hey wrote:
>
> Tushar wrote:
> > Hi Adrian,
> > RETI has the return address -> where the control must return after
> > servicing the interrupt.
> > When you want nested interrupts, while one interrupt is being
serviced,
> > any-other interrupt can occur. Depending on your config, higher
priority
> > interrupts may have to be serviced and the current interrupt would be
> > put on hold. Now when the control goes to higher priority interrupt,
> > reti has the return address of your original interrupt.
> > So it program flow control would end up in a lock state.
> > Try to visualize it and you will get the answer.
> > Warm regards,
> > Tushar.
>
> Thanks Tushar, but with all due respect this is precisely the kind of
> non-answer I've been getting from ADI technical support. Do you
> guys genuinely not understand the question I am asking :-)
>
> I understand perfectly well what nested interrupts are and why RETI
> must be saved if nesting is allowed. The question is why must the
> [--SP]=RETI be the *1st* instruction (rather than the 9th say).
>
> The ADI docs clearly state that nesting is prevented until
> [--SP]=RETI has been executed, and this much certainly seems
> to be true as I have written plenty of handlers that don't
> save RETI at all (and the reason they work is that they are not
> interrupted, I assume). But if it's true that executing
> [--SP]=RETI is what enables nesting, then why does it have to
> be the 1st instruction?
>
> It should work just as well if it's the 9th or 999th instruction,
> (unless there's some other undocumented gotcha somewhere).
>
> Regards
> --
> Adrian Hey
>
Hello Fabio,

fabio_fly wrote:
> I understand that the RETI push instruction should be the 1st. one as a
> recommendation, not as an obligation.

Well this is what's strange. IMO a hardware reference manual should be
documenting how the hardware actually works and what it's limitations
are, not offering advice about what may or may not be good programming
practice, in ADIs opinion :-)

Both my BF535 and BF533 manuals use the word "must" (on pages 4-54 and
4-51 respectively).

Though now I come to look at my BF537 manual (which I've not used
before) I see it scarcely has anything to say on the subject. Though
a quick search does reveal some sample code that looks like an ISR
and definitely has [--SP]=RETI somewhere other than 1st instruction.

So maybe there's something different about BF537, or maybe the
BF533/BF535 manuals are just wrong. (I suspect the latter, to be
honest.)

> Hope this helps!

Yes it does, thanks.

Regards
--
Adrian Hey
Hi, Adrian,

I agree with you: sometimes ADI docs are a bit confusing.
>From the little experience I have with BF531 & BF537 (about 18
months), and in the assembly point of view, I see no differences
between both. And I've been using nested interrupts on both, with the
[-- SP] = RETI instruction most of the times after the 10th. position
in the ISR...

As I have understood also from the hard. ref., and as Tushar said
before, the use of that instruction as the first one on the ISR
enables also a faster response to other higher priorities peripherals.

Best regards,

Fabio
--- In a..., Adrian Hey wrote:
>
> Hello Fabio,
>
> fabio_fly wrote:
> > I understand that the RETI push instruction should be the 1st. one
as a
> > recommendation, not as an obligation.
>
> Well this is what's strange. IMO a hardware reference manual should be
> documenting how the hardware actually works and what it's limitations
> are, not offering advice about what may or may not be good programming
> practice, in ADIs opinion :-)
>
> Both my BF535 and BF533 manuals use the word "must" (on pages 4-54 and
> 4-51 respectively).
>
> Though now I come to look at my BF537 manual (which I've not used
> before) I see it scarcely has anything to say on the subject. Though
> a quick search does reveal some sample code that looks like an ISR
> and definitely has [--SP]=RETI somewhere other than 1st instruction.
>
> So maybe there's something different about BF537, or maybe the
> BF533/BF535 manuals are just wrong. (I suspect the latter, to be
> honest.)
>
> > Hope this helps!
>
> Yes it does, thanks.
>
> Regards
> --
> Adrian Hey
>
Like many others, Fabio too has been using [-- SP] = RETI instruction most of the times after the 10th. position in the ISR...
With all due respect, Adrian, to get better response from ADI, you have to clearly cite the situation that you want to place critical section as first few instructions of your ISR after which you want to enable nesting. In this case, you will get precise response.

----- Original Message ----
From: fabio_fly
To: a...
Sent: Monday, November 13, 2006 6:33:32 AM
Subject: [adsp] Re: [--SP]=RETI (Blackfin)

Hi, Adrian,

I agree with you: sometimes ADI docs are a bit confusing.
>From the little experience I have with BF531 & BF537 (about 18
months), and in the assembly point of view, I see no differences
between both. And I've been using nested interrupts on both, with the
[-- SP] = RETI instruction most of the times after the 10th. position
in the ISR...

As I have understood also from the hard. ref., and as Tushar said
before, the use of that instruction as the first one on the ISR
enables also a faster response to other higher priorities peripherals.

Best regards,

Fabio

--- In adsp@yahoogroups. com, Adrian Hey wrote:
>
> Hello Fabio,
>
> fabio_fly wrote:
> > I understand that the RETI push instruction should be the 1st. one
as a
> > recommendation, not as an obligation.
>
> Well this is what's strange. IMO a hardware reference manual should be
> documenting how the hardware actually works and what it's limitations
> are, not offering advice about what may or may not be good programming
> practice, in ADIs opinion :-)
>
> Both my BF535 and BF533 manuals use the word "must" (on pages 4-54 and
> 4-51 respectively) .
>
> Though now I come to look at my BF537 manual (which I've not used
> before) I see it scarcely has anything to say on the subject. Though
> a quick search does reveal some sample code that looks like an ISR
> and definitely has [--SP]=RETI somewhere other than 1st instruction.
>
> So maybe there's something different about BF537, or maybe the
> BF533/BF535 manuals are just wrong. (I suspect the latter, to be
> honest.)
>
> > Hope this helps!
>
> Yes it does, thanks.
>
> Regards
> --
> Adrian Hey
It could well be that the return address that gets pushed to the stack (the
quantity represented as RETI in ADI's assembler) is derived from the program
counter in some way. To take a naive example, it might be "What the program
counter was two machine cycles ago" if two cycles is how long it takes to
jump into the ISR. Obviously, if you waited nine instructions before
executing this, you would push the address of the 7th instruction in your
ISR, rather than the address you wanted, and the wheels would come off your
program spectacularly.

Even if RETI actually referenced a buffer that remembered the program
counter before an interrupt, that buffer might be a CPU resource used by
other instructions for other purposes, and ADI couldn't be bothered
documenting exactly which instructions you're allowed to use in between
jumping to the ISR and pushing RETI.

Steve Conner
www.scopeboy.com
www.optosci.com
Tushar Agrawal wrote:
> With all due respect, Adrian, to get better response from ADI, you have
> to clearly cite the situation that you want to place critical section as
> first few instructions of your ISR after which you want to enable
> nesting. In this case, you will get precise response.

I very much doubt it. I believe the question as asked to ADI technical
support and in this forum was perfectly clear and my reasons for not
wanting to make it the 1st instruction are irrelevant.

I know folk within ADI who really do know what they're talking about
probably have better things to do than provide technical support.
But there seems to little point in providing technical support at
all if users can't rely on..
1 - Getting the question that they actually asked answered, not
some other question.
2 - Getting it answered correctly.

The answers I got were either irrelevant or wrong (typically both).
It's shattered my confidence in the value of ADI tech support.

As for the offending sentence which appears in both the BF535 and BF533
hardware ref manuals..

"The first instruction in an interrupt service routine that supports
nesting must save the return address currently held in RETI by
pushing it onto the Supervisor stack ([--SP]=RETI)."

If this is incorrect (it's not necessary that [--SP]=RETI is the first
instruction) then the errata for both manuals should reflect this.

I find it hard to believe that I'm the first person to have read this
and thought it a bit strange. But I guess it's possible that I am the
first person to have been foolish enough to seriously consider the
possibility that it might be true :-)

Regards
--
Adrian Hey