Fundamentally, you have to save any registers used in the execution
of an ISR in order to save the context of the interrupted code. If
you are writing in assembly you simply push onto the stack whatever
you intend to use in the ISR and then pop the stack to restore the
values.
If you write your ISRs in C then Codewarrior provides #pragma
interrupt and #pragma interrupt saveall for your ISR (the code
launched from the vector table) and #pragma interrupt called for any
code called from the ISR.
#pragma interrupt..... Context saved Return For
------------------------- --------------------- ------ --------
#pragma interrupt only registers used RTI ISR
#pragma interrupt saveall all registers RTI ISR
#pragma interrupt called only registers used RTS non ISR
If you have a simple ISR that doesn't call many routines then
#pragma interrupt is sufficient. You then have to protect any
subroutines launched out of the ISR with #pragma interrupt called.
If you find yourself doing a lot of #pragma interrupt called for a
particular ISR then it is more efficient to save the entire context
once with a #pragma interrupt saveall for the ISR than saving many
partial contexts for the ISR and all the called routines.
Reply by Yochum, William●April 12, 20042004-04-12
> If you have a simple ISR that
doesn't call many routines then > #pragma interrupt is
sufficient.
This is
fundamentally correct, but I do think it is a compiler defect when an ISR
routine written in "C", which does not explicitly call a
subroutine, fails because the compiler implicitly substitutes a
run-time library routine which is not interrupt safe.
This is the
case if you perform certain types of math in your ISR.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Friday, April 09, 2004 7:51 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: modulus (%) affects interrupts?
Fundamentally, you have to save any registers used in the
execution of an ISR in order to save the context of the interrupted
code. If you are writing in assembly you simply push onto the stack
whatever you intend to use in the ISR and then pop the stack to restore
the values.
If you write your ISRs in C then Codewarrior
provides #pragma interrupt and #pragma interrupt saveall for your ISR (the
code launched from the vector table) and #pragma interrupt called for any
code called from the ISR.
#pragma
interrupt..... Context
saved Return For ------------------------- --------------------- ------ -------- #pragma interrupt only
registers used RTI ISR #pragma
interrupt saveall all registers
RTI ISR #pragma interrupt called only
registers used RTS non ISR
If you
have a simple ISR that doesn't call many routines then #pragma
interrupt is sufficient. You then have to protect any subroutines
launched out of the ISR with #pragma interrupt called.
If you find
yourself doing a lot of #pragma interrupt called for a particular ISR then
it is more efficient to save the entire context once with a #pragma
interrupt saveall for the ISR than saving many partial contexts for the
ISR and all the called routines.
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
I was wondering. If you have a C function that you want to use as an
ISR but also call from the main loop does "#pragma interrupt" work
for both? Does it require 2 different functions? What are the
implications.
Thanks,
Pete
--- In , "Michael W. Mann"
<Michael.W.Mann@M...> wrote: > Fundamentally, you have to save any registers used
in the execution
> of an ISR in order to save the context of the interrupted code. If
> you are writing in assembly you simply push onto the stack whatever
> you intend to use in the ISR and then pop the stack to restore the
> values.
>
> If you write your ISRs in C then Codewarrior provides #pragma
> interrupt and #pragma interrupt saveall for your ISR (the code
> launched from the vector table) and #pragma interrupt called for any > code called from the ISR.
>
> #pragma interrupt..... Context saved Return For
> ------------------------- --------------------- ------ --------
> #pragma interrupt only registers used RTI ISR
> #pragma interrupt saveall all registers RTI ISR
> #pragma interrupt called only registers used RTS non ISR
>
> If you have a simple ISR that doesn't call many routines then
> #pragma interrupt is sufficient. You then have to protect any
> subroutines launched out of the ISR with #pragma interrupt called.
>
> If you find yourself doing a lot of #pragma interrupt called for a
> particular ISR then it is more efficient to save the entire context
> once with a #pragma interrupt saveall for the ISR than saving many
> partial contexts for the ISR and all the called routines.
Reply by Corey, Rick●April 12, 20042004-04-12
I'm not even doing the math (%) inside the ISR - the % is
in main.
Rick
Corey
-----Original Message----- From: Yochum, William
[mailto:w...@microwavedata.com] Sent: Monday, April 12, 2004 9:57
AM To: Michael W. Mann; m...@yahoogroups.com Subject:
RE: [motoroladsp] Re: modulus (%) affects interrupts?
> If you have a simple ISR that
doesn't call many routines then > #pragma interrupt is
sufficient.
This is
fundamentally correct, but I do think it is a compiler defect when an ISR
routine written in "C", which does not explicitly call a
subroutine, fails because the compiler implicitly substitutes a
run-time library routine which is not interrupt safe.
This is the
case if you perform certain types of math in your ISR.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Friday, April 09, 2004 7:51 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: modulus (%) affects interrupts?
Fundamentally, you have to save any registers used in the
execution of an ISR in order to save the context of the interrupted
code. If you are writing in assembly you simply push onto the stack
whatever you intend to use in the ISR and then pop the stack to restore
the values.
If you write your ISRs in C then Codewarrior
provides #pragma interrupt and #pragma interrupt saveall for your ISR (the
code launched from the vector table) and #pragma interrupt called for any
code called from the ISR.
#pragma
interrupt..... Context
saved Return For ------------------------- --------------------- ------ -------- #pragma interrupt only
registers used RTI ISR #pragma
interrupt saveall all registers
RTI ISR #pragma interrupt called only
registers used RTS non ISR
If you
have a simple ISR that doesn't call many routines then #pragma
interrupt is sufficient. You then have to protect any subroutines
launched out of the ISR with #pragma interrupt called.
If you find
yourself doing a lot of #pragma interrupt called for a particular ISR then
it is more efficient to save the entire context once with a #pragma
interrupt saveall for the ISR than saving many partial contexts for the
ISR and all the called routines.
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
--- In , "Pete Becher" <pbecher@d...>
wrote: > Hi All,
>
> I was wondering. If you have a C function that you want to use as an > ISR but also call from the main loop does
"#pragma interrupt" work
> for both? Does it require 2 different functions? What are the
> implications.
There are times you can get away with calling a routine that
is "#pragma interrupt" enabled from outside of an ISR processing
thread.
Basically when you call such a routine you are needlessly saving and
restoring the core's registers. This is just inefficient. But at
the return you are also enabling interrupts. That is the difference
between an RTI (return from interrupt) instead RTS (return from
subroutine). The #pragma enabled routine will return via RTI. If
enabling interrupts at that time causes on harm to your application
then you can get away with it. But be sure that it doesn't renable
interrupts when you desire to keep them masked.
If you don't want this risk then you can code up two separate
routines in C. You can also code the routine in assembly and check
the SR to see if interrupts are enabled or masked. Then you can save
or not save context accordingly. >
> Thanks,
> Pete
Reply by Yochum, William●April 13, 20042004-04-13
Correct me if I'm wrong, but strictly speaking
the difference between an "RTI" and an "RTS" is restoration of the SR
register. This MIGHT reenable interrupts, but it doesn't
necessarily do so, right?
If a "#pragma interrupt" routine was called from the
main loop it would simply restore the interrupt status that was active at that
time. If interrupts were off they should remain off.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Tuesday, April 13, 2004 2:50 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: #pragma interrupt / modulus (%) affects
interrupts?
--- In m...@yahoogroups.com, "Pete Becher" <pbecher@d...>
wrote: > Hi All, > > I was wondering. If
you have a C function that you want to use as an > ISR but also
call from the main loop does "#pragma interrupt" work > for both?
Does it require 2 different functions? What are the >
implications.
There are times you can get away with calling a routine
that is "#pragma interrupt" enabled from outside of an ISR processing thread.
Basically when you call such a routine you are
needlessly saving and restoring the core's registers. This is
just inefficient. But at the return you are also enabling
interrupts. That is the difference between an RTI (return from
interrupt) instead RTS (return from subroutine). The #pragma enabled
routine will return via RTI. If enabling interrupts at that time
causes on harm to your application then you can get away with it.
But be sure that it doesn't renable interrupts when you desire to
keep them masked.
If you don't want this risk then you can code
up two separate routines in C. You can also code the routine in
assembly and check the SR to see if interrupts are enabled or
masked. Then you can save or not save context accordingly. >
> Thanks, > Pete
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
RTI
usually restores the SR by popping it off the stack.
If you
encounter an RTI, but you never pushed the SR onto the stack in a matching "go
to ISR" mechanism, the RTI should break the stack most
fatally.
Maybe
you could set up a "callback function" (non-ISR, with no RTI). Have the
ISR itself do nothing but call the callback function. Since the ISR
shell would contain the RTI, main could call it, too, without blowing the
stack.
Of
course the callback function would have to be re-entrant or have ISR
protection.
(Maybe
callback is the wrong term if it is called directly from inside the
ISR.)
Rick
Corey
-----Original Message----- From: Yochum, William
[mailto:w...@microwavedata.com] Sent: Tuesday, April 13, 2004 3:23
PM To: Michael W. Mann; m...@yahoogroups.com Subject:
Re: #pragma interrupt / modulus (%) affects interrupts?
Correct me if I'm wrong, but strictly speaking
the difference between an "RTI" and an "RTS" is restoration of the SR
register. This MIGHT reenable interrupts, but it doesn't
necessarily do so, right?
If a "#pragma interrupt" routine was called from the
main loop it would simply restore the interrupt status that was active at that
time. If interrupts were off they should remain off.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Tuesday, April 13, 2004 2:50 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: #pragma interrupt / modulus (%) affects
interrupts?
--- In m...@yahoogroups.com, "Pete Becher" <pbecher@d...>
wrote: > Hi All, > > I was wondering. If
you have a C function that you want to use as an > ISR but also
call from the main loop does "#pragma interrupt" work > for both?
Does it require 2 different functions? What are the >
implications.
There are times you can get away with calling a routine
that is "#pragma interrupt" enabled from outside of an ISR processing thread.
Basically when you call such a routine you are
needlessly saving and restoring the core's registers. This is
just inefficient. But at the return you are also enabling
interrupts. That is the difference between an RTI (return from
interrupt) instead RTS (return from subroutine). The #pragma enabled
routine will return via RTI. If enabling interrupts at that time
causes on harm to your application then you can get away with it.
But be sure that it doesn't renable interrupts when you desire to
keep them masked.
If you don't want this risk then you can code
up two separate routines in C. You can also code the routine in
assembly and check the SR to see if interrupts are enabled or
masked. Then you can save or not save context accordingly. >
> Thanks, > Pete
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
It doesn't work generally, but in the DSP56800
family:
JSR saves SP & SR on the
stack.
RTS pops SP & SR from the stack, restores
SP but discards SR.
RTI pops SP & SR from the stack,
and restores both registers.
So that's why the RTI is safe for a JSR
call.
-----Original Message----- From: Corey, Rick
[mailto:R...@dpconline.com] Sent: Tuesday, April 13, 2004 3:34 PM To: 'Yochum, William'; Michael W. Mann;
m...@yahoogroups.com Subject: RE: #pragma interrupt / modulus (%)
affects interrupts?
Hi
RTI
usually restores the SR by popping it off the stack.
If you
encounter an RTI, but you never pushed the SR onto the stack in a matching "go
to ISR" mechanism, the RTI should break the stack most
fatally.
Maybe
you could set up a "callback function" (non-ISR, with no RTI). Have the
ISR itself do nothing but call the callback function. Since the ISR
shell would contain the RTI, main could call it, too, without blowing the
stack.
Of
course the callback function would have to be re-entrant or have ISR
protection.
(Maybe
callback is the wrong term if it is called directly from inside the
ISR.)
Rick
Corey
-----Original Message----- From: Yochum, William
[mailto:w...@microwavedata.com] Sent: Tuesday, April 13, 2004 3:23
PM To: Michael W. Mann; m...@yahoogroups.com Subject:
Re: #pragma interrupt / modulus (%) affects interrupts?
Correct me if I'm wrong, but strictly speaking
the difference between an "RTI" and an "RTS" is restoration of the SR
register. This MIGHT reenable interrupts, but it doesn't
necessarily do so, right?
If a "#pragma interrupt" routine was called from the
main loop it would simply restore the interrupt status that was active at that
time. If interrupts were off they should remain off.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Tuesday, April 13, 2004 2:50 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: #pragma interrupt / modulus (%) affects
interrupts?
--- In m...@yahoogroups.com, "Pete Becher" <pbecher@d...>
wrote: > Hi All, > > I was wondering. If
you have a C function that you want to use as an > ISR but also
call from the main loop does "#pragma interrupt" work > for both?
Does it require 2 different functions? What are the >
implications.
There are times you can get away with calling a routine
that is "#pragma interrupt" enabled from outside of an ISR processing thread.
Basically when you call such a routine you are
needlessly saving and restoring the core's registers. This is
just inefficient. But at the return you are also enabling
interrupts. That is the difference between an RTI (return from
interrupt) instead RTS (return from subroutine). The #pragma enabled
routine will return via RTI. If enabling interrupts at that time
causes on harm to your application then you can get away with it.
But be sure that it doesn't renable interrupts when you desire to
keep them masked.
If you don't want this risk then you can code
up two separate routines in C. You can also code the routine in
assembly and check the SR to see if interrupts are enabled or
masked. Then you can save or not save context accordingly. >
> Thanks, > Pete
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
In the
56803, somewhere around version 5.0.?, checking the "deferred inlining" checkbox
would cause an RTS to be placed in an ISR, and an RTI into the next function in
the file with the ISR. That blew up vigorously and immediately - I always
assumed it was corrupting the stack.
Rick
Corey
-----Original Message----- From: Yochum, William
[mailto:W...@microwavedata.com] Sent: Tuesday, April 13, 2004 4:30
PM To: Corey, Rick Cc: m...@yahoogroups.com Subject: RE: #pragma interrupt / modulus (%) affects interrupts?
It doesn't work generally, but in the DSP56800
family:
JSR saves SP & SR on the
stack.
RTS pops SP & SR from the stack, restores
SP but discards SR.
RTI pops SP & SR from the stack,
and restores both registers.
So that's why the RTI is safe for a JSR
call.
-----Original Message----- From: Corey, Rick
[mailto:R...@dpconline.com] Sent: Tuesday, April 13, 2004 3:34 PM To: 'Yochum, William'; Michael W. Mann;
m...@yahoogroups.com Subject: RE: #pragma interrupt / modulus (%)
affects interrupts?
Hi
RTI
usually restores the SR by popping it off the stack.
If you
encounter an RTI, but you never pushed the SR onto the stack in a matching "go
to ISR" mechanism, the RTI should break the stack most
fatally.
Maybe
you could set up a "callback function" (non-ISR, with no RTI). Have the
ISR itself do nothing but call the callback function. Since the ISR
shell would contain the RTI, main could call it, too, without blowing the
stack.
Of
course the callback function would have to be re-entrant or have ISR
protection.
(Maybe
callback is the wrong term if it is called directly from inside the
ISR.)
Rick
Corey
-----Original Message----- From: Yochum, William
[mailto:w...@microwavedata.com] Sent: Tuesday, April 13, 2004 3:23
PM To: Michael W. Mann; m...@yahoogroups.com Subject:
Re: #pragma interrupt / modulus (%) affects interrupts?
Correct me if I'm wrong, but strictly speaking
the difference between an "RTI" and an "RTS" is restoration of the SR
register. This MIGHT reenable interrupts, but it doesn't
necessarily do so, right?
If a "#pragma interrupt" routine was called from the
main loop it would simply restore the interrupt status that was active at that
time. If interrupts were off they should remain off.
-----Original Message----- From: Michael W. Mann [mailto:M...@Motorola.Com] Sent:
Tuesday, April 13, 2004 2:50 PM To: m...@yahoogroups.com Subject: [motoroladsp] Re: #pragma interrupt / modulus (%) affects
interrupts?
--- In m...@yahoogroups.com, "Pete Becher" <pbecher@d...>
wrote: > Hi All, > > I was wondering. If
you have a C function that you want to use as an > ISR but also
call from the main loop does "#pragma interrupt" work > for both?
Does it require 2 different functions? What are the >
implications.
There are times you can get away with calling a routine
that is "#pragma interrupt" enabled from outside of an ISR processing thread.
Basically when you call such a routine you are
needlessly saving and restoring the core's registers. This is
just inefficient. But at the return you are also enabling
interrupts. That is the difference between an RTI (return from
interrupt) instead RTS (return from subroutine). The #pragma enabled
routine will return via RTI. If enabling interrupts at that time
causes on harm to your application then you can get away with it.
But be sure that it doesn't renable interrupts when you desire to
keep them masked.
If you don't want this risk then you can code
up two separate routines in C. You can also code the routine in
assembly and check the SR to see if interrupts are enabled or
masked. Then you can save or not save context accordingly. >
> Thanks, > Pete
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
Metrowerks Tech Support has done an excellent job of chasing this down -
they put a _lot_ of time into it and several engineers got involved.
We've been communicating back and forth for several weeks, and several
Motorola engineers also put time in. Thanks and praise to Metrowerks Tech
Support!
There was nothing wrong at all with their modulus routines - the problem was
in my code. I had not interrupt-protected a local variable's
initialization, and the ISR very repeatably corrupted that variable when my
main loop timing was changed by the 32-bit modulus routine. That depleted
my pool of buffers so much that transmission slowed down by a factor of
1,000.
Metrowerks Tech Support really went the extra mile - or several extra miles
- to identify the cause of the problem, even thought they were pretty sure
from the beginning that their modulus routines were not at fault. Many
thanks to Han, Roberts and Chris!
Here's what I forgot to protect (slightly edited): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
static ushort AddMsgToTxList ( volatile struct sCanPktBuffer
**ppsPacketsToInsert )
{
volatile struct sCanPktBuffer *psInsertHere=gpMultiPkt_ToTxListHead;
// ^ this initialization got corrupted if the ISR hit
during the next 4 lines ^
// My FlexCAN Mailbox interrupt service routine uses and
alters gpMultiPkt_ToTxListHead
if ( *ppsPacketsToInsert == NULL )
return ( 0 );
LED4_Off();
LED5_On();
// ***** DISABLE ALL CAN Tx IRQs
// ***** protect against concurrent IRQ access to
gpMultiPkt_ToTxListHead *******
clrRegBits( *IPR3, 0x0300 ); // disable FCAN_MB_IRQ by
setting IPL to 0
// however, it is too late! The variable "psInsertHere" needs to be
initialized inside the ISR-protected critical section
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
A second issue they pointed out is that one should add some NOPs in order to
provide enough delay to ensure the interrupt is really disabled. I found
the same thing in one test: without the NOPs, I could still corrupt my pool
of buffers. Adding the NOPs protected them.
BETTER:
clrRegBits( *IPR3, 0x0300 ); // disable FCAN_MB_IRQ by setting IPL to 0
asm(nop);
asm(nop);
asm(nop); // wait long enough to be sure the IRQ is really disabled
I made two macros so I won't make this mistake again:
#define DISABLE_CAN_MBOX_IRQ { clrRegBits(*IPR3, 0x0300); asm(nop);
asm(nop); asm(nop); }
#define RESTORE_CAN_MBOX_IRQ { setRegBits(*IPR3, 0x0100 ); } // set CAN
Mailbox IPL to 1 for Priority Level 0
I'm also going to go through some older code to look for instances where
I
need to add NOPs to allow interrupts time to be completely disabled.
I'm eating Humble Pie now.
Rick Corey
-----Original Message-----
From: Corey, Rick
Sent: Thursday, April 08, 2004 8:15 AM
To: 'MW Ron';
Cc: Corey, Rick
Subject: RE: [motoroladsp] modulus (%) affects interrupts?
Hi Ron
The modulus problem is not a red herring. I have weeks of testing where:
'without the % it works fine for days" and 20-30 cycles of "add
the % and
break it - remove the % and it works fine for as long as I run the
test".
The most recent test is "make both arguments ushorts and run
overnight" vs.
"if either is a long it will crash very quickly". This is conclusive.
The
two variables used in the % statement are not used anywhere else in the
program and are local to the routine that uses them. It is not a red
herring.
Rick Corey
-----Original Message-----
From: MW Ron [mailto:]
Sent: Wednesday, April 07, 2004 5:10 PM
To:
Cc: Corey, Rick
Subject: Re: [motoroladsp] modulus (%) affects interrupts?
Importance: Low
Rick Corey wrote:
> Can anyone imagine a way that a modulus operator
(%) in the main loop could > slow down an ISR? I'm stumped.
An ISR will not call any function in the main loop or be affected by it in
anyway. The ISR should run to completion before going back to the main loop.
The engineers that looked at this are guessing that the time to complete the
ISR you wrote might depend on some data structure that could be corrupted by
something done in the mainloop. The mod library itself would not do this.
It is likely something in your code. Perhaps the modulus operation is just
a red herring?