⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sch.c

📁 一个多任务调度器
💻 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 + -