Main Page   Modules   Data Structures   File List   Globals  

time.c

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2002, 2003, Oliver Tscherwitschke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice,
00009    this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright notice,
00011    this list of conditions and the following disclaimer in the documentation
00012    and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014    derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
00017 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00019 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00035 #include <avr/signal.h>
00036 #include <stddef.h>
00037 #include <avr/interrupt.h>
00038 
00039 #include "otos_cfg.h"
00040 #include "otos_def.h"
00041 #include "types.h"
00042 #include "task.h"
00043 #include "time.h"
00044 
00045 
00046 
00047 /* the system tick counter */
00048 uint32_t volatile g_ticks; 
00049 
00050 /* tick hook function */
00051 void (*g_pTickHook)(void);          /* initialized to NULL by C runtime system */
00052 
00053 
00069 uint32_t otosGetTicks(void)
00070 {
00071     uint32_t ticks;
00072     uint8_t  iStat;    
00073 
00074 
00075     iStat = SREG;           /* save cpu status register         */
00076     cli();                  /* disable interrupts               */
00077     ticks = g_ticks;        /* read tick counter                */
00078     SREG = iStat;           /* restore status register (i-bit)  */
00079     
00080     return ticks;
00081 }
00082 
00083 
00092 void otosSleep(uint32_t ticks)
00093 {
00094     if (ticks == 0)
00095         otosScheduler(SCHED_NORM);
00096     else
00097     {
00098         cli();
00099         g_pRunningTask->sleepTicks = ticks;     /* number of ticks to sleep */
00100         otosBlock();                            /* block task */        
00101     }    
00102 }
00103 
00111 void otosDelay(uint32_t ticks)
00112 {
00113     uint32_t startTime;
00114 
00115     
00116     startTime = otosGetTicks();
00117     while (otosGetTickDiff(startTime) < ticks);
00118 }
00119 
00120 
00130 void otosSetTickHook(void (*pFunc)(void))
00131 {
00132     uint8_t  iStat;    
00133 
00134 
00135     iStat = SREG;           /* save cpu status register         */
00136     cli();
00137     g_pTickHook = pFunc;
00138     SREG = iStat;           /* restore status register (i-bit)  */
00139 }
00140 
00141 
00149 uint32_t otosGetTickDiff(uint32_t earlier)
00150 {
00151     uint32_t now = otosGetTicks();
00152     
00153     
00154     if (now >= earlier)
00155         return now - earlier;
00156     else
00157         return 0xffffffff - earlier + now + 1;
00158 }
00159 
00160 
00161 
00169 #if (defined __AVR_ATmega103__) || (defined __AVR_ATmega128__)
00170     #define OTOS_TIMER_IRQ SIG_OUTPUT_COMPARE0
00171 #elif (defined __AVR_ATmega163__) || (defined __AVR_ATmega323__)
00172     #define OTOS_TIMER_IRQ SIG_OUTPUT_COMPARE2
00173 #endif
00174 
00182 SIGNAL(OTOS_TIMER_IRQ)
00183 {
00184     OtosTask* pTask;
00185     OtosTask* pNextTask;
00186     
00187 
00188     ++g_ticks;
00189 
00190     /* call tick hook function if specified */
00191     if (g_pTickHook != NULL)
00192         (*g_pTickHook)();
00193 
00194     /* check blocked queue if a task must be woken up */
00195     pTask = g_pBlockedQueue;
00196     while (pTask != NULL)
00197     {
00198         pNextTask = pTask->pNext;           /* remember next task, because after wakeup it is not valid any more */
00199         if (pTask->sleepTicks != 0)         /* task is sleeping */
00200         {
00201             if (--pTask->sleepTicks == 0)   /* dec sleep_ticks and check if it must be woken up */
00202             {
00203                 otosWakeup(pTask);
00204                 g_performDispatch = TRUE;
00205             }
00206         }
00207         pTask = pNextTask;
00208     }
00209     
00210     /* handle preemtive multitasking */
00211     if (g_timeSliceTicks)                               /* g_timeSliceTicks != 0: use preemtive m/t */
00212     {
00213         if (--g_timeSliceCounter == 0)                  /* time slice expired */
00214         {
00215             g_timeSliceCounter = g_timeSliceTicks;
00216             g_performDispatch = TRUE;                   /* scheduler will do round robin */
00217         }
00218     }
00219     
00220     /* call scheduler if g_performDispatch is TRUE */
00221     if (g_performDispatch == TRUE)
00222         otosScheduler(SCHED_NORM);
00223 }
00224 

Generated on Sat Jan 25 18:41:43 2003 for otOS by doxygen1.3-rc2