17 |
17 |
18 You should have received a copy of the GNU Lesser General Public |
18 You should have received a copy of the GNU Lesser General Public |
19 License along with this library; if not, write to the Free Software |
19 License along with this library; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 */ |
21 */ |
|
22 /*! |
|
23 ** @file timer.c |
|
24 ** @author Edouard TISSERANT and Francis DUPIN |
|
25 ** @date Tue Jun 5 09:32:32 2007 |
|
26 ** |
|
27 ** @brief |
|
28 ** |
|
29 ** |
|
30 */ |
22 |
31 |
23 /* #define DEBUG_WAR_CONSOLE_ON */ |
32 /* #define DEBUG_WAR_CONSOLE_ON */ |
24 /* #define DEBUG_ERR_CONSOLE_ON */ |
33 /* #define DEBUG_ERR_CONSOLE_ON */ |
25 |
34 |
26 #include <applicfg.h> |
35 #include <applicfg.h> |
32 TIMEVAL total_sleep_time = TIMEVAL_MAX; |
41 TIMEVAL total_sleep_time = TIMEVAL_MAX; |
33 TIMER_HANDLE last_timer_raw = -1; |
42 TIMER_HANDLE last_timer_raw = -1; |
34 |
43 |
35 #define min_val(a,b) ((a<b)?a:b) |
44 #define min_val(a,b) ((a<b)?a:b) |
36 |
45 |
37 /* --------- Use this to declare a new alarm --------- */ |
46 /*! |
|
47 ** ------- Use this to declare a new alarm ------ |
|
48 ** |
|
49 ** @param d |
|
50 ** @param id |
|
51 ** @param callback |
|
52 ** @param value |
|
53 ** @param period |
|
54 ** |
|
55 ** @return |
|
56 **/ |
38 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) |
57 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) |
39 { |
58 { |
40 /*printf("SetAlarm(UNS32 id=%d, TimerCallback_t callback=%x, TIMEVAL value=%d, TIMEVAL period=%d)\n", id, callback, value, period); */ |
59 /*printf("SetAlarm(UNS32 id=%d, TimerCallback_t callback=%x, TIMEVAL value=%d, TIMEVAL period=%d)\n", id, callback, value, period); */ |
41 TIMER_HANDLE i; |
60 TIMER_HANDLE i; |
42 TIMER_HANDLE row_number = TIMER_NONE; |
61 TIMER_HANDLE row_number = TIMER_NONE; |
43 |
62 |
44 /* in order to decide new timer setting we have to run over all timer rows */ |
63 /** in order to decide new timer setting we have to run over all timer rows */ |
45 for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) |
64 for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) |
46 { |
65 { |
47 s_timer_entry *row = (timers+i); |
66 s_timer_entry *row = (timers+i); |
48 |
67 |
49 if (callback && /* if something to store */ |
68 if (callback && /** if something to store */ |
50 row->state == TIMER_FREE) /* and empty row */ |
69 row->state == TIMER_FREE) /** and empty row */ |
51 { /* just store */ |
70 { /** just store */ |
52 row->callback = callback; |
71 row->callback = callback; |
53 row->d = d; |
72 row->d = d; |
54 row->id = id; |
73 row->id = id; |
55 row->val = value; |
74 row->val = value; |
56 row->interval = period; |
75 row->interval = period; |
58 row_number = i; |
77 row_number = i; |
59 break; |
78 break; |
60 } |
79 } |
61 } |
80 } |
62 |
81 |
63 if (row_number != TIMER_NONE) /* if successfull **/ |
82 if (row_number != TIMER_NONE) /** if successfull **/ |
64 { |
83 { |
65 TIMEVAL real_timer_value; |
84 TIMEVAL real_timer_value; |
66 TIMEVAL elapsed_time; |
85 TIMEVAL elapsed_time; |
67 |
86 |
68 if (row_number == last_timer_raw + 1) last_timer_raw++; |
87 if (row_number == last_timer_raw + 1) last_timer_raw++; |
69 |
88 |
70 /* set next wakeup alarm if new entry is sooner than others, or if it is alone */ |
89 /** set next wakeup alarm if new entry is sooner than others, or if it is alone */ |
71 real_timer_value = min_val(value, TIMEVAL_MAX); |
90 real_timer_value = min_val(value, TIMEVAL_MAX); |
72 elapsed_time = getElapsedTime(); |
91 elapsed_time = getElapsedTime(); |
73 |
92 |
74 /*printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); */ |
93 /**printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); */ |
75 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) |
94 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) |
76 { |
95 { |
77 total_sleep_time = elapsed_time + real_timer_value; |
96 total_sleep_time = elapsed_time + real_timer_value; |
78 setTimer(real_timer_value); |
97 setTimer(real_timer_value); |
79 } |
98 } |
80 /*printf("SetAlarm() return %d\n", row_number); */ |
99 /**printf("SetAlarm() return %d\n", row_number); */ |
81 return row_number; |
100 return row_number; |
82 } |
101 } |
83 return TIMER_NONE; |
102 return TIMER_NONE; |
84 } |
103 } |
85 |
104 |
86 /* --------- Use this to remove an alarm --------- */ |
105 /*! |
|
106 ** ----- Use this to remove an alarm ---- |
|
107 ** |
|
108 ** @param handle |
|
109 ** |
|
110 ** @return |
|
111 **/ |
87 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) |
112 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) |
88 { |
113 { |
89 /* Quick and dirty. system timer will continue to be trigged, but no action will be preformed. */ |
114 /** Quick and dirty. system timer will continue to be trigged, but no action will be preformed. */ |
90 MSG_WAR(0x3320, "DelAlarm. handle = ", handle); |
115 MSG_WAR(0x3320, "DelAlarm. handle = ", handle); |
91 if(handle != TIMER_NONE) |
116 if(handle != TIMER_NONE) |
92 { |
117 { |
93 if(handle == last_timer_raw) |
118 if(handle == last_timer_raw) |
94 last_timer_raw--; |
119 last_timer_raw--; |
97 else { |
122 else { |
98 } |
123 } |
99 return TIMER_NONE; |
124 return TIMER_NONE; |
100 } |
125 } |
101 |
126 |
102 |
127 /*! |
103 /* --------- TimeDispatch is called on each timer expiration --------- */ |
128 ** ------ TimeDispatch is called on each timer expiration ---- |
|
129 ** |
|
130 **/ |
104 void TimeDispatch() |
131 void TimeDispatch() |
105 { |
132 { |
106 TIMER_HANDLE i; |
133 TIMER_HANDLE i; |
107 TIMEVAL next_wakeup = TIMEVAL_MAX; /* used to compute when should normaly occur next wakeup */ |
134 TIMEVAL next_wakeup = TIMEVAL_MAX; /** used to compute when should normaly occur next wakeup */ |
108 /* First run : change timer state depending on time */ |
135 /** First run : change timer state depending on time */ |
109 /* Get time since timer signal */ |
136 /** Get time since timer signal */ |
110 TIMEVAL overrun = getElapsedTime(); |
137 TIMEVAL overrun = getElapsedTime(); |
111 |
138 |
112 TIMEVAL real_total_sleep_time = total_sleep_time + overrun; |
139 TIMEVAL real_total_sleep_time = total_sleep_time + overrun; |
113 /*printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); */ |
140 /*printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); */ |
114 |
141 |
115 for(i=0; i <= last_timer_raw; i++) |
142 for(i=0; i <= last_timer_raw; i++) |
116 { |
143 { |
117 s_timer_entry *row = (timers+i); |
144 s_timer_entry *row = (timers+i); |
118 |
145 |
119 if (row->state & TIMER_ARMED) /* if row is active */ |
146 if (row->state & TIMER_ARMED) /** if row is active */ |
120 { |
147 { |
121 if (row->val <= real_total_sleep_time) /* to be trigged */ |
148 if (row->val <= real_total_sleep_time) /** to be trigged */ |
122 { |
149 { |
123 /*printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); */ |
150 /*printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); */ |
124 if (!row->interval) /* if simply outdated */ |
151 if (!row->interval) /** if simply outdated */ |
125 { |
152 { |
126 row->state = TIMER_TRIG; /* ask for trig */ |
153 row->state = TIMER_TRIG; /** ask for trig */ |
127 } |
154 } |
128 else /* or period have expired */ |
155 else /** or period have expired */ |
129 { |
156 { |
130 /* set val as interval, with overrun correction */ |
157 /** set val as interval, with overrun correction */ |
131 row->val = row->interval - (overrun % row->interval); |
158 row->val = row->interval - (overrun % row->interval); |
132 row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */ |
159 row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */ |
133 /* Check if this new timer value is the soonest */ |
160 /** Check if this new timer value is the soonest */ |
134 next_wakeup = min_val(row->val,next_wakeup); |
161 next_wakeup = min_val(row->val,next_wakeup); |
135 } |
162 } |
136 } |
163 } |
137 else |
164 else |
138 { |
165 { |
139 /* Each armed timer value in decremented. */ |
166 /** Each armed timer value in decremented. */ |
140 row->val -= real_total_sleep_time; |
167 row->val -= real_total_sleep_time; |
141 |
168 |
142 /* Check if this new timer value is the soonest */ |
169 /** Check if this new timer value is the soonest */ |
143 next_wakeup = min_val(row->val,next_wakeup); |
170 next_wakeup = min_val(row->val,next_wakeup); |
144 } |
171 } |
145 } |
172 } |
146 } |
173 } |
147 |
174 |
148 /* Remember how much time we should sleep. */ |
175 /** Remember how much time we should sleep. */ |
149 total_sleep_time = next_wakeup; |
176 total_sleep_time = next_wakeup; |
150 |
177 |
151 /* Set timer to soonest occurence */ |
178 /** Set timer to soonest occurence */ |
152 setTimer(next_wakeup); |
179 setTimer(next_wakeup); |
153 |
180 |
154 /* Then trig them or not. */ |
181 /** Then trig them or not. */ |
155 for(i=0; i<=last_timer_raw; i++) |
182 for(i=0; i<=last_timer_raw; i++) |
156 { |
183 { |
157 s_timer_entry *row = (timers+i); |
184 s_timer_entry *row = (timers+i); |
158 |
185 |
159 if (row->state & TIMER_TRIG) |
186 if (row->state & TIMER_TRIG) |
160 { |
187 { |
161 row->state &= ~TIMER_TRIG; /* reset trig state (will be free if not periodic) */ |
188 row->state &= ~TIMER_TRIG; /** reset trig state (will be free if not periodic) */ |
162 if(row->callback) |
189 if(row->callback) |
163 (*row->callback)(row->d, row->id); /* trig ! */ |
190 (*row->callback)(row->d, row->id); /** trig ! */ |
164 } |
191 } |
165 } |
192 } |
166 } |
193 } |
167 |
194 |