调度器的核心是调度器数据结构。这是一种用户自定义的数据类型,集中了每个任务所需的信息。
typedef data struct //可能的话,存储在DATA区,速度快,每个任务7个字节。
{
void (code *pTask)(void); //指向任务的指针(必须是一个" void(void)"函数)
ushort Delay; //延迟直到下一次执行
ushort Period; //连续运行时间间隔
ushort RunMe; //当任务需要运行时,由调度器加1
uchar Co_op;//如果任务是合作式的,设置为1,如果任务是抢占式的,设置为0
}sTask;
sTask SCH_tasks_G[SCH_MAX_TASKS];
tByte SCH_Add_Task(void (code * pFunction)(),
const tWord DELAY,
const tWord PERIOD)
{
tByte Index = 0;
//首先在队列中找一个空隙,如果有的话
while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
{
Index++;
}
// 是否到达结尾
if (Index == SCH_MAX_TASKS)
{
// 队列已满
//设置全局错误变量
Error_code_G = ERROR_SCH_TOO_MANY_TASKS;
// Also return an error code
return SCH_MAX_TASKS;
}
//如果能运行到这里,则说明任务队列中有空位
SCH_tasks_G[Index].pTask = pFunction;
SCH_tasks_G[Index].Delay = DELAY;
SCH_tasks_G[Index].Period = PERIOD;
SCH_tasks_G[Index].RunMe = 0;
return Index; // return position of task (to allow later deletion)
}
当任务被添加到任务队列时,SCH_Add_Task()返回该任务在任务队列中的位置:
Task_ID=SCH_Add_Task();
有时需要从队列中删除任务,可以如下使用SCH_Delet_Task();来实现
SCH_Delete_Task( TASK_ID) ;
bit SCH_Delete_Task(const tByte TASK_INDEX)
{
bit Return_code;
if (SCH_tasks_G[TASK_INDEX].pTask == 0)
{
// No task at this location...
//
// Set the global error variable
Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK;
// ...also return an error code
Return_code = RETURN_ERROR;
}
else
{
Return_code = RETURN_NORMAL;
}
SCH_tasks_G[TASK_INDEX].pTask = 0x0000;
SCH_tasks_G[TASK_INDEX].Delay = 0;
SCH_tasks_G[TASK_INDEX].Period = 0;
SCH_tasks_G[TASK_INDEX].RunMe = 0;
return Return_code; // return status
}
void SCH_Go_To_Sleep()
{
PCON |= 0x01; // Enter idle mode (generic 8051 version)
// Entering idle mode requires TWO consecutive instructions
// on 80c515 / 80c505 - to avoid accidental triggering
//PCON |= 0x01; // Enter idle mode (#1)
//PCON |= 0x20; // Enter idle mode (#2)
}每次调用调度程序的结尾将系统置为“睡眠”,并在下一个定时器时标产生时醒来
文章评论(0条评论)
登录后参与讨论