/** Wait until specified time: @param when time to sleep until @return current time. */ pit_tick_t pit_wait_until (pit_tick_t when) { when <<= 8; while (1) { pit_tick_t diff; pit_tick_t now; now = pit_get () << 8; diff = now - when; if (diff < (PIT_OVERRUN_TICKS_MAX << 8)) return now; } }
/** Wait for specified period: @param period how long to wait @return current time. */ pit_tick_t pit_wait (pit_tick_t period) { return pit_wait_until (pit_get () + period); }
/*! @brief Kernel start. * Start the kernel running within an infinite loop. * @return None. */ void kernel_start (void) { uint32_t i; uint32_t tick = 0; uint32_t now = 0; uint32_t then = 0; uint32_t diff = 0; uint32_t extra = 0; then = pit_get (); while (1) { /* If there has been another tick then decrement * the current block period of each task, unless it's already * blocked for 0 time */ now = pit_get (); if (then > now) diff = (MAX_INT - then) + now; // Deal with wrap-around else diff = now - then; tick = tick + (diff / ACCURACY_DIVIDER); extra = diff % ACCURACY_DIVIDER; then = now - extra; if (tick > 0) { //USB_INFO ("tick = %d", tick); for (i = 0; i < tasks_registered; i++) { if (tasks[i].blocked_for > 0) tasks[i].blocked_for -= tick; } tick = 0; /* Run through the list of tasks round-robin style * If a task is in a blocked state then it is not run */ for (i = 0; i < tasks_registered; i++) { if (tasks[i].state == TASK_READY) { /* If the tasked is blocked for 0 time then it can be run */ if (tasks[i].blocked_for <= 0) { /* Run the task */ tasks[i].func (tasks[i].data); /* Block the task again for the period it specifies */ tasks[i].blocked_for = tasks[i].period; } } } } } }