1
+ /*
2
+ * Copyright (c) 2015-2021 University of Antwerp, Aloxy NV.
3
+ *
4
+ * This file is part of Sub-IoT.
5
+ * See https://github.com/Sub-IoT/Sub-IoT-Stack for further info.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ #include "stdio.h"
20
+ #include <stdlib.h>
21
+ #include "timer.c"
22
+
23
+ #define COUNTER_OVERFLOW_MAX 0xFFFF0000
24
+
25
+ static timer_event dummy_tester_event ;
26
+ static timer_event dummy_tester_event2 ;
27
+ static timer_event dummy_tester_event3 ;
28
+ static timer_event dummy_tester_event4 ;
29
+ static timer_event dummy_tester_event5 ;
30
+ static timer_event dummy_tester_event6 ;
31
+
32
+ void dummy_function (){}
33
+ void dummy_function2 (){}
34
+ void dummy_function3 (){}
35
+ void dummy_function4 (){}
36
+ void dummy_function5 (){}
37
+ void dummy_function6 (){}
38
+ void dummy_function7 (){}
39
+ void dummy_function8 (){}
40
+
41
+ void test_timer_events () {
42
+ //can init event
43
+ assert (timer_init_event (& dummy_tester_event , & dummy_function ) == SUCCESS );
44
+ //cannot init same event multiple times
45
+ assert (timer_init_event (& dummy_tester_event , & dummy_function ) == - EALREADY );
46
+ //manually conf next_event
47
+ dummy_tester_event .next_event = TIMER_TICKS_PER_SEC * 1 ;
48
+ // can post a task from an event
49
+ assert (timer_add_event (& dummy_tester_event ) == SUCCESS );
50
+ // after adding event, associated task is scheduled
51
+ assert (timer_is_task_scheduled (dummy_tester_event .f ));
52
+ // cancel event
53
+ timer_cancel_event (& dummy_tester_event );
54
+ // after cancelling event, associated task is no longer scheduled
55
+ assert (timer_is_task_scheduled (dummy_tester_event .f ) == false);
56
+ }
57
+
58
+ void test_timer_post_tasks () {
59
+ // cannot post task with less than min priority
60
+ assert (timer_post_task_prio_delay (& dummy_function2 , TIMER_TICKS_PER_SEC * 5 , MIN_PRIORITY + 1 ) == EINVAL );
61
+ // can post task
62
+ assert (timer_post_task_prio_delay (& dummy_function2 , TIMER_TICKS_PER_SEC * 5 , DEFAULT_PRIORITY ) == SUCCESS );
63
+ // after posting, task is scheduled
64
+ assert (timer_is_task_scheduled (& dummy_function2 ));
65
+ // can modify the fire time by posting the same task again
66
+ assert (timer_post_task_prio_delay (& dummy_function2 , TIMER_TICKS_PER_SEC * 7 , DEFAULT_PRIORITY ) == SUCCESS );
67
+ // cannot modify the priority by posting the same task again
68
+ assert (timer_post_task_prio_delay (& dummy_function2 , TIMER_TICKS_PER_SEC * 7 , DEFAULT_PRIORITY - 1 ) == EALREADY );
69
+ // can cancel the task
70
+ assert (timer_cancel_task (& dummy_function2 ) == SUCCESS );
71
+ // after cancelling, task is no longer scheduled
72
+ assert (timer_is_task_scheduled (& dummy_function2 ) == false);
73
+ // cannot cancel an unscheduled task
74
+ assert (timer_cancel_task (& dummy_function2 ) == EALREADY );
75
+
76
+ // task posted with delay of 0 is scheduled immediately
77
+ sched_register_task (& dummy_function3 );
78
+ assert (timer_post_task_prio_delay (& dummy_function3 , TIMER_TICKS_PER_SEC * 0 , DEFAULT_PRIORITY ) == SUCCESS );
79
+ assert (timer_is_task_scheduled (& dummy_function3 ) == false);
80
+ }
81
+
82
+ void run_overflow_test (timer_tick_t timer_offset , timer_tick_t next_event_time ) {
83
+ NG (timer_offset ) = timer_offset ;
84
+ NG (timers )[NG (next_event )].next_event = next_event_time ;
85
+ NG (hw_event_scheduled ) = false;
86
+ run_overflow_c ();
87
+ }
88
+ void test_timer_overflow () {
89
+ set_hw_timer_value (0 );
90
+ //regular cases:
91
+ //create an event
92
+ assert (timer_init_event (& dummy_tester_event2 , & dummy_function4 ) == SUCCESS );
93
+ dummy_tester_event2 .next_event = TIMER_TICKS_PER_SEC * 1 ;
94
+ assert (timer_add_event (& dummy_tester_event2 ) == SUCCESS );
95
+
96
+ // event is in the next period
97
+ run_overflow_test (COUNTER_OVERFLOW_INCREASE * 10 , COUNTER_OVERFLOW_INCREASE * 11 + 3000 );
98
+ assert (NG (hw_event_scheduled ) == true); //i.e. event gets scheduled for the next period
99
+
100
+ // event is in the far future
101
+ run_overflow_test (COUNTER_OVERFLOW_INCREASE * 10 , COUNTER_OVERFLOW_INCREASE * 12 + 3000 );
102
+ assert ( (NG (hw_event_scheduled ) == false) && NG (timers )[NG (next_event )].f != 0x0 ); //i.e. event should not be scheduled yet
103
+
104
+ // event is in the distant past
105
+ run_overflow_test (COUNTER_OVERFLOW_INCREASE * 10 , 0 );
106
+ assert ( (NG (hw_event_scheduled ) == false) && NG (timers )[NG (next_event )].f != 0x0 ); //i.e. event doesn't get fired
107
+
108
+ // event is in this period but in near past (behind hw_timer time)
109
+ set_hw_timer_value (4000 );
110
+ run_overflow_test (COUNTER_OVERFLOW_INCREASE * 10 , COUNTER_OVERFLOW_INCREASE * 11 + 3000 );
111
+ assert ( (NG (hw_event_scheduled ) == false) && get_next_event () == NO_EVENT ); //i.e. event got fired immediately
112
+ set_hw_timer_value (0 );
113
+
114
+ timer_cancel_event (& dummy_tester_event2 );
115
+
116
+ //overflow cases:
117
+ //create another event
118
+ assert (timer_init_event (& dummy_tester_event3 , & dummy_function5 ) == SUCCESS );
119
+ dummy_tester_event3 .next_event = TIMER_TICKS_PER_SEC * 1 ;
120
+ assert (timer_add_event (& dummy_tester_event3 ) == SUCCESS );
121
+
122
+ // event is in the next period
123
+ run_overflow_test (COUNTER_OVERFLOW_MAX , 3000 );
124
+ assert (NG (hw_event_scheduled ) == true); //i.e. event gets scheduled for the next period
125
+
126
+ // event is in the far future
127
+ run_overflow_test (COUNTER_OVERFLOW_MAX , COUNTER_OVERFLOW_INCREASE + 3000 );
128
+ assert ( (NG (hw_event_scheduled ) == false) && NG (timers )[NG (next_event )].f != 0x0 ); //i.e. event should not be scheduled yet
129
+
130
+ // event is in the distant past
131
+ set_hw_timer_value (0 );
132
+ run_overflow_test (0 , COUNTER_OVERFLOW_MAX );
133
+ assert ( (NG (hw_event_scheduled ) == false) && NG (timers )[NG (next_event )].f != 0x0 ); //i.e. event doesn't get fired
134
+
135
+ // event is in this period but in near past (behind hw_timer time)
136
+ set_hw_timer_value (4000 );
137
+ run_overflow_test (COUNTER_OVERFLOW_MAX , 3000 );
138
+ assert ( (NG (hw_event_scheduled ) == false) && get_next_event () == NO_EVENT ); //i.e. event got fired immediately
139
+
140
+ timer_cancel_event (& dummy_tester_event3 );
141
+ }
142
+
143
+ void setup_counter_test (timer_tick_t timer_offset , uint16_t hw_timer_value , bool is_overflow_pending ) {
144
+ NG (timer_offset ) = timer_offset ;
145
+ set_hw_timer_value (hw_timer_value );
146
+ set_overflow_pending (is_overflow_pending );
147
+ }
148
+
149
+ void test_timer_get_counter_value () {
150
+ //regular cases:
151
+ setup_counter_test (COUNTER_OVERFLOW_INCREASE , 0x00ff , false);
152
+ assert (timer_get_counter_value () == COUNTER_OVERFLOW_INCREASE + 0x00ff );
153
+ setup_counter_test (COUNTER_OVERFLOW_INCREASE , 0x00ff , true);
154
+ assert (timer_get_counter_value () == COUNTER_OVERFLOW_INCREASE + 0x00ff + COUNTER_OVERFLOW_INCREASE );
155
+
156
+ //overflow cases:
157
+ setup_counter_test (COUNTER_OVERFLOW_MAX , 0x00ff , false);
158
+ assert (timer_get_counter_value () == COUNTER_OVERFLOW_MAX + 0x00ff );
159
+ setup_counter_test (COUNTER_OVERFLOW_MAX , 0x00ff , true);
160
+ assert (timer_get_counter_value () == COUNTER_OVERFLOW_MAX + 0x00ff + COUNTER_OVERFLOW_INCREASE );
161
+ }
162
+
163
+ void test_timer_timed_events () {
164
+ //reset time to 0
165
+ NG (timer_offset ) = 0 ;
166
+ set_hw_timer_value (0 );
167
+ set_overflow_pending (false);
168
+
169
+ // - schedule three events of different times
170
+ assert (timer_init_event (& dummy_tester_event4 , & dummy_function6 ) == SUCCESS );
171
+ dummy_tester_event4 .next_event = TIMER_TICKS_PER_SEC * 1 ;
172
+ assert (timer_init_event (& dummy_tester_event5 , & dummy_function7 ) == SUCCESS );
173
+ dummy_tester_event5 .next_event = TIMER_TICKS_PER_SEC * 3 ;
174
+ assert (timer_init_event (& dummy_tester_event6 , & dummy_function8 ) == SUCCESS );
175
+ dummy_tester_event6 .next_event = TIMER_TICKS_PER_SEC * 5 ;
176
+
177
+ // post tasks from the events
178
+ assert (timer_add_event (& dummy_tester_event4 ) == SUCCESS );
179
+ assert (timer_add_event (& dummy_tester_event5 ) == SUCCESS );
180
+ assert (timer_add_event (& dummy_tester_event6 ) == SUCCESS );
181
+
182
+ assert (timer_is_task_scheduled (dummy_tester_event4 .f ));
183
+ // check event returned is as expected
184
+ uint32_t next_event = get_next_event ();
185
+ assert (NG (timers )[next_event ].f == dummy_tester_event4 .f );
186
+ // move time forward till after that event
187
+ NG (timer_offset ) = TIMER_TICKS_PER_SEC * 2 ;
188
+ // events from the past should still get returned if they haven't fired yet
189
+ next_event = get_next_event ();
190
+ assert (NG (timers )[next_event ].f == dummy_tester_event4 .f );
191
+ timer_cancel_event (& dummy_tester_event4 );
192
+ next_event = get_next_event ();
193
+ assert (NG (timers )[next_event ].f == dummy_tester_event5 .f );
194
+ timer_cancel_event (& dummy_tester_event5 );
195
+ next_event = get_next_event ();
196
+ assert (NG (timers )[next_event ].f == dummy_tester_event6 .f );
197
+ timer_cancel_event (& dummy_tester_event6 );
198
+ //when no events listed, should return NO_EVENT
199
+ next_event = get_next_event ();
200
+ assert (next_event == NO_EVENT );
201
+ }
202
+
203
+ int main (int argc , char * argv []){
204
+ timer_init ();
205
+ scheduler_init ();
206
+
207
+ test_timer_events ();
208
+
209
+ test_timer_post_tasks ();
210
+
211
+ test_timer_overflow ();
212
+
213
+ test_timer_get_counter_value ();
214
+
215
+ test_timer_timed_events ();
216
+
217
+ printf ("All timer tests passed!\n" );
218
+
219
+ exit (0 );
220
+ }
0 commit comments