📄 sch.c
字号:
/*------------------------------------------------------------------*-
版权说明:
1、此程序应称作“时间触发多任务调度器”。
2、程序摘自《时间触发嵌入式系统设计模式
使用8051系统微控制器开发可靠应用》。
在本站好书推荐中有对此书的说明。
3、原作者在书中对版权进行了说明:
只要购买了本书就可以使用书中源程序。
4、在项目中多次用到此程序,感觉很不错。
此处提供的调度器程序是我简化过的。
移植说明:
1、代码全部用标准C语言编写,可以方便的插
入到项目中。
2、内核唯一需要硬件支持的是定时器,需要开
一个定时器,为内核提供调度周期信号。
-*------------------------------------------------------------------*/
#include "AFA.h"
s_task SCH_task_array[SCH_MAX_TASKS]; /*定义任务队列*/
/*------------------------------------------------------------------*-
SCH_Init_Time()
调度器初始化
1、准备调度器数据结构并且设置定时器以所需的
频率中断。
2、必须在使用调度器之前调用这个函数。
-*------------------------------------------------------------------*/
void SCH_Init_Time(void)
{
for (uchar i=0; i< SCH_MAX_TASKS; i++)/*清空任务队列*/ //sch_max_tasks=6;
{
SCH_Delete_Task(i);
}
OCR1A = 1250; /*计数周期为10mS,F=1M*/
TIMSK1 = 0x02; /*比较中断A允许 */
SREG = 0x80;
TCCR1A = 0x00;
TCCR1B = 0x08; /*运行于CTC模式*/
TCCR1B |= 0x02; /*设置8分频*/
}
/*------------------------------------------------------------------*-
SCH_Start()
启动调度器
1、启动调度器,也就允许调度器运行。
2、主要是允许中,因为任务状态是在中断中
刷新的。
-*------------------------------------------------------------------*/
void SCH_Start(void)
{
SEI(); /*开全局中断*/
}
/*------------------------------------------------------------------*-
SCH_Add_Task()
任务添加
1、将任务添加到任务队列中,并设置执行条件。
2、任务添加成功将返回,任务被添加的位置。
3、任务添加失败将返回0。
4、变量说明:
pFunction 函数指针,指向要添加的函数。
delay 任务运行等待时间。
period 任务运行周期时间,此处用于需要
周期性运行的任务。
如只要运行一次,则此值应为0
-*------------------------------------------------------------------*/
uchar SCH_Add_Task(void (* pFunction)(), uint delay, uint period)
{
static uchar k=0;
while((SCH_task_array[k].task != 0) && (k < SCH_MAX_TASKS)) //指针为0就表示没有任务,则加载
{ // 不为0时就已有, 则退出
k++;
}
if (k == SCH_MAX_TASKS)/*检查任务队列溢出*/
return 0; /*溢出处理*/
SCH_task_array[k].task = pFunction; /*加载任务*/
SCH_task_array[k].delay = delay; /*任务运行等待时间*/
SCH_task_array[k].period = period; /*任务运行周期时间,此处用于需要
周期性运行的任务。
如只要运行一次,则此值应为0
*/
SCH_task_array[k].run = 0x00; /*停止执行*/
return k; /*返回任务ID号*/
}
/*------------------------------------------------------------------*-
SCH_Update()
任务刷新
1、定时器T1,A组比较中断。 10ms中断一次
2、对任务定时时间进行刷新。
3、任务定时时间到,设置任务运行标志。
-*------------------------------------------------------------------*/
#pragma vector=TIMER1_OVF_vect
__interrupt void SCH_Update(void)
{
for(static uchar i=0; i<SCH_MAX_TASKS; i++)
{
if (SCH_task_array[i].task) /*检测任务是否存在*/
{
if(SCH_task_array[i].delay == 0) /*任务时间是否到*/
{
SCH_task_array[i].run ++; /*设置运行标志 */
if(SCH_task_array[i].period) /*是否为循环任务*/
{
SCH_task_array[i].delay = SCH_task_array[i].period;/*重载任务定时器*/
}
}
else
{
SCH_task_array[i].delay --;/*刷新任务等待时间*/
}
}
}
}
/*------------------------------------------------------------------*-
SCH_Dispatch_Tasks()
任务调度
1、调度程序,当任务需要运行时,由本程序调用。
2、这个函数必须重复运行。
-*------------------------------------------------------------------*/
void SCH_Dispatch_Tasks(void)
{
for( static uchar j=0; j<SCH_MAX_TASKS; j++) /*查询任务队列*/
{
if (SCH_task_array[j].run > 0) /*运行任务*/
{
(*SCH_task_array[j].task)();
SCH_task_array[j].run --; /*运行标志自减*/
if (SCH_task_array[j].period == 0) /*删除单周期任务*/
{
SCH_Delete_Task(j);
}
}
}
}
/*------------------------------------------------------------------*-
SCH_Delete_Task()
任务删除
1、删除指定任务。
2、要删除任务的ID,此ID在任务添加时给出。
-*------------------------------------------------------------------*/
void SCH_Delete_Task(uchar task_id)/*清除任务*/
{
SCH_task_array[task_id].task = 0x00;
SCH_task_array[task_id].delay = 0x00;
SCH_task_array[task_id].period = 0x00;
SCH_task_array[task_id].run = 0x00;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -