Searching \ for '[PIC] C18 Interrupts' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'C18 Interrupts'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] C18 Interrupts'
2008\04\08@120735 by Harold Hallikainen

face
flavicon
face
I'm trying to figure out the usage of the #pragma interrupt in C18.

It APPEARS to do two things. It seems that it saves away temporary data
from mainline code, then runs the code in your ISR, then restores the
temporary data, then does a RETFIE 1.

So, how do you handle something where the ISR calls a few functions?  For
example,

#pragma interrupt HighIsrCode

void HighIsrCode(void){
 isr1();
 isr2();
 isr3();
}


#pragma interrupt isr1 // is this needed, or does it mess stuff up?
void isr1(void){
 do stuff here
}

The question is the #pragma interrupt on isr1 (and 2 and 3). It SEEMS this
might be needed so any temporaries used here do not mess up temporaries in
mainline code. However, the RETFIE 1 is certainly undesirable in isr1. It
should only be at the end of HighIsrCode.

Perhaps ALL mainline tempdata is stored on the stack before the start of
HighIsrCode and restored on the way out so we do not need to worry about
overwriting it during HighIsrCode and all functions called by it (they
perhaps write to the same tempdata section used by mainline code, but the
mainline contents are restored on the way out of HighIsrCode).

So, how should isr subfunctions be handled in C18?

THANKS!

Harold





--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\08@123617 by Tamas Rudnai

face picon face
This is called context saving - it saves all the necessary MCU status to
temporary data, then executes your code inside the function, then restores
context and returns with RETFIE. You can call other functions from the ISR
as long as long as your stack can hold the return addresses. You do not need
#pragma stuff for those functions, as the context is already saved and as
you mentioned it would use RETFIE which would re-enable interrupts which you
do not want before returning from ISR - so that would mess up stuff, to
answer to your question.

Tamas


On Tue, Apr 8, 2008 at 4:34 PM, Harold Hallikainen <spam_OUTharoldTakeThisOuTspamhallikainen.org>
wrote:

{Quote hidden}

> -

2008\04\08@123650 by Rikard Bosnjakovic

picon face
On 08/04/2008, Harold Hallikainen <.....haroldKILLspamspam@spam@hallikainen.org> wrote:

>So, how should isr subfunctions be handled in C18?
[...]

Harold,

I have not used the C18-compiler but I downloaded the documentation
från Microchip (DS51288J) and I found this in section 2.9.2.7:

2.9.2.7 NESTING INTERRUPTS
Low-priority interrupts may be nested since active registers are saved onto the
software stack. Only a single instance of a high-priority interrupt
service routine may be
active at a time since these ISR's use the single-level hardware
shadow registers.
If nesting of low-priority interrupts is desired, a statement to set
the GIEL bit can be
added near the beginning of the ISR. See the processor data sheet for details.

Distinguishing between low- and high priority seems to be done with
"#pragma interrupt high_pri_isr" and "#pragma interruptlow
low_pri_isr". So for your example, try adding these lines:

#pragma interruptlow isr1
#pragma interruptlow isr2
#pragma interruptlow isr3

and keep the pragma for HighIsrCode as it is.


--
- Rikard - http://bos.hack.org/cv/

2008\04\08@124742 by John Temples

flavicon
face
On Tue, 8 Apr 2008, Harold Hallikainen wrote:

> I'm trying to figure out the usage of the #pragma interrupt in C18.
>
> It APPEARS to do two things. It seems that it saves away temporary data
> from mainline code, then runs the code in your ISR, then restores the
> temporary data, then does a RETFIE 1.

Yes, that's what it does.

{Quote hidden}

No, don't do that.  C18 takes care of the problem by doing a worst-case
context save if you call a function from an ISR; i.e., it will save
everything that can be saved.  Depending on your application, you'll
find this can result in several hundred cycles of context save and
restore time.  If interrupt latency is a concern, don't call functions
from an ISR.

--
John W. Temples, III

2008\04\08@143218 by John Temples
flavicon
face
On Tue, 8 Apr 2008, Rikard Bosnjakovic wrote:

> Distinguishing between low- and high priority seems to be done with
> "#pragma interrupt high_pri_isr" and "#pragma interruptlow
> low_pri_isr". So for your example, try adding these lines:
>
> #pragma interruptlow isr1
> #pragma interruptlow isr2
> #pragma interruptlow isr3
>
> and keep the pragma for HighIsrCode as it is.

#pragma interruptlow is for low-priority ISRs, not for functions
called from high-priority ISRs.  Functions called from ISRs don't
require any special treatment.

--
John W. Temples, III

2008\04\08@180425 by Harold Hallikainen

face
flavicon
face

> On Tue, 8 Apr 2008, Rikard Bosnjakovic wrote:
>
>> Distinguishing between low- and high priority seems to be done with
>> "#pragma interrupt high_pri_isr" and "#pragma interruptlow
>> low_pri_isr". So for your example, try adding these lines:
>>
>> #pragma interruptlow isr1
>> #pragma interruptlow isr2
>> #pragma interruptlow isr3
>>
>> and keep the pragma for HighIsrCode as it is.
>
> #pragma interruptlow is for low-priority ISRs, not for functions
> called from high-priority ISRs.  Functions called from ISRs don't
> require any special treatment.
>
>

I agree. So, is this sentence from section 2.9.2 of the DS1228J inaccurate?

"Interrupt service routines use a temporary data section that is distinct
from that used by normal C functions. Any temporary data required during
the  interrupt service routine is allocated in this section and is not
overlaid with the temporary locations of other functions, including other
interrupt functions."

So... is interrupt temporary data REALLY saved in a distinct data section,
or are the contents of the temp data section saved on entry into the
interrupt and restored on the way out?

THANKS!

Harold

--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\08@180448 by Harold Hallikainen

face
flavicon
face

{Quote hidden}

Is it REALLY a matter of calling functions from the ISR, or is it a matter
of using #pragma interrupt at all? I suspect that #pragma interrupt saves
all mainline temp data. From then on out, the interrupt can mess with temp
data all it wants, since it will be restored on the way back out of the
main ISR. It SEEMS that a function call from the main ISR would have no
more overhead than any other function call. It seems that the trick is
that, especially if you want to do any math in the interrupt, the
interrupt may mess up mainline temp data in the middle of some mainline
operation (again, especially a math operation).

MANY years ago, I licensed the Microsoft 6800 Basic interpreter for use in
a product. I wanted to use the floating point functions in an interrupt.
So, when I needed to use them in an interrupt, I saved away all the temps
used by the floating point operations, did my operation, then restored the
mainline temps and got out. It SEEMS that C18 is doing something like that
here, though the documentation seems to indicate otherwise, as quoted in a
posting I made a couple minutes ago.

So, at this point, it APPEARS to me that #pragma interrupt saves all
mainline temps, then runs the code, including any function calls, then
restores the saved mainline temps, then does a fast return from interrupt.
The temp save and restore takes a bit of time...

Harold




--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\08@180454 by Harold Hallikainen

face
flavicon
face

> This is called context saving - it saves all the necessary MCU status to
> temporary data, then executes your code inside the function, then restores
> context and returns with RETFIE. You can call other functions from the ISR
> as long as long as your stack can hold the return addresses. You do not
> need
> #pragma stuff for those functions, as the context is already saved and as
> you mentioned it would use RETFIE which would re-enable interrupts which
> you
> do not want before returning from ISR - so that would mess up stuff, to
> answer to your question.
>
> Tamas

That's kind of what I thought, but the C Compilers User's Guide section
2.9.33 has an example of multiple high priority interrupts where they DO
have the #pragma interrupt in front of each (they also have a nosave).
They do not show how these are called, but since we only have a single
high priority interrupt vector, it SEEMS that they must be called from
there, and that temp data is stored there.

Confusing documentation!

Thanks!

Harold


--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\08@183849 by piclist3

flavicon
face
On Tue, 8 Apr 2008, Harold Hallikainen wrote:

> Is it REALLY a matter of calling functions from the ISR

Yes; I wasn't just speculating.  Here's a simple example you can
compile either way.

void    main(void)
{
    double x, y;

    x *= y;
}

#pragma interrupt isr

#if 1

void    isr(void)
{
}

#else

void    func(void)
{
}

void    isr(void)
{
    func();
}

#endif

--
John W. Temples, III

2008\04\08@193929 by Xiaofan Chen

face picon face
On Wed, Apr 9, 2008 at 2:58 AM, Harold Hallikainen
<haroldspamKILLspamhallikainen.org> wrote:
> > No, don't do that.  C18 takes care of the problem by doing a worst-case
> > context save if you call a function from an ISR; i.e., it will save
> > everything that can be saved.  Depending on your application, you'll
> > find this can result in several hundred cycles of context save and
> > restore time.  If interrupt latency is a concern, don't call functions
> > from an ISR.

> Is it REALLY a matter of calling functions from the ISR,

Yes.

Extensive discussion here.
http://forum.microchip.com/tm.aspx?m=279936

It seems that the advise from expert like John Temples is to try to
avoid calling functions inside ISR.

Xiaofan

2008\04\08@224035 by Harold Hallikainen

face
flavicon
face

>> Is it REALLY a matter of calling functions from the ISR,
>
> Yes.
>
> Extensive discussion here.
> http://forum.microchip.com/tm.aspx?m=279936
>
> It seems that the advise from expert like John Temples is to try to
> avoid calling functions inside ISR.
>

That's an interesting discussion. So, if you do an ISR that does no
function calls, the compiler is smart enough to look through the ISR and
determine whether it needs to save away temp data, as I read the
discussion. But, as I further read it, it is NOT smart enough to figure it
out if there are function calls in the ISR. Interesting. Maybe I can use
#includes instead of function calls to try to keep my code somewhat
organized.

Thanks!

Harold



--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\08@235828 by Harold Hallikainen

face
flavicon
face

{Quote hidden}

For the high priority interrupt, it indeed appears that the compiler is
copying the mainline temp data away, then using the mainline temp
locations for its temp data, then copying the mainline data back. It
would, of course, be faster if it just referenced a different area of
memory for interrupts, then readjusted a pointer to temp data on the way
out of the ISR. This SEEMS to be what is described in the manual (quoted
below), but is, apparently, not what the compiler is doing, right?

Harold

>From C18 Users Guide:

Interrupt service routines use a temporary data section that is distinct
from that used
by normal C functions. Any temporary data required during the evaluation of
expressions in the interrupt service routine is allocated in this section
and is not
overlaid with the temporary locations of other functions, including other
interrupt
functions. The interrupt pragmas allow the interrupt temporary data
section to be
named. If this section is not named, the compiler temporary variables are
created in a
udata section named fname_tmp. For example:
void foo(void);
...
#pragma interrupt foo
void foo(void)
{
  /* perform interrupt function here */
}
The compiler temporary variables for interrupt service routine foo will be
placed in the
udata section foo_tmp.






--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2008\04\21@223258 by Harold Hallikainen

face
flavicon
face
Last week I asked about C18 interrupt latency. Today I ran across this
(http://techtrain.microchip.com/webseminars/ArchivedDetail.aspx?Active=152),
which, I believe, explains things well.

Harold


--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

More... (looser matching)
- Last day of these posts
- In 2008 , 2009 only
- Today
- New search...