You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.8 KiB
77 lines
1.8 KiB
/** @file task.c
|
|
@author M. P. Hayes, UCECE
|
|
@date 17 August 2011
|
|
@brief Simple task scheduler.
|
|
*/
|
|
#include "system.h"
|
|
#include "task.h"
|
|
#include "timer.h"
|
|
|
|
|
|
/** With 16-bit times the maximum value is 32768. */
|
|
#define TASK_OVERRUN_MAX 32767
|
|
|
|
|
|
/** Schedule tasks
|
|
@param tasks pointer to array of tasks (the highest priority
|
|
task comes first)
|
|
@param num_tasks number of tasks to schedule
|
|
@return this never returns.
|
|
*/
|
|
void task_schedule (task_t *tasks, uint8_t num_tasks)
|
|
{
|
|
uint8_t i;
|
|
timer_tick_t now;
|
|
task_t *next_task;
|
|
|
|
timer_init ();
|
|
now = timer_get ();
|
|
|
|
/* Start by scheduling the first task. */
|
|
next_task = tasks;
|
|
|
|
while (1)
|
|
{
|
|
timer_tick_t sleep_min;
|
|
|
|
/* Wait until the next task is ready to run. */
|
|
timer_wait_until (next_task->reschedule);
|
|
|
|
/* Schedule the task. */
|
|
next_task->func (next_task->data);
|
|
|
|
/* Update the reschedule time. */
|
|
next_task->reschedule += next_task->period;
|
|
|
|
sleep_min = ~0;
|
|
now = timer_get ();
|
|
|
|
/* Search array of tasks. Schedule the first task (highest priority)
|
|
that needs to run otherwise wait until first task ready. */
|
|
for (i = 0; i < num_tasks; i++)
|
|
{
|
|
task_t * task = tasks + i;
|
|
timer_tick_t overrun;
|
|
|
|
overrun = now - task->reschedule;
|
|
if (overrun < TASK_OVERRUN_MAX)
|
|
{
|
|
/* Have found a task that can run immediately. */
|
|
next_task = task;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
timer_tick_t sleep;
|
|
|
|
sleep = -overrun;
|
|
if (sleep < sleep_min)
|
|
{
|
|
sleep_min = sleep;
|
|
next_task = task;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|