|
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. |
[Prev in Thread] | Current Thread | [Next in Thread] |