00001 00002 // This file is compiled with WinAVR version 4.1.2 00003 // 00004 // These routines mess with the stack 00005 // 00006 // you must use either of these optimizations: 00007 // -O1 00008 // -O3 00009 // -O2 00010 // 00011 // Whatever you do, do NOT use -O0....it will NOT work 00012 // 00013 // ///////////////////////////////////////////////////////////////////////////////////////// 00014 00015 #include "task.h" 00016 #include "pq.h" 00017 00024 00025 volatile int InterruptCount; 00026 volatile int Blocking; 00064 void ExitInterrupt(void) 00065 { 00066 /*--------------------------------------------------------------------- 00067 * * 00068 * ExitInterrupt * 00069 * * 00070 * This function keeps track of the nesting level of interrupts * 00071 * If nesting level is == 0, then do a context swap to the highest * 00072 * priority task * 00073 * * 00074 * WARNING! * 00075 * Don't mess with this function, you will be sorry * 00076 * Adding any local variables or passed parameters * 00077 * Messes with the stack. IrqSwap alters the stack and * 00078 * if it is different from what it expects, it will mess * 00079 * up the stack. * 00080 * * 00081 * Hey, you don't even need to add any local variables, just add a * 00082 * Little bit more code and it will mess things up. Always check * 00083 * the listing file to see how much might get pushed onto the stack * 00084 * * 00085 * * 00086 * ExitInterrupt will alocate at least 4 bytes on the stack probably * 00087 * for sr, depending on how it does this. * 00088 * Currently ExitInterrupt uses 4 bytes on the stack to save various * 00089 * registers that it doesn't really have to * 00090 * * 00091 * Currently IrqSwap() needs to remove 6 bytes from stack for the * 00092 * ATmega2561 or 4 bytes for the ATmega128 (using -O1,-O2,-O3 or -Os * 00093 * * 00094 ----------------------------------------------------------------------*/ 00095 --InterruptCount; 00096 if(!InterruptCount && !Blocking) //don't swap if nested 00097 { 00098 CurrentTask->TimeStamp = TStamp; 00099 Replace(&ActiveTasks,(void **)&NextTask,CurrentTask); 00100 if(NextTask != CurrentTask) 00101 { 00102 NextTask->TcbSwaps++; 00103 IrqSwap(); //interrupts will be re-enabled right after this 00104 } 00105 } 00106 } 00107