File tree Expand file tree Collapse file tree 2 files changed +10
-3
lines changed Expand file tree Collapse file tree 2 files changed +10
-3
lines changed Original file line number Diff line number Diff line change @@ -26,7 +26,10 @@ typedef enum {
2626typedef struct {
2727 /* Timing Parameters */
2828 uint32_t deadline_ticks ; /* Expiration time in absolute system ticks */
29- uint32_t period_ms ; /* Reload period in milliseconds */
29+ uint32_t last_expected_fire_tick ; /* Last calculated expected fire time for
30+ * periodic timer
31+ */
32+ uint32_t period_ms ; /* Reload period in milliseconds */
3033
3134 /* Timer Identification and State */
3235 uint16_t id ; /* Unique handle assigned by the kernel */
Original file line number Diff line number Diff line change @@ -251,7 +251,9 @@ void _timer_tick_handler(void)
251251
252252 /* Handle auto-reload timers */
253253 if (t -> mode == TIMER_AUTORELOAD ) {
254- t -> deadline_ticks = now + MS_TO_TICKS (t -> period_ms );
254+ /* Calculate next expected fire tick to prevent cumulative error */
255+ t -> last_expected_fire_tick += MS_TO_TICKS (t -> period_ms );
256+ t -> deadline_ticks = t -> last_expected_fire_tick ;
255257 timer_sorted_insert (t ); /* Re-insert for next expiration */
256258 } else {
257259 t -> mode = TIMER_DISABLED ; /* One-shot timers are done */
@@ -305,6 +307,7 @@ int32_t mo_timer_create(void *(*callback)(void *arg),
305307 t -> arg = arg ;
306308 t -> period_ms = period_ms ;
307309 t -> deadline_ticks = 0 ;
310+ t -> last_expected_fire_tick = 0 ;
308311 t -> mode = TIMER_DISABLED ;
309312 t -> _reserved = 0 ;
310313
@@ -387,7 +390,8 @@ int32_t mo_timer_start(uint16_t id, uint8_t mode)
387390
388391 /* Configure and start timer */
389392 t -> mode = mode ;
390- t -> deadline_ticks = mo_ticks () + MS_TO_TICKS (t -> period_ms );
393+ t -> last_expected_fire_tick = mo_ticks () + MS_TO_TICKS (t -> period_ms );
394+ t -> deadline_ticks = t -> last_expected_fire_tick ;
391395
392396 if (unlikely (timer_sorted_insert (t ) != ERR_OK )) {
393397 t -> mode = TIMER_DISABLED ;
You can’t perform that action at this time.
0 commit comments