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 // If in the future, a newer version (or older version for that matter) does not 00014 // work properly, the code might have to be changed. In particular, void IrqSwap(void) 00015 // 00016 // The following line in IrqSwap may need to be changed, in particular: 00017 // "adiw r24,6 \n\t" //add 6 (remove irrelavent calls) 00018 // 00019 // This line adds 6 to the stack pointer, and depending on how much the compiler 00020 // pushes on stacks, this value could change. For instance, to make the -O0 option 00021 // work correctly, you need to change this value to 8 00022 // ///////////////////////////////////////////////////////////////////////////////////////// 00023 00024 #include "task.h" 00025 00026 void IrqSwap(void) __attribute__ ( ( naked ) ); 00027 00028 void IrqSwap(void) 00029 { 00030 //----------------------------- 00031 // next, we need to adjust 00032 // the size of the stack 00033 // ignore return addresses on 00034 // stack to IrqSwap and 00035 // Exit Interrupt 00036 //----------------------------- 00037 asm volatile ( 00038 "in r25,__SP_H__ \n\t" //get the stack pointer 00039 "in r24,__SP_L__ \n\t" 00040 "adiw r24,6 \n\t" //add 6 (remove irrelavent calls) 00041 "lds r26, CurrentTask \n\t" //get address of current task 00042 "lds r27, CurrentTask + 1 \n\t" 00043 "st x+, r24 \n\t" //save stack pointer in TCB 00044 "st x+, r25 \n\t" 00045 ); 00046 CurrentTask = NextTask; 00047 RESTORE_CONTEXT(); //restore next task context 00048 }