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

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

Re: [avr-gcc-list] Pre-prologue and post-epilogue asm code insertion?


From: Ruud Vlaming
Subject: Re: [avr-gcc-list] Pre-prologue and post-epilogue asm code insertion?
Date: Tue, 21 Oct 2008 09:57:42 +0200
User-agent: KMail/1.9.1

On Tuesday 21 October 2008 03:55, Mark Litwack wrote:

> Is there an easy way to insert a few lines of asm code in an

> ISR before the prologue starts (at the ISR entry) and then

> some additional code after the epilogue (right before the

> RETI)?

I had a similar challenge and there are three 'solutions':

(1) This is the direct awnser to your question. Yes it is possible.

If you use gcc 4.2.x you can hack the backend to insert

your code in parts where the prolog / epilog is generated.

It is not very difficult, but not the first choice since it requires

a recompile of gcc. But for me it worked. If you use gcc 4.3.x

it might also be possible, but i have no experience yet. The

latter version is organized differently. Btw, i would do this

as a last resort.

(2) You can write a method wrapper for methodes that need

dressing before gcc alters the registers or anything. Just like this

(from the OS i wrote)

void taskYield(void) __attribute__ ((naked, noinline));

void taskYield(void)

{ portResqueGlobalInterruptState();

portSaveContext();

portJump(privYieldBody); }

static void privYieldBody(void) __attribute__((used, bikini));

void privYieldBody(void)

{ privInitOs();

privTrace(eventAPIcallTaskYield);

privEnterOS(defActionTaskStateSwitch); }

In this example you see that the Yieldbody is wrapped so

if you call taskYield you can do some things before

the real work starts. Of course you must manually catch the

return address and place it on the correct spot on the stack.

(3) If you want to minimize the handwork you can 'misuse' the

signal attribute for your handling function and declare the

interrupt handler naked. Gcc will complain that you misspeld

a signal handler but will still generate all necessary code to

save registers etc. Only thing you have to keep in mind is

that the signal handler will reactivate interrupts, so they

must be deactivated directly afterwards.

/* The gcc warning is ok, we misuse the gcc facilities to make sure all registers are saved. */

void HandlePinChange(void) __attribute__ ((signal));

void HandlePinChange(void)

{ isrStackCheck(2);

/* Do your stuff here */ }

void SIG_PIN_CHANGE(void) __attribute__ ((signal, naked, used, externally_visible));

void SIG_PIN_CHANGE(void)

{ isrBegin();

HandlePinChange();

/* Make sure you disable your interrupts immediately */

taskDisableGlobalInterrupts();

isrEndYield(); }

Hope this helps. As said, i faced similar challenges when i was

writing my OS. Maybe it helps you further to have a look at my

code to see how i handled these. You do not need to download it but

can see it directly over over doxygen.

http://www.femtoos.org/doxy/index.html

Good luck

Ruud.


reply via email to

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