diff --git a/sched/Kconfig b/sched/Kconfig index aa7a41c6676..840871b26ac 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -150,6 +150,16 @@ config USEC_PER_TICK This value should never be less than the underlying resolution of the timer. Error may ensue. +config TIMER_ADJUST_USEC + int "System timer tick adjustment (microseconds)" + default 0 + ---help--- + This value is added to the absolute tick set to the system timer. + This is used to compensate for interrupt latency in real-time + systems where the event required to be triggered on exact time. + The default value of 0 means that no adjustment is made. E.g. + 5 means for each timer being set will be fired 5 microseconds earlier. + if !SCHED_TICKLESS config SYSTEMTICK_EXTCLK diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 1d268877cdb..6fe5ba0b35d 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -407,6 +407,23 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval) } #endif + /* Normally, timer event cannot triggered on exact time + * due to the existence of interrupt latency. + * Assuming that the interrupt latency is distributed within + * [Best-Case Execution Time, Worst-Case Excution Time], + * we can set the timer adjustment value to the BCET to + * reduce the latency. + * After the adjustment, the timer interrupt latency will be + * [0, WCET - BCET]. + * Please use this carefully, if the timer adjustment value is not + * the best-case interrupt latency, it will immediately fired + * another timer interrupt, which may result in a much larger timer + * interrupt latency. + */ + + interval = interval <= (CONFIG_TIMER_ADJUST_USEC / USEC_PER_TICK) ? 0 : + interval - (CONFIG_TIMER_ADJUST_USEC / USEC_PER_TICK); + #ifdef CONFIG_SCHED_TICKLESS_ALARM /* Convert the delay to a time in the future (with respect * to the time when last stopped the timer).