@@ -122,6 +122,52 @@ static inline void sim_timer_current(struct timespec *ts)
122
122
ts -> tv_nsec = nsec ;
123
123
}
124
124
125
+ /****************************************************************************
126
+ * Name: sim_update_hosttimer
127
+ *
128
+ * Description:
129
+ * Ths function is called periodically to deliver the tick events to the
130
+ * NuttX simulation.
131
+ *
132
+ ****************************************************************************/
133
+
134
+ #ifdef CONFIG_SIM_WALLTIME_SIGNAL
135
+ static void sim_update_hosttimer (void )
136
+ {
137
+ struct timespec * next = NULL ;
138
+ struct timespec current ;
139
+ sq_entry_t * entry ;
140
+ uint64_t nsec ;
141
+
142
+ for (entry = sq_peek (& g_oneshot_list ); entry ; entry = sq_next (entry ))
143
+ {
144
+ struct sim_oneshot_lowerhalf_s * priv =
145
+ container_of (entry , struct sim_oneshot_lowerhalf_s , link );
146
+
147
+ if (next == NULL )
148
+ {
149
+ next = & priv -> alarm ;
150
+ continue ;
151
+ }
152
+
153
+ if (clock_timespec_compare (next , & priv -> alarm ) > 0 )
154
+ {
155
+ next = & priv -> alarm ;
156
+ }
157
+ }
158
+
159
+ sim_timer_current (& current );
160
+ clock_timespec_subtract (next , & current , & current );
161
+
162
+ nsec = current .tv_sec * NSEC_PER_SEC ;
163
+ nsec += current .tv_nsec ;
164
+
165
+ host_settimer (nsec );
166
+ }
167
+ #else
168
+ # define sim_update_hosttimer ()
169
+ #endif
170
+
125
171
/****************************************************************************
126
172
* Name: sim_timer_update_internal
127
173
*
@@ -134,11 +180,18 @@ static inline void sim_timer_current(struct timespec *ts)
134
180
static void sim_timer_update_internal (void )
135
181
{
136
182
sq_entry_t * entry ;
183
+ irqstate_t flags ;
184
+
185
+ flags = enter_critical_section ();
137
186
138
187
for (entry = sq_peek (& g_oneshot_list ); entry ; entry = sq_next (entry ))
139
188
{
140
189
sim_process_tick (entry );
141
190
}
191
+
192
+ sim_update_hosttimer ();
193
+
194
+ leave_critical_section (flags );
142
195
}
143
196
144
197
/****************************************************************************
@@ -244,15 +297,22 @@ static int sim_start(struct oneshot_lowerhalf_s *lower,
244
297
struct sim_oneshot_lowerhalf_s * priv =
245
298
(struct sim_oneshot_lowerhalf_s * )lower ;
246
299
struct timespec current ;
300
+ irqstate_t flags ;
247
301
248
302
DEBUGASSERT (priv != NULL && callback != NULL && ts != NULL );
249
303
304
+ flags = enter_critical_section ();
305
+
250
306
sim_timer_current (& current );
251
307
clock_timespec_add (& current , ts , & priv -> alarm );
252
308
253
309
priv -> callback = callback ;
254
310
priv -> arg = arg ;
255
311
312
+ sim_update_hosttimer ();
313
+
314
+ leave_critical_section (flags );
315
+
256
316
return OK ;
257
317
}
258
318
@@ -286,15 +346,25 @@ static int sim_cancel(struct oneshot_lowerhalf_s *lower,
286
346
struct sim_oneshot_lowerhalf_s * priv =
287
347
(struct sim_oneshot_lowerhalf_s * )lower ;
288
348
struct timespec current ;
349
+ irqstate_t flags ;
289
350
290
351
DEBUGASSERT (priv != NULL && ts != NULL );
291
352
353
+ flags = enter_critical_section ();
354
+
292
355
sim_timer_current (& current );
293
356
clock_timespec_subtract (& priv -> alarm , & current , ts );
294
357
358
+ priv -> alarm .tv_sec = UINT_MAX ;
359
+ priv -> alarm .tv_nsec = NSEC_PER_SEC - 1 ;
360
+
361
+ sim_update_hosttimer ();
362
+
295
363
priv -> callback = NULL ;
296
364
priv -> arg = NULL ;
297
365
366
+ leave_critical_section (flags );
367
+
298
368
return OK ;
299
369
}
300
370
@@ -329,7 +399,7 @@ static int sim_current(struct oneshot_lowerhalf_s *lower,
329
399
330
400
#ifdef CONFIG_SIM_WALLTIME_SIGNAL
331
401
/****************************************************************************
332
- * Name: sim_alarm_handler
402
+ * Name: sim_timer_handler
333
403
*
334
404
* Description:
335
405
* The signal handler is called periodically and is used to deliver TICK
@@ -342,7 +412,7 @@ static int sim_current(struct oneshot_lowerhalf_s *lower,
342
412
*
343
413
****************************************************************************/
344
414
345
- static int sim_alarm_handler (int irq , void * context , void * arg )
415
+ static int sim_timer_handler (int irq , void * context , void * arg )
346
416
{
347
417
sim_timer_update_internal ();
348
418
return OK ;
@@ -408,14 +478,12 @@ struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
408
478
void up_timer_initialize (void )
409
479
{
410
480
#ifdef CONFIG_SIM_WALLTIME_SIGNAL
411
- int host_alarm_irq ;
412
-
413
- host_settimer (& host_alarm_irq );
481
+ int timer_irq = host_timerirq ();
414
482
415
483
/* Enable the alarm handler and attach the interrupt to the NuttX logic */
416
484
417
- up_enable_irq (host_alarm_irq );
418
- irq_attach (host_alarm_irq , sim_alarm_handler , NULL );
485
+ up_enable_irq (timer_irq );
486
+ irq_attach (timer_irq , sim_timer_handler , NULL );
419
487
#endif
420
488
421
489
up_alarm_set_lowerhalf (oneshot_initialize (0 , 0 ));
0 commit comments