/** * Interrupt handler for the timer interrupt * Announce to the kernel that a tick has passed */ static void sp_timer_isr(void *arg) { ARG_UNUSED(arg); _sys_idle_elapsed_ticks = silent_ticks + 1; silent_ticks = 0; z_clock_announce(_sys_idle_elapsed_ticks); }
static void lptmr_irq_handler(struct device *unused) { ARG_UNUSED(unused); SYSTEM_TIMER_INSTANCE->CSR |= LPTMR_CSR_TCF(1); /* Rearm timer. */ cycle_count += CYCLES_PER_TICK; /* Track cycles. */ z_clock_announce(1); /* Poke the scheduler. */ }
/* * Exit from idle mode * * If we have been silent for a number of ticks, announce immediately to the * kernel how many silent ticks have passed. * If this is called due to the 1st non silent timer interrupt, sp_timer_isr() * will be called right away, which will announce that last (non silent) one. * * Note that we do not assume this function is called before the interrupt is * raised (the interrupt can handle it announcing all ticks) */ void z_clock_idle_exit(void) { silent_ticks -= hwtimer_get_pending_silent_ticks(); if (silent_ticks > 0) { _sys_idle_elapsed_ticks = silent_ticks; z_clock_announce(_sys_idle_elapsed_ticks); } silent_ticks = 0; hwtimer_set_silent_ticks(0); }
static void litex_timer_irq_handler(void *device) { ARG_UNUSED(device); int key = irq_lock(); sys_write8(TIMER_EV, TIMER_EV_PENDING_ADDR); accumulated_cycle_count += sys_clock_hw_cycles_per_tick(); z_clock_announce(1); irq_unlock(key); }
static void hpet_isr(void *arg) { ARG_UNUSED(arg); k_spinlock_key_t key = k_spin_lock(&lock); u32_t now = MAIN_COUNTER_REG; u32_t dticks = (now - last_count) / cyc_per_tick; last_count += dticks * cyc_per_tick; if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL) || IS_ENABLED(CONFIG_QEMU_TICKLESS_WORKAROUND)) { u32_t next = last_count + cyc_per_tick; if ((s32_t)(next - now) < MIN_DELAY) { next += cyc_per_tick; } TIMER0_COMPARATOR_REG = next; } k_spin_unlock(&lock, key); z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1); }
/* Note: this function has public linkage, and MUST have this * particular name. The platform architecture itself doesn't care, * but there is a test (tests/kernel/arm_irq_vector_table) that needs * to find it to it can set it in a custom vector table. Should * probably better abstract that at some point (e.g. query and reset * it by pointer at runtime, maybe?) so we don't have this leaky * symbol. */ void rtc1_nrf_isr(void *arg) { ARG_UNUSED(arg); RTC->EVENTS_COMPARE[0] = 0; u32_t key = irq_lock(); u32_t t = counter(); u32_t dticks = counter_sub(t, last_count) / CYC_PER_TICK; last_count += dticks * CYC_PER_TICK; if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { u32_t next = last_count + CYC_PER_TICK; if (counter_sub(next, t) < MIN_DELAY) { next += CYC_PER_TICK; } set_comparator(next); } irq_unlock(key); z_clock_announce(dticks); }