/* * sys_tick.c * * Created on: Sep 25, 2015 * Author: tkl */ #include #include #include "irq.h" #include "timer.h" #include "stack.h" #include "queue.h" #include "thread.h" #include "schedule.h" #include "kernel.h" #include "sys_tick.h" struct sys_tick_obj { struct loki_timer *hw_timer; unsigned long tick; unsigned int used; }; extern volatile struct thread_context *current_thread; extern volatile struct thread_list threads; static struct sys_tick_obj sys_tick_obj; void *timer_cb(void *arg) { int i; sys_tick_obj.tick++; for(i = 0; i < threads.count; i++) { if(threads.list[i]->status == THREAD_STATUS_SLEEPING) { if(threads.list[i]->next_executing_time <= sys_tick_obj.tick) { threads.list[i]->status = THREAD_STATUS_EXECUTING; sys_tick_obj.used--; if(sys_tick_obj.used == 0) timer_close(sys_tick_obj.hw_timer); } } } return arg; } void sys_tick_init(const struct loki_timer *hw_timer) { if(NULL == hw_timer) return; sys_tick_obj.tick = 0; sys_tick_obj.used = 0; sys_tick_obj.hw_timer = (struct loki_timer *)hw_timer; timer_set_it_callback(hw_timer, timer_cb, NULL); } void sleep_ms(unsigned int ms) { int irq; irq = disable_irq(); current_thread->next_executing_time = sys_tick_obj.tick + ms; current_thread->status = THREAD_STATUS_SLEEPING; sys_tick_obj.used++; if(sys_tick_obj.used == 1) timer_open(sys_tick_obj.hw_timer); restore_irq(irq); schedule(); }