Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/sys/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ typedef enum {
typedef struct {
/* Timing Parameters */
uint32_t deadline_ticks; /* Expiration time in absolute system ticks */
uint32_t period_ms; /* Reload period in milliseconds */
uint32_t last_expected_fire_tick; /* Last calculated expected fire time for
* periodic timer
*/
uint32_t period_ms; /* Reload period in milliseconds */

/* Timer Identification and State */
uint16_t id; /* Unique handle assigned by the kernel */
Expand Down
8 changes: 6 additions & 2 deletions kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,9 @@ void _timer_tick_handler(void)

/* Handle auto-reload timers */
if (t->mode == TIMER_AUTORELOAD) {
t->deadline_ticks = now + MS_TO_TICKS(t->period_ms);
/* Calculate next expected fire tick to prevent cumulative error */
t->last_expected_fire_tick += MS_TO_TICKS(t->period_ms);
t->deadline_ticks = t->last_expected_fire_tick;
timer_sorted_insert(t); /* Re-insert for next expiration */
} else {
t->mode = TIMER_DISABLED; /* One-shot timers are done */
Expand Down Expand Up @@ -305,6 +307,7 @@ int32_t mo_timer_create(void *(*callback)(void *arg),
t->arg = arg;
t->period_ms = period_ms;
t->deadline_ticks = 0;
t->last_expected_fire_tick = 0;
t->mode = TIMER_DISABLED;
t->_reserved = 0;

Expand Down Expand Up @@ -387,7 +390,8 @@ int32_t mo_timer_start(uint16_t id, uint8_t mode)

/* Configure and start timer */
t->mode = mode;
t->deadline_ticks = mo_ticks() + MS_TO_TICKS(t->period_ms);
t->last_expected_fire_tick = mo_ticks() + MS_TO_TICKS(t->period_ms);
t->deadline_ticks = t->last_expected_fire_tick;

if (unlikely(timer_sorted_insert(t) != ERR_OK)) {
t->mode = TIMER_DISABLED;
Expand Down
Loading