71 lines
1.4 KiB
C
71 lines
1.4 KiB
C
/*
|
|
* sys_tick.c
|
|
*
|
|
* Created on: Sep 25, 2015
|
|
* Author: tkl
|
|
*/
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "irq.h"
|
|
#include "timer.h"
|
|
#include "stack.h"
|
|
#include "queue.h"
|
|
#include "thread.h"
|
|
#include "schedule.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();
|
|
}
|
|
|