00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00048 uint32_t volatile g_ticks;
00049
00050
00051 void (*g_pTickHook)(void);
00052
00053
00069 uint32_t otosGetTicks(void)
00070 {
00071 uint32_t ticks;
00072 uint8_t iStat;
00073
00074
00075 iStat = SREG;
00076 cli();
00077 ticks = g_ticks;
00078 SREG = iStat;
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;
00100 otosBlock();
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;
00136 cli();
00137 g_pTickHook = pFunc;
00138 SREG = iStat;
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
00191 if (g_pTickHook != NULL)
00192 (*g_pTickHook)();
00193
00194
00195 pTask = g_pBlockedQueue;
00196 while (pTask != NULL)
00197 {
00198 pNextTask = pTask->pNext;
00199 if (pTask->sleepTicks != 0)
00200 {
00201 if (--pTask->sleepTicks == 0)
00202 {
00203 otosWakeup(pTask);
00204 g_performDispatch = TRUE;
00205 }
00206 }
00207 pTask = pNextTask;
00208 }
00209
00210
00211 if (g_timeSliceTicks)
00212 {
00213 if (--g_timeSliceCounter == 0)
00214 {
00215 g_timeSliceCounter = g_timeSliceTicks;
00216 g_performDispatch = TRUE;
00217 }
00218 }
00219
00220
00221 if (g_performDispatch == TRUE)
00222 otosScheduler(SCHED_NORM);
00223 }
00224