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 #include <stdio.h> 00015 #include "task.h" 00016 #include "pq.h" 00017 00018 /************************************************************************** 00019 ** PendSemaphore (Lock) 00020 ** This function checks the value of the semaphore. 00021 ** 1. Check Value EventCount 00022 ** 2. Decrement the value of the EventCount 00023 ** 3. If Value in Step 1 was greater than 0, then return 00024 ** 4. If Value in Step 1 was less than or equal to 0 THEN 00025 ** 5. Add task to list of pending tasks 00026 ** 6. Do a Context Switch 00027 ** 00028 ** parameters: 00029 ** e.............pointer to event control block for semaphore 00030 ** Timeout.......Number of system timer ticks to wait for semaphore to post 00031 ** 00032 ** return value: 00033 ** Inidicates status of operation. 0 or positive is normal, 00034 ** negative is error 00035 **************************************************************************/ 00036 00037 int PendSemaphore(ECB *e, int Timeout) //wait for semaphore availiable 00038 { 00039 char sr; 00040 int retval; 00041 sr = Disable(); 00042 if(e->EventCount > 0) /* is resource availiable? */ 00043 { 00044 /* yes */ 00045 --e->EventCount; 00046 Enable(sr); 00047 retval = EVENT_NOERROR; //everything is peachy 00048 } 00049 else 00050 { 00051 /* no */ 00052 --e->EventCount; 00053 if(!e->task_h) //make linked list of waiting tasks 00054 e->task_h = CurrentTask; 00055 else 00056 e->task_t->next = CurrentTask; 00057 e->task_t = CurrentTask; 00058 CurrentTask->status = EVENT_NOERROR; 00059 if(e->SemaphoreMode) 00060 CurrentTask->timeout = Timeout; 00061 00062 //swap out current task 00063 00064 CurrentTask->TimeStamp = TStamp; 00065 if(Delete(&ActiveTasks,(void **)&NextTask)) //get highest priority task 00066 { 00067 NextTask->TcbSwaps++; 00068 DoSwap(); //do context swap 00069 } 00070 else 00071 { 00072 CurrentTask->status = EVENT_NOTASKS; 00073 } 00074 //----------------------- 00075 // Pend is over, check status 00076 //----------------------- 00077 00078 Enable(sr); 00079 retval = CurrentTask->status; //return this value 00080 } 00081 return retval; 00082 }