avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] On getting an ISR leaner with GCC


From: dlc
Subject: Re: [avr-gcc-list] On getting an ISR leaner with GCC
Date: Tue, 30 Dec 2008 09:50:52 -0700
User-agent: Thunderbird 2.0.0.18 (Macintosh/20081105)

All,

Stu Bell wrote:
If you look in the avr-libc manual under Frequently Asked Questions you
can find FAQ #3: "How to permanently bind a variable to a register".
That allows you to assign particular registers to variables, although
care must be used when using the avr-libc library functions.

This was useful information but I found that simply binding a variable to a register or register pair is not good enough, using the ones the FAQ mentions as safe isn't always safe. The caveat "care must be used when using the avr-libc library functions" all but negates the value of the register declaration if something in libc uses it. Nowhere did I find a list of registers that nothing uses (which, truth be told, I would have been surprised to find anyway) so that declaration is _probably_ only useful if you don't use anything in libc.

I agree with Dave that calling functions in an ISR is a particularly bad
idea if youwant to save cycles.  But I would also start looking at what
you are trying to do and see if there was some other way to do it.  10
uS is not much time - 160 cycles at 16 MHz.  Is there some way to either
slow the interrupts down or to assign some timer function to the duty?
If all you are doing is counting, tying the signal to one of the counter
clock lines allows you to count wihtout interrupting the processor.  If
this is a small function in a large application, allocating registers
will be difficult since you will need to export the assigned variable
(and it's register assignment) to all code modules.  You might also want
to look at the Event function in the Xmega series.

Definitely, I'm no noob to ISR's - No functions are called. I needed a 10us resolution for a hobby servo timing so that was pretty much fixed. I was using that IRQ to do double duty by setting a background time keeper value as well.

You can also declare the ISR "naked" which will cause the
prologue/epilogue to be omitted, but then the onus of saving only those
registers needed falls to you.  If the ISR is simple, as you said, a
little assembly might be just the trick.

I'm going to experiment with this a bit, I like this ability since I _know_ what variables I'll be playing with. I can set aside a global temp variable to use whose value does not need saved and handle the essential register saves myself.

Fun stuff,
DLC

Best regards, Stu Bell DataPlay (DPHI, Inc.)
The subject says it all. I've an ISR that is using too many cycles for something that kicks every 10us. I'm very experienced with the PIC and know how to specify registers that are not touched outside of the ISR to avoid lots of "push-n-pop" actions. Is there something like that in the AVR toolchain or am I going to have to resort to assembly to get this thing leaned down? I'd like to create some memory that is dedicated to the ISR such that the compiler knows that it doesn't need to be saved. Also a way to get
scratchpad memory
assigned to it for some basic math that I don't want to have to use the overhead of push/pop. Can anyone offer insight into how I can lean an ISR down or what sorts of operations or memory
types to avoid there with avr-gcc?

In my experience, the number one thing to do to make ISRs leaner is to avoid function calls from within the ISR. inline function calls are ok, it's the ones to an external function that isn't. You just have to look at the assembly code generated to see the difference.

If the ISR doesn't do any function calls, then it will only push/pop the bare minimum of registers. If the ISR has to do a function call, then it needs to push/pop all of the registers that "any old" C function might touch.

--
-------------------------------------------------
Dennis Clark          TTT Enterprises
www.techtoystoday.com
-------------------------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]