1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17:
18:
19: #include "kernel.h"
20: #include "timer.h"
21: #include "../sysdepend/sys_timer.h"
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
34: Noinit(EXPORT LSYSTIM knl_current_time);
35: Noinit(EXPORT LSYSTIM knl_real_time_ofs);
36:
37: 38: 39:
40: Noinit(EXPORT QUEUE knl_timer_queue);
41:
42: 43: 44:
45: EXPORT ER knl_timer_startup( void )
46: {
47: knl_current_time = knl_real_time_ofs = uitoll(0);
48: QueInit(&knl_timer_queue);
49:
50:
51: knl_start_hw_timer();
52:
53: return E_OK;
54: }
55:
56: #if USE_SHUTDOWN
57: 58: 59:
60: EXPORT void knl_timer_shutdown( void )
61: {
62: knl_terminate_hw_timer();
63: }
64: #endif
65:
66:
67: 68: 69:
70: LOCAL void knl_enqueue_tmeb( TMEB *event )
71: {
72: QUEUE *q;
73: ABSTIM ofs = lltoul(knl_current_time) - ABSTIM_DIFF_MIN;
74:
75: for ( q = knl_timer_queue.next; q != &knl_timer_queue; q = q->next ) {
76: if ( (ABSTIM)(event->time - ofs) < (ABSTIM)((((TMEB*)q)->time) - ofs) ) {
77: break;
78: }
79: }
80: QueInsert(&event->queue, q);
81: }
82:
83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96:
97: EXPORT void knl_timer_insert( TMEB *event, TMO tmout, CBACK callback, void *arg )
98: {
99: event->callback = callback;
100: event->arg = arg;
101:
102: if ( tmout == TMO_FEVR ) {
103: QueInit(&event->queue);
104: } else {
105: 106:
107: event->time = lltoul(knl_current_time) + tmout + TIMER_PERIOD;
108: knl_enqueue_tmeb(event);
109: }
110: }
111:
112: EXPORT void knl_timer_insert_reltim( TMEB *event, RELTIM tmout, CBACK callback, void *arg )
113: {
114: event->callback = callback;
115: event->arg = arg;
116:
117: 118:
119: event->time = lltoul(knl_current_time) + tmout + TIMER_PERIOD;
120: knl_enqueue_tmeb(event);
121: }
122:
123: 124: 125: 126: 127: 128:
129: EXPORT void knl_timer_insert_abs( TMEB *evt, ABSTIM time, CBACK cback, void *arg )
130: {
131: evt->callback = cback;
132: evt->arg = arg;
133: evt->time = time;
134: knl_enqueue_tmeb(evt);
135: }
136:
137:
138:
139: 140: 141: 142: 143: 144:
145:
146: EXPORT void knl_timer_handler( void )
147: {
148: TMEB *event;
149: ABSTIM cur;
150:
151: knl_clear_hw_timer_interrupt();
152:
153: BEGIN_CRITICAL_SECTION;
154: knl_current_time = ll_add(knl_current_time, uitoll(TIMER_PERIOD));
155: cur = lltoul(knl_current_time);
156:
157: #if USE_DBGSPT && defined(USE_FUNC_TD_INF_TSK)
158: if ( knl_ctxtsk != NULL ) {
159:
160: if ( knl_ctxtsk->sysmode > 0 ) {
161: knl_ctxtsk->stime += TIMER_PERIOD;
162: } else {
163: knl_ctxtsk->utime += TIMER_PERIOD;
164: }
165: }
166: #endif
167:
168:
169: while ( !isQueEmpty(&knl_timer_queue) ) {
170: event = (TMEB*)knl_timer_queue.next;
171:
172: if ( !knl_abstim_reached(cur, event->time) ) {
173: break;
174: }
175:
176: QueRemove(&event->queue);
177: if ( event->callback != NULL ) {
178: (*event->callback)(event->arg);
179: }
180: }
181:
182: END_CRITICAL_SECTION;
183:
184: knl_end_of_hw_timer_interrupt();
185: }