kosmos/source/firmware/kernel/sys_tick.c
2016-09-21 10:08:49 +02:00

76 lines
1.5 KiB
C

/*
* sys_tick.c
*
* Created on: Sep 25, 2015
* Author: tkl
*/
#include <stddef.h>
#include <stdbool.h>
#include "timer.h"
#include "sys_tick.h"
#include "irq.h"
#include "stack.h"
#include "queue.h"
#include "thread.h"
#include "schedule.h"
#include "kernel.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);
}
unsigned long sys_tick_get_ms(void)
{
return sys_tick_obj.tick;
}
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();
}